diff options
author | Paul Mackerras <paulus@samba.org> | 2005-09-28 23:13:36 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-09-28 23:13:36 -0400 |
commit | ab11d1ea281e85895369ef57c5259ad8a432fabb (patch) | |
tree | 684147479c6a8bb2fbed21bdcf12de1dd519c730 | |
parent | 952ecef7a0479049c8abb7c34a688ec2981ceadd (diff) | |
parent | 664cceb0093b755739e56572b836a99104ee8a75 (diff) |
Merge by hand from Linus' tree.
Signed-off-by: Paul Mackerras <paulus@samba.org>
180 files changed, 3605 insertions, 3065 deletions
diff --git a/Documentation/Changes b/Documentation/Changes index 5eaab0441d76..27232be26e1a 100644 --- a/Documentation/Changes +++ b/Documentation/Changes | |||
@@ -237,6 +237,12 @@ udev | |||
237 | udev is a userspace application for populating /dev dynamically with | 237 | udev is a userspace application for populating /dev dynamically with |
238 | only entries for devices actually present. udev replaces devfs. | 238 | only entries for devices actually present. udev replaces devfs. |
239 | 239 | ||
240 | FUSE | ||
241 | ---- | ||
242 | |||
243 | Needs libfuse 2.4.0 or later. Absolute minimum is 2.3.0 but mount | ||
244 | options 'direct_io' and 'kernel_cache' won't work. | ||
245 | |||
240 | Networking | 246 | Networking |
241 | ========== | 247 | ========== |
242 | 248 | ||
@@ -390,6 +396,10 @@ udev | |||
390 | ---- | 396 | ---- |
391 | o <http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html> | 397 | o <http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html> |
392 | 398 | ||
399 | FUSE | ||
400 | ---- | ||
401 | o <http://sourceforge.net/projects/fuse> | ||
402 | |||
393 | Networking | 403 | Networking |
394 | ********** | 404 | ********** |
395 | 405 | ||
diff --git a/Documentation/keys.txt b/Documentation/keys.txt index 0321ded4b9ae..b22e7c8d059a 100644 --- a/Documentation/keys.txt +++ b/Documentation/keys.txt | |||
@@ -195,8 +195,8 @@ KEY ACCESS PERMISSIONS | |||
195 | ====================== | 195 | ====================== |
196 | 196 | ||
197 | Keys have an owner user ID, a group access ID, and a permissions mask. The mask | 197 | Keys have an owner user ID, a group access ID, and a permissions mask. The mask |
198 | has up to eight bits each for user, group and other access. Only five of each | 198 | has up to eight bits each for possessor, user, group and other access. Only |
199 | set of eight bits are defined. These permissions granted are: | 199 | five of each set of eight bits are defined. These permissions granted are: |
200 | 200 | ||
201 | (*) View | 201 | (*) View |
202 | 202 | ||
@@ -241,16 +241,16 @@ about the status of the key service: | |||
241 | type, description and permissions. The payload of the key is not available | 241 | type, description and permissions. The payload of the key is not available |
242 | this way: | 242 | this way: |
243 | 243 | ||
244 | SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY | 244 | SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY |
245 | 00000001 I----- 39 perm 1f0000 0 0 keyring _uid_ses.0: 1/4 | 245 | 00000001 I----- 39 perm 1f1f0000 0 0 keyring _uid_ses.0: 1/4 |
246 | 00000002 I----- 2 perm 1f0000 0 0 keyring _uid.0: empty | 246 | 00000002 I----- 2 perm 1f1f0000 0 0 keyring _uid.0: empty |
247 | 00000007 I----- 1 perm 1f0000 0 0 keyring _pid.1: empty | 247 | 00000007 I----- 1 perm 1f1f0000 0 0 keyring _pid.1: empty |
248 | 0000018d I----- 1 perm 1f0000 0 0 keyring _pid.412: empty | 248 | 0000018d I----- 1 perm 1f1f0000 0 0 keyring _pid.412: empty |
249 | 000004d2 I--Q-- 1 perm 1f0000 32 -1 keyring _uid.32: 1/4 | 249 | 000004d2 I--Q-- 1 perm 1f1f0000 32 -1 keyring _uid.32: 1/4 |
250 | 000004d3 I--Q-- 3 perm 1f0000 32 -1 keyring _uid_ses.32: empty | 250 | 000004d3 I--Q-- 3 perm 1f1f0000 32 -1 keyring _uid_ses.32: empty |
251 | 00000892 I--QU- 1 perm 1f0000 0 0 user metal:copper: 0 | 251 | 00000892 I--QU- 1 perm 1f000000 0 0 user metal:copper: 0 |
252 | 00000893 I--Q-N 1 35s 1f0000 0 0 user metal:silver: 0 | 252 | 00000893 I--Q-N 1 35s 1f1f0000 0 0 user metal:silver: 0 |
253 | 00000894 I--Q-- 1 10h 1f0000 0 0 user metal:gold: 0 | 253 | 00000894 I--Q-- 1 10h 001f0000 0 0 user metal:gold: 0 |
254 | 254 | ||
255 | The flags are: | 255 | The flags are: |
256 | 256 | ||
@@ -637,6 +637,34 @@ call, and the key released upon close. How to deal with conflicting keys due to | |||
637 | two different users opening the same file is left to the filesystem author to | 637 | two different users opening the same file is left to the filesystem author to |
638 | solve. | 638 | solve. |
639 | 639 | ||
640 | Note that there are two different types of pointers to keys that may be | ||
641 | encountered: | ||
642 | |||
643 | (*) struct key * | ||
644 | |||
645 | This simply points to the key structure itself. Key structures will be at | ||
646 | least four-byte aligned. | ||
647 | |||
648 | (*) key_ref_t | ||
649 | |||
650 | This is equivalent to a struct key *, but the least significant bit is set | ||
651 | if the caller "possesses" the key. By "possession" it is meant that the | ||
652 | calling processes has a searchable link to the key from one of its | ||
653 | keyrings. There are three functions for dealing with these: | ||
654 | |||
655 | key_ref_t make_key_ref(const struct key *key, | ||
656 | unsigned long possession); | ||
657 | |||
658 | struct key *key_ref_to_ptr(const key_ref_t key_ref); | ||
659 | |||
660 | unsigned long is_key_possessed(const key_ref_t key_ref); | ||
661 | |||
662 | The first function constructs a key reference from a key pointer and | ||
663 | possession information (which must be 0 or 1 and not any other value). | ||
664 | |||
665 | The second function retrieves the key pointer from a reference and the | ||
666 | third retrieves the possession flag. | ||
667 | |||
640 | When accessing a key's payload contents, certain precautions must be taken to | 668 | When accessing a key's payload contents, certain precautions must be taken to |
641 | prevent access vs modification races. See the section "Notes on accessing | 669 | prevent access vs modification races. See the section "Notes on accessing |
642 | payload contents" for more information. | 670 | payload contents" for more information. |
@@ -665,7 +693,11 @@ payload contents" for more information. | |||
665 | 693 | ||
666 | void key_put(struct key *key); | 694 | void key_put(struct key *key); |
667 | 695 | ||
668 | This can be called from interrupt context. If CONFIG_KEYS is not set then | 696 | Or: |
697 | |||
698 | void key_ref_put(key_ref_t key_ref); | ||
699 | |||
700 | These can be called from interrupt context. If CONFIG_KEYS is not set then | ||
669 | the argument will not be parsed. | 701 | the argument will not be parsed. |
670 | 702 | ||
671 | 703 | ||
@@ -689,13 +721,17 @@ payload contents" for more information. | |||
689 | 721 | ||
690 | (*) If a keyring was found in the search, this can be further searched by: | 722 | (*) If a keyring was found in the search, this can be further searched by: |
691 | 723 | ||
692 | struct key *keyring_search(struct key *keyring, | 724 | key_ref_t keyring_search(key_ref_t keyring_ref, |
693 | const struct key_type *type, | 725 | const struct key_type *type, |
694 | const char *description) | 726 | const char *description) |
695 | 727 | ||
696 | This searches the keyring tree specified for a matching key. Error ENOKEY | 728 | This searches the keyring tree specified for a matching key. Error ENOKEY |
697 | is returned upon failure. If successful, the returned key will need to be | 729 | is returned upon failure (use IS_ERR/PTR_ERR to determine). If successful, |
698 | released. | 730 | the returned key will need to be released. |
731 | |||
732 | The possession attribute from the keyring reference is used to control | ||
733 | access through the permissions mask and is propagated to the returned key | ||
734 | reference pointer if successful. | ||
699 | 735 | ||
700 | 736 | ||
701 | (*) To check the validity of a key, this function can be called: | 737 | (*) To check the validity of a key, this function can be called: |
@@ -732,7 +768,7 @@ More complex payload contents must be allocated and a pointer to them set in | |||
732 | key->payload.data. One of the following ways must be selected to access the | 768 | key->payload.data. One of the following ways must be selected to access the |
733 | data: | 769 | data: |
734 | 770 | ||
735 | (1) Unmodifyable key type. | 771 | (1) Unmodifiable key type. |
736 | 772 | ||
737 | If the key type does not have a modify method, then the key's payload can | 773 | If the key type does not have a modify method, then the key's payload can |
738 | be accessed without any form of locking, provided that it's known to be | 774 | be accessed without any form of locking, provided that it's known to be |
diff --git a/MAINTAINERS b/MAINTAINERS index 7d1dd5bad39a..c1bc9a86a99d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -604,6 +604,15 @@ P: H. Peter Anvin | |||
604 | M: hpa@zytor.com | 604 | M: hpa@zytor.com |
605 | S: Maintained | 605 | S: Maintained |
606 | 606 | ||
607 | CPUSETS | ||
608 | P: Paul Jackson | ||
609 | P: Simon Derr | ||
610 | M: pj@sgi.com | ||
611 | M: simon.derr@bull.net | ||
612 | L: linux-kernel@vger.kernel.org | ||
613 | W: http://www.bullopensource.org/cpuset/ | ||
614 | S: Supported | ||
615 | |||
607 | CRAMFS FILESYSTEM | 616 | CRAMFS FILESYSTEM |
608 | W: http://sourceforge.net/projects/cramfs/ | 617 | W: http://sourceforge.net/projects/cramfs/ |
609 | S: Orphan | 618 | S: Orphan |
@@ -1906,6 +1915,13 @@ M: joern@wh.fh-wedel.de | |||
1906 | L: linux-mtd@lists.infradead.org | 1915 | L: linux-mtd@lists.infradead.org |
1907 | S: Maintained | 1916 | S: Maintained |
1908 | 1917 | ||
1918 | PKTCDVD DRIVER | ||
1919 | P: Peter Osterlund | ||
1920 | M: petero2@telia.com | ||
1921 | L: linux-kernel@vger.kernel.org | ||
1922 | L: packet-writing@suse.com | ||
1923 | S: Maintained | ||
1924 | |||
1909 | POSIX CLOCKS and TIMERS | 1925 | POSIX CLOCKS and TIMERS |
1910 | P: George Anzinger | 1926 | P: George Anzinger |
1911 | M: george@mvista.com | 1927 | M: george@mvista.com |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 130e6228b587..7779f2d1acad 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -175,10 +175,10 @@ else | |||
175 | endif | 175 | endif |
176 | @touch $@ | 176 | @touch $@ |
177 | 177 | ||
178 | archprepare: maketools include/asm-arm/.arch | 178 | archprepare: maketools |
179 | 179 | ||
180 | .PHONY: maketools FORCE | 180 | .PHONY: maketools FORCE |
181 | maketools: include/linux/version.h FORCE | 181 | maketools: include/linux/version.h include/asm-arm/.arch FORCE |
182 | $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h | 182 | $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h |
183 | 183 | ||
184 | # Convert bzImage to zImage | 184 | # Convert bzImage to zImage |
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig index 94aafec5fb46..c279e41ed10e 100644 --- a/arch/arm/configs/ixp4xx_defconfig +++ b/arch/arm/configs/ixp4xx_defconfig | |||
@@ -1,14 +1,13 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.12-rc1-bk2 | 3 | # Linux kernel version: 2.6.14-rc1-git5 |
4 | # Sun Mar 27 22:53:40 2005 | 4 | # Tue Sep 20 17:26:28 2005 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_UID16=y | 8 | CONFIG_UID16=y |
9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
10 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_GENERIC_IOMAP=y | ||
12 | 11 | ||
13 | # | 12 | # |
14 | # Code maturity level options | 13 | # Code maturity level options |
@@ -16,11 +15,13 @@ CONFIG_GENERIC_IOMAP=y | |||
16 | CONFIG_EXPERIMENTAL=y | 15 | CONFIG_EXPERIMENTAL=y |
17 | CONFIG_CLEAN_COMPILE=y | 16 | CONFIG_CLEAN_COMPILE=y |
18 | CONFIG_BROKEN_ON_SMP=y | 17 | CONFIG_BROKEN_ON_SMP=y |
18 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
19 | 19 | ||
20 | # | 20 | # |
21 | # General setup | 21 | # General setup |
22 | # | 22 | # |
23 | CONFIG_LOCALVERSION="" | 23 | CONFIG_LOCALVERSION="" |
24 | CONFIG_LOCALVERSION_AUTO=y | ||
24 | CONFIG_SWAP=y | 25 | CONFIG_SWAP=y |
25 | CONFIG_SYSVIPC=y | 26 | CONFIG_SYSVIPC=y |
26 | # CONFIG_POSIX_MQUEUE is not set | 27 | # CONFIG_POSIX_MQUEUE is not set |
@@ -31,10 +32,13 @@ CONFIG_SYSCTL=y | |||
31 | # CONFIG_HOTPLUG is not set | 32 | # CONFIG_HOTPLUG is not set |
32 | CONFIG_KOBJECT_UEVENT=y | 33 | CONFIG_KOBJECT_UEVENT=y |
33 | # CONFIG_IKCONFIG is not set | 34 | # CONFIG_IKCONFIG is not set |
35 | CONFIG_INITRAMFS_SOURCE="" | ||
34 | CONFIG_EMBEDDED=y | 36 | CONFIG_EMBEDDED=y |
35 | CONFIG_KALLSYMS=y | 37 | CONFIG_KALLSYMS=y |
36 | # CONFIG_KALLSYMS_ALL is not set | 38 | # CONFIG_KALLSYMS_ALL is not set |
37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 39 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
40 | CONFIG_PRINTK=y | ||
41 | CONFIG_BUG=y | ||
38 | CONFIG_BASE_FULL=y | 42 | CONFIG_BASE_FULL=y |
39 | CONFIG_FUTEX=y | 43 | CONFIG_FUTEX=y |
40 | CONFIG_EPOLL=y | 44 | CONFIG_EPOLL=y |
@@ -81,6 +85,7 @@ CONFIG_ARCH_IXP4XX=y | |||
81 | # CONFIG_ARCH_VERSATILE is not set | 85 | # CONFIG_ARCH_VERSATILE is not set |
82 | # CONFIG_ARCH_IMX is not set | 86 | # CONFIG_ARCH_IMX is not set |
83 | # CONFIG_ARCH_H720X is not set | 87 | # CONFIG_ARCH_H720X is not set |
88 | # CONFIG_ARCH_AAEC2000 is not set | ||
84 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | 89 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y |
85 | 90 | ||
86 | # | 91 | # |
@@ -90,15 +95,16 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | |||
90 | # | 95 | # |
91 | # IXP4xx Platforms | 96 | # IXP4xx Platforms |
92 | # | 97 | # |
93 | # CONFIG_ARCH_AVILA is not set | 98 | CONFIG_ARCH_AVILA=y |
94 | CONFIG_ARCH_ADI_COYOTE=y | 99 | CONFIG_ARCH_ADI_COYOTE=y |
95 | CONFIG_ARCH_IXDP425=y | 100 | CONFIG_ARCH_IXDP425=y |
96 | # CONFIG_MACH_IXDPG425 is not set | 101 | CONFIG_MACH_IXDPG425=y |
97 | # CONFIG_MACH_IXDP465 is not set | 102 | CONFIG_MACH_IXDP465=y |
98 | CONFIG_ARCH_IXCDP1100=y | 103 | CONFIG_ARCH_IXCDP1100=y |
99 | CONFIG_ARCH_PRPMC1100=y | 104 | CONFIG_ARCH_PRPMC1100=y |
100 | CONFIG_ARCH_IXDP4XX=y | 105 | CONFIG_ARCH_IXDP4XX=y |
101 | # CONFIG_MACH_GTWX5715 is not set | 106 | CONFIG_CPU_IXP46X=y |
107 | CONFIG_MACH_GTWX5715=y | ||
102 | 108 | ||
103 | # | 109 | # |
104 | # IXP4xx Options | 110 | # IXP4xx Options |
@@ -114,7 +120,6 @@ CONFIG_CPU_32v5=y | |||
114 | CONFIG_CPU_ABRT_EV5T=y | 120 | CONFIG_CPU_ABRT_EV5T=y |
115 | CONFIG_CPU_CACHE_VIVT=y | 121 | CONFIG_CPU_CACHE_VIVT=y |
116 | CONFIG_CPU_TLB_V4WBI=y | 122 | CONFIG_CPU_TLB_V4WBI=y |
117 | CONFIG_CPU_MINICACHE=y | ||
118 | 123 | ||
119 | # | 124 | # |
120 | # Processor Features | 125 | # Processor Features |
@@ -127,9 +132,10 @@ CONFIG_DMABOUNCE=y | |||
127 | # | 132 | # |
128 | # Bus support | 133 | # Bus support |
129 | # | 134 | # |
135 | CONFIG_ISA_DMA_API=y | ||
130 | CONFIG_PCI=y | 136 | CONFIG_PCI=y |
131 | CONFIG_PCI_LEGACY_PROC=y | 137 | CONFIG_PCI_LEGACY_PROC=y |
132 | CONFIG_PCI_NAMES=y | 138 | # CONFIG_PCI_DEBUG is not set |
133 | 139 | ||
134 | # | 140 | # |
135 | # PCCARD (PCMCIA/CardBus) support | 141 | # PCCARD (PCMCIA/CardBus) support |
@@ -140,6 +146,15 @@ CONFIG_PCI_NAMES=y | |||
140 | # Kernel Features | 146 | # Kernel Features |
141 | # | 147 | # |
142 | # CONFIG_PREEMPT is not set | 148 | # CONFIG_PREEMPT is not set |
149 | # CONFIG_NO_IDLE_HZ is not set | ||
150 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | ||
151 | CONFIG_SELECT_MEMORY_MODEL=y | ||
152 | CONFIG_FLATMEM_MANUAL=y | ||
153 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
154 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
155 | CONFIG_FLATMEM=y | ||
156 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
157 | # CONFIG_SPARSEMEM_STATIC is not set | ||
143 | CONFIG_ALIGNMENT_TRAP=y | 158 | CONFIG_ALIGNMENT_TRAP=y |
144 | 159 | ||
145 | # | 160 | # |
@@ -175,6 +190,241 @@ CONFIG_PM=y | |||
175 | CONFIG_APM=y | 190 | CONFIG_APM=y |
176 | 191 | ||
177 | # | 192 | # |
193 | # Networking | ||
194 | # | ||
195 | CONFIG_NET=y | ||
196 | |||
197 | # | ||
198 | # Networking options | ||
199 | # | ||
200 | CONFIG_PACKET=m | ||
201 | CONFIG_PACKET_MMAP=y | ||
202 | CONFIG_UNIX=y | ||
203 | CONFIG_XFRM=y | ||
204 | # CONFIG_XFRM_USER is not set | ||
205 | # CONFIG_NET_KEY is not set | ||
206 | CONFIG_INET=y | ||
207 | CONFIG_IP_MULTICAST=y | ||
208 | CONFIG_IP_ADVANCED_ROUTER=y | ||
209 | CONFIG_ASK_IP_FIB_HASH=y | ||
210 | # CONFIG_IP_FIB_TRIE is not set | ||
211 | CONFIG_IP_FIB_HASH=y | ||
212 | CONFIG_IP_MULTIPLE_TABLES=y | ||
213 | CONFIG_IP_ROUTE_FWMARK=y | ||
214 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
215 | # CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set | ||
216 | CONFIG_IP_ROUTE_VERBOSE=y | ||
217 | CONFIG_IP_PNP=y | ||
218 | CONFIG_IP_PNP_DHCP=y | ||
219 | CONFIG_IP_PNP_BOOTP=y | ||
220 | # CONFIG_IP_PNP_RARP is not set | ||
221 | # CONFIG_NET_IPIP is not set | ||
222 | CONFIG_NET_IPGRE=m | ||
223 | CONFIG_NET_IPGRE_BROADCAST=y | ||
224 | CONFIG_IP_MROUTE=y | ||
225 | CONFIG_IP_PIMSM_V1=y | ||
226 | CONFIG_IP_PIMSM_V2=y | ||
227 | # CONFIG_ARPD is not set | ||
228 | CONFIG_SYN_COOKIES=y | ||
229 | # CONFIG_INET_AH is not set | ||
230 | # CONFIG_INET_ESP is not set | ||
231 | # CONFIG_INET_IPCOMP is not set | ||
232 | CONFIG_INET_TUNNEL=m | ||
233 | CONFIG_INET_DIAG=y | ||
234 | CONFIG_INET_TCP_DIAG=y | ||
235 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
236 | CONFIG_TCP_CONG_BIC=y | ||
237 | |||
238 | # | ||
239 | # IP: Virtual Server Configuration | ||
240 | # | ||
241 | CONFIG_IP_VS=m | ||
242 | CONFIG_IP_VS_DEBUG=y | ||
243 | CONFIG_IP_VS_TAB_BITS=12 | ||
244 | |||
245 | # | ||
246 | # IPVS transport protocol load balancing support | ||
247 | # | ||
248 | # CONFIG_IP_VS_PROTO_TCP is not set | ||
249 | # CONFIG_IP_VS_PROTO_UDP is not set | ||
250 | # CONFIG_IP_VS_PROTO_ESP is not set | ||
251 | # CONFIG_IP_VS_PROTO_AH is not set | ||
252 | |||
253 | # | ||
254 | # IPVS scheduler | ||
255 | # | ||
256 | CONFIG_IP_VS_RR=m | ||
257 | CONFIG_IP_VS_WRR=m | ||
258 | CONFIG_IP_VS_LC=m | ||
259 | CONFIG_IP_VS_WLC=m | ||
260 | CONFIG_IP_VS_LBLC=m | ||
261 | CONFIG_IP_VS_LBLCR=m | ||
262 | CONFIG_IP_VS_DH=m | ||
263 | CONFIG_IP_VS_SH=m | ||
264 | # CONFIG_IP_VS_SED is not set | ||
265 | # CONFIG_IP_VS_NQ is not set | ||
266 | |||
267 | # | ||
268 | # IPVS application helper | ||
269 | # | ||
270 | # CONFIG_IPV6 is not set | ||
271 | CONFIG_NETFILTER=y | ||
272 | # CONFIG_NETFILTER_DEBUG is not set | ||
273 | CONFIG_BRIDGE_NETFILTER=y | ||
274 | # CONFIG_NETFILTER_NETLINK is not set | ||
275 | |||
276 | # | ||
277 | # IP: Netfilter Configuration | ||
278 | # | ||
279 | CONFIG_IP_NF_CONNTRACK=m | ||
280 | # CONFIG_IP_NF_CT_ACCT is not set | ||
281 | # CONFIG_IP_NF_CONNTRACK_MARK is not set | ||
282 | # CONFIG_IP_NF_CONNTRACK_EVENTS is not set | ||
283 | # CONFIG_IP_NF_CT_PROTO_SCTP is not set | ||
284 | CONFIG_IP_NF_FTP=m | ||
285 | CONFIG_IP_NF_IRC=m | ||
286 | # CONFIG_IP_NF_NETBIOS_NS is not set | ||
287 | # CONFIG_IP_NF_TFTP is not set | ||
288 | # CONFIG_IP_NF_AMANDA is not set | ||
289 | CONFIG_IP_NF_QUEUE=m | ||
290 | CONFIG_IP_NF_IPTABLES=m | ||
291 | CONFIG_IP_NF_MATCH_LIMIT=m | ||
292 | # CONFIG_IP_NF_MATCH_IPRANGE is not set | ||
293 | CONFIG_IP_NF_MATCH_MAC=m | ||
294 | # CONFIG_IP_NF_MATCH_PKTTYPE is not set | ||
295 | CONFIG_IP_NF_MATCH_MARK=m | ||
296 | CONFIG_IP_NF_MATCH_MULTIPORT=m | ||
297 | CONFIG_IP_NF_MATCH_TOS=m | ||
298 | # CONFIG_IP_NF_MATCH_RECENT is not set | ||
299 | # CONFIG_IP_NF_MATCH_ECN is not set | ||
300 | # CONFIG_IP_NF_MATCH_DSCP is not set | ||
301 | CONFIG_IP_NF_MATCH_AH_ESP=m | ||
302 | CONFIG_IP_NF_MATCH_LENGTH=m | ||
303 | CONFIG_IP_NF_MATCH_TTL=m | ||
304 | CONFIG_IP_NF_MATCH_TCPMSS=m | ||
305 | # CONFIG_IP_NF_MATCH_HELPER is not set | ||
306 | CONFIG_IP_NF_MATCH_STATE=m | ||
307 | # CONFIG_IP_NF_MATCH_CONNTRACK is not set | ||
308 | CONFIG_IP_NF_MATCH_OWNER=m | ||
309 | # CONFIG_IP_NF_MATCH_PHYSDEV is not set | ||
310 | # CONFIG_IP_NF_MATCH_ADDRTYPE is not set | ||
311 | # CONFIG_IP_NF_MATCH_REALM is not set | ||
312 | # CONFIG_IP_NF_MATCH_SCTP is not set | ||
313 | # CONFIG_IP_NF_MATCH_DCCP is not set | ||
314 | # CONFIG_IP_NF_MATCH_COMMENT is not set | ||
315 | # CONFIG_IP_NF_MATCH_HASHLIMIT is not set | ||
316 | # CONFIG_IP_NF_MATCH_STRING is not set | ||
317 | CONFIG_IP_NF_FILTER=m | ||
318 | CONFIG_IP_NF_TARGET_REJECT=m | ||
319 | CONFIG_IP_NF_TARGET_LOG=m | ||
320 | CONFIG_IP_NF_TARGET_ULOG=m | ||
321 | CONFIG_IP_NF_TARGET_TCPMSS=m | ||
322 | CONFIG_IP_NF_NAT=m | ||
323 | CONFIG_IP_NF_NAT_NEEDED=y | ||
324 | CONFIG_IP_NF_TARGET_MASQUERADE=m | ||
325 | CONFIG_IP_NF_TARGET_REDIRECT=m | ||
326 | # CONFIG_IP_NF_TARGET_NETMAP is not set | ||
327 | # CONFIG_IP_NF_TARGET_SAME is not set | ||
328 | CONFIG_IP_NF_NAT_SNMP_BASIC=m | ||
329 | CONFIG_IP_NF_NAT_IRC=m | ||
330 | CONFIG_IP_NF_NAT_FTP=m | ||
331 | CONFIG_IP_NF_MANGLE=m | ||
332 | CONFIG_IP_NF_TARGET_TOS=m | ||
333 | # CONFIG_IP_NF_TARGET_ECN is not set | ||
334 | # CONFIG_IP_NF_TARGET_DSCP is not set | ||
335 | CONFIG_IP_NF_TARGET_MARK=m | ||
336 | # CONFIG_IP_NF_TARGET_CLASSIFY is not set | ||
337 | # CONFIG_IP_NF_TARGET_TTL is not set | ||
338 | # CONFIG_IP_NF_RAW is not set | ||
339 | CONFIG_IP_NF_ARPTABLES=m | ||
340 | CONFIG_IP_NF_ARPFILTER=m | ||
341 | # CONFIG_IP_NF_ARP_MANGLE is not set | ||
342 | |||
343 | # | ||
344 | # Bridge: Netfilter Configuration | ||
345 | # | ||
346 | # CONFIG_BRIDGE_NF_EBTABLES is not set | ||
347 | |||
348 | # | ||
349 | # DCCP Configuration (EXPERIMENTAL) | ||
350 | # | ||
351 | # CONFIG_IP_DCCP is not set | ||
352 | |||
353 | # | ||
354 | # SCTP Configuration (EXPERIMENTAL) | ||
355 | # | ||
356 | # CONFIG_IP_SCTP is not set | ||
357 | CONFIG_ATM=y | ||
358 | CONFIG_ATM_CLIP=y | ||
359 | # CONFIG_ATM_CLIP_NO_ICMP is not set | ||
360 | CONFIG_ATM_LANE=m | ||
361 | CONFIG_ATM_MPOA=m | ||
362 | CONFIG_ATM_BR2684=m | ||
363 | # CONFIG_ATM_BR2684_IPFILTER is not set | ||
364 | CONFIG_BRIDGE=m | ||
365 | CONFIG_VLAN_8021Q=m | ||
366 | # CONFIG_DECNET is not set | ||
367 | CONFIG_LLC=m | ||
368 | # CONFIG_LLC2 is not set | ||
369 | CONFIG_IPX=m | ||
370 | # CONFIG_IPX_INTERN is not set | ||
371 | CONFIG_ATALK=m | ||
372 | CONFIG_DEV_APPLETALK=y | ||
373 | CONFIG_IPDDP=m | ||
374 | CONFIG_IPDDP_ENCAP=y | ||
375 | CONFIG_IPDDP_DECAP=y | ||
376 | CONFIG_X25=m | ||
377 | CONFIG_LAPB=m | ||
378 | # CONFIG_NET_DIVERT is not set | ||
379 | CONFIG_ECONET=m | ||
380 | CONFIG_ECONET_AUNUDP=y | ||
381 | CONFIG_ECONET_NATIVE=y | ||
382 | CONFIG_WAN_ROUTER=m | ||
383 | CONFIG_NET_SCHED=y | ||
384 | CONFIG_NET_SCH_CLK_JIFFIES=y | ||
385 | # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set | ||
386 | # CONFIG_NET_SCH_CLK_CPU is not set | ||
387 | CONFIG_NET_SCH_CBQ=m | ||
388 | CONFIG_NET_SCH_HTB=m | ||
389 | # CONFIG_NET_SCH_HFSC is not set | ||
390 | # CONFIG_NET_SCH_ATM is not set | ||
391 | CONFIG_NET_SCH_PRIO=m | ||
392 | CONFIG_NET_SCH_RED=m | ||
393 | CONFIG_NET_SCH_SFQ=m | ||
394 | CONFIG_NET_SCH_TEQL=m | ||
395 | CONFIG_NET_SCH_TBF=m | ||
396 | CONFIG_NET_SCH_GRED=m | ||
397 | CONFIG_NET_SCH_DSMARK=m | ||
398 | # CONFIG_NET_SCH_NETEM is not set | ||
399 | CONFIG_NET_SCH_INGRESS=m | ||
400 | CONFIG_NET_QOS=y | ||
401 | CONFIG_NET_ESTIMATOR=y | ||
402 | CONFIG_NET_CLS=y | ||
403 | # CONFIG_NET_CLS_BASIC is not set | ||
404 | CONFIG_NET_CLS_TCINDEX=m | ||
405 | CONFIG_NET_CLS_ROUTE4=m | ||
406 | CONFIG_NET_CLS_ROUTE=y | ||
407 | CONFIG_NET_CLS_FW=m | ||
408 | CONFIG_NET_CLS_U32=m | ||
409 | # CONFIG_CLS_U32_PERF is not set | ||
410 | # CONFIG_NET_CLS_IND is not set | ||
411 | # CONFIG_CLS_U32_MARK is not set | ||
412 | CONFIG_NET_CLS_RSVP=m | ||
413 | CONFIG_NET_CLS_RSVP6=m | ||
414 | # CONFIG_NET_EMATCH is not set | ||
415 | # CONFIG_NET_CLS_ACT is not set | ||
416 | CONFIG_NET_CLS_POLICE=y | ||
417 | |||
418 | # | ||
419 | # Network testing | ||
420 | # | ||
421 | CONFIG_NET_PKTGEN=m | ||
422 | # CONFIG_HAMRADIO is not set | ||
423 | # CONFIG_IRDA is not set | ||
424 | # CONFIG_BT is not set | ||
425 | # CONFIG_IEEE80211 is not set | ||
426 | |||
427 | # | ||
178 | # Device Drivers | 428 | # Device Drivers |
179 | # | 429 | # |
180 | 430 | ||
@@ -244,6 +494,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y | |||
244 | CONFIG_MTD_IXP4XX=y | 494 | CONFIG_MTD_IXP4XX=y |
245 | # CONFIG_MTD_EDB7312 is not set | 495 | # CONFIG_MTD_EDB7312 is not set |
246 | # CONFIG_MTD_PCI is not set | 496 | # CONFIG_MTD_PCI is not set |
497 | # CONFIG_MTD_PLATRAM is not set | ||
247 | 498 | ||
248 | # | 499 | # |
249 | # Self-contained MTD device drivers | 500 | # Self-contained MTD device drivers |
@@ -283,7 +534,6 @@ CONFIG_MTD_NAND_IDS=m | |||
283 | # | 534 | # |
284 | # Block devices | 535 | # Block devices |
285 | # | 536 | # |
286 | # CONFIG_BLK_DEV_FD is not set | ||
287 | # CONFIG_BLK_CPQ_DA is not set | 537 | # CONFIG_BLK_CPQ_DA is not set |
288 | # CONFIG_BLK_CPQ_CISS_DA is not set | 538 | # CONFIG_BLK_CPQ_CISS_DA is not set |
289 | # CONFIG_BLK_DEV_DAC960 is not set | 539 | # CONFIG_BLK_DEV_DAC960 is not set |
@@ -297,7 +547,6 @@ CONFIG_BLK_DEV_RAM=y | |||
297 | CONFIG_BLK_DEV_RAM_COUNT=16 | 547 | CONFIG_BLK_DEV_RAM_COUNT=16 |
298 | CONFIG_BLK_DEV_RAM_SIZE=8192 | 548 | CONFIG_BLK_DEV_RAM_SIZE=8192 |
299 | CONFIG_BLK_DEV_INITRD=y | 549 | CONFIG_BLK_DEV_INITRD=y |
300 | CONFIG_INITRAMFS_SOURCE="" | ||
301 | # CONFIG_CDROM_PKTCDVD is not set | 550 | # CONFIG_CDROM_PKTCDVD is not set |
302 | 551 | ||
303 | # | 552 | # |
@@ -351,6 +600,7 @@ CONFIG_BLK_DEV_CMD64X=y | |||
351 | CONFIG_BLK_DEV_HPT366=y | 600 | CONFIG_BLK_DEV_HPT366=y |
352 | # CONFIG_BLK_DEV_SC1200 is not set | 601 | # CONFIG_BLK_DEV_SC1200 is not set |
353 | # CONFIG_BLK_DEV_PIIX is not set | 602 | # CONFIG_BLK_DEV_PIIX is not set |
603 | # CONFIG_BLK_DEV_IT821X is not set | ||
354 | # CONFIG_BLK_DEV_NS87415 is not set | 604 | # CONFIG_BLK_DEV_NS87415 is not set |
355 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set | 605 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set |
356 | CONFIG_BLK_DEV_PDC202XX_NEW=y | 606 | CONFIG_BLK_DEV_PDC202XX_NEW=y |
@@ -369,6 +619,7 @@ CONFIG_BLK_DEV_IDEDMA=y | |||
369 | # | 619 | # |
370 | # SCSI device support | 620 | # SCSI device support |
371 | # | 621 | # |
622 | # CONFIG_RAID_ATTRS is not set | ||
372 | # CONFIG_SCSI is not set | 623 | # CONFIG_SCSI is not set |
373 | 624 | ||
374 | # | 625 | # |
@@ -379,6 +630,7 @@ CONFIG_BLK_DEV_IDEDMA=y | |||
379 | # | 630 | # |
380 | # Fusion MPT device support | 631 | # Fusion MPT device support |
381 | # | 632 | # |
633 | # CONFIG_FUSION is not set | ||
382 | 634 | ||
383 | # | 635 | # |
384 | # IEEE 1394 (FireWire) support | 636 | # IEEE 1394 (FireWire) support |
@@ -391,235 +643,13 @@ CONFIG_BLK_DEV_IDEDMA=y | |||
391 | # CONFIG_I2O is not set | 643 | # CONFIG_I2O is not set |
392 | 644 | ||
393 | # | 645 | # |
394 | # Networking support | 646 | # Network device support |
395 | # | ||
396 | CONFIG_NET=y | ||
397 | |||
398 | # | ||
399 | # Networking options | ||
400 | # | ||
401 | CONFIG_PACKET=m | ||
402 | CONFIG_PACKET_MMAP=y | ||
403 | CONFIG_NETLINK_DEV=m | ||
404 | CONFIG_UNIX=y | ||
405 | # CONFIG_NET_KEY is not set | ||
406 | CONFIG_INET=y | ||
407 | CONFIG_IP_MULTICAST=y | ||
408 | CONFIG_IP_ADVANCED_ROUTER=y | ||
409 | CONFIG_IP_MULTIPLE_TABLES=y | ||
410 | CONFIG_IP_ROUTE_FWMARK=y | ||
411 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
412 | # CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set | ||
413 | CONFIG_IP_ROUTE_VERBOSE=y | ||
414 | CONFIG_IP_PNP=y | ||
415 | CONFIG_IP_PNP_DHCP=y | ||
416 | CONFIG_IP_PNP_BOOTP=y | ||
417 | # CONFIG_IP_PNP_RARP is not set | ||
418 | # CONFIG_NET_IPIP is not set | ||
419 | CONFIG_NET_IPGRE=m | ||
420 | CONFIG_NET_IPGRE_BROADCAST=y | ||
421 | CONFIG_IP_MROUTE=y | ||
422 | CONFIG_IP_PIMSM_V1=y | ||
423 | CONFIG_IP_PIMSM_V2=y | ||
424 | # CONFIG_ARPD is not set | ||
425 | CONFIG_SYN_COOKIES=y | ||
426 | # CONFIG_INET_AH is not set | ||
427 | # CONFIG_INET_ESP is not set | ||
428 | # CONFIG_INET_IPCOMP is not set | ||
429 | CONFIG_INET_TUNNEL=m | ||
430 | # CONFIG_IP_TCPDIAG is not set | ||
431 | # CONFIG_IP_TCPDIAG_IPV6 is not set | ||
432 | |||
433 | # | ||
434 | # IP: Virtual Server Configuration | ||
435 | # | ||
436 | CONFIG_IP_VS=m | ||
437 | CONFIG_IP_VS_DEBUG=y | ||
438 | CONFIG_IP_VS_TAB_BITS=12 | ||
439 | |||
440 | # | ||
441 | # IPVS transport protocol load balancing support | ||
442 | # | ||
443 | # CONFIG_IP_VS_PROTO_TCP is not set | ||
444 | # CONFIG_IP_VS_PROTO_UDP is not set | ||
445 | # CONFIG_IP_VS_PROTO_ESP is not set | ||
446 | # CONFIG_IP_VS_PROTO_AH is not set | ||
447 | |||
448 | # | ||
449 | # IPVS scheduler | ||
450 | # | ||
451 | CONFIG_IP_VS_RR=m | ||
452 | CONFIG_IP_VS_WRR=m | ||
453 | CONFIG_IP_VS_LC=m | ||
454 | CONFIG_IP_VS_WLC=m | ||
455 | CONFIG_IP_VS_LBLC=m | ||
456 | CONFIG_IP_VS_LBLCR=m | ||
457 | CONFIG_IP_VS_DH=m | ||
458 | CONFIG_IP_VS_SH=m | ||
459 | # CONFIG_IP_VS_SED is not set | ||
460 | # CONFIG_IP_VS_NQ is not set | ||
461 | |||
462 | # | ||
463 | # IPVS application helper | ||
464 | # | ||
465 | # CONFIG_IPV6 is not set | ||
466 | CONFIG_NETFILTER=y | ||
467 | # CONFIG_NETFILTER_DEBUG is not set | ||
468 | CONFIG_BRIDGE_NETFILTER=y | ||
469 | |||
470 | # | ||
471 | # IP: Netfilter Configuration | ||
472 | # | 647 | # |
473 | CONFIG_IP_NF_CONNTRACK=m | ||
474 | # CONFIG_IP_NF_CT_ACCT is not set | ||
475 | # CONFIG_IP_NF_CONNTRACK_MARK is not set | ||
476 | # CONFIG_IP_NF_CT_PROTO_SCTP is not set | ||
477 | CONFIG_IP_NF_FTP=m | ||
478 | CONFIG_IP_NF_IRC=m | ||
479 | # CONFIG_IP_NF_TFTP is not set | ||
480 | # CONFIG_IP_NF_AMANDA is not set | ||
481 | CONFIG_IP_NF_QUEUE=m | ||
482 | CONFIG_IP_NF_IPTABLES=m | ||
483 | CONFIG_IP_NF_MATCH_LIMIT=m | ||
484 | # CONFIG_IP_NF_MATCH_IPRANGE is not set | ||
485 | CONFIG_IP_NF_MATCH_MAC=m | ||
486 | # CONFIG_IP_NF_MATCH_PKTTYPE is not set | ||
487 | CONFIG_IP_NF_MATCH_MARK=m | ||
488 | CONFIG_IP_NF_MATCH_MULTIPORT=m | ||
489 | CONFIG_IP_NF_MATCH_TOS=m | ||
490 | # CONFIG_IP_NF_MATCH_RECENT is not set | ||
491 | # CONFIG_IP_NF_MATCH_ECN is not set | ||
492 | # CONFIG_IP_NF_MATCH_DSCP is not set | ||
493 | CONFIG_IP_NF_MATCH_AH_ESP=m | ||
494 | CONFIG_IP_NF_MATCH_LENGTH=m | ||
495 | CONFIG_IP_NF_MATCH_TTL=m | ||
496 | CONFIG_IP_NF_MATCH_TCPMSS=m | ||
497 | # CONFIG_IP_NF_MATCH_HELPER is not set | ||
498 | CONFIG_IP_NF_MATCH_STATE=m | ||
499 | # CONFIG_IP_NF_MATCH_CONNTRACK is not set | ||
500 | CONFIG_IP_NF_MATCH_OWNER=m | ||
501 | # CONFIG_IP_NF_MATCH_PHYSDEV is not set | ||
502 | # CONFIG_IP_NF_MATCH_ADDRTYPE is not set | ||
503 | # CONFIG_IP_NF_MATCH_REALM is not set | ||
504 | # CONFIG_IP_NF_MATCH_SCTP is not set | ||
505 | # CONFIG_IP_NF_MATCH_COMMENT is not set | ||
506 | # CONFIG_IP_NF_MATCH_HASHLIMIT is not set | ||
507 | CONFIG_IP_NF_FILTER=m | ||
508 | CONFIG_IP_NF_TARGET_REJECT=m | ||
509 | CONFIG_IP_NF_TARGET_LOG=m | ||
510 | CONFIG_IP_NF_TARGET_ULOG=m | ||
511 | CONFIG_IP_NF_TARGET_TCPMSS=m | ||
512 | CONFIG_IP_NF_NAT=m | ||
513 | CONFIG_IP_NF_NAT_NEEDED=y | ||
514 | CONFIG_IP_NF_TARGET_MASQUERADE=m | ||
515 | CONFIG_IP_NF_TARGET_REDIRECT=m | ||
516 | # CONFIG_IP_NF_TARGET_NETMAP is not set | ||
517 | # CONFIG_IP_NF_TARGET_SAME is not set | ||
518 | CONFIG_IP_NF_NAT_SNMP_BASIC=m | ||
519 | CONFIG_IP_NF_NAT_IRC=m | ||
520 | CONFIG_IP_NF_NAT_FTP=m | ||
521 | CONFIG_IP_NF_MANGLE=m | ||
522 | CONFIG_IP_NF_TARGET_TOS=m | ||
523 | # CONFIG_IP_NF_TARGET_ECN is not set | ||
524 | # CONFIG_IP_NF_TARGET_DSCP is not set | ||
525 | CONFIG_IP_NF_TARGET_MARK=m | ||
526 | # CONFIG_IP_NF_TARGET_CLASSIFY is not set | ||
527 | # CONFIG_IP_NF_RAW is not set | ||
528 | CONFIG_IP_NF_ARPTABLES=m | ||
529 | CONFIG_IP_NF_ARPFILTER=m | ||
530 | # CONFIG_IP_NF_ARP_MANGLE is not set | ||
531 | |||
532 | # | ||
533 | # Bridge: Netfilter Configuration | ||
534 | # | ||
535 | # CONFIG_BRIDGE_NF_EBTABLES is not set | ||
536 | CONFIG_XFRM=y | ||
537 | # CONFIG_XFRM_USER is not set | ||
538 | |||
539 | # | ||
540 | # SCTP Configuration (EXPERIMENTAL) | ||
541 | # | ||
542 | # CONFIG_IP_SCTP is not set | ||
543 | CONFIG_ATM=y | ||
544 | CONFIG_ATM_CLIP=y | ||
545 | # CONFIG_ATM_CLIP_NO_ICMP is not set | ||
546 | CONFIG_ATM_LANE=m | ||
547 | CONFIG_ATM_MPOA=m | ||
548 | CONFIG_ATM_BR2684=m | ||
549 | # CONFIG_ATM_BR2684_IPFILTER is not set | ||
550 | CONFIG_BRIDGE=m | ||
551 | CONFIG_VLAN_8021Q=m | ||
552 | # CONFIG_DECNET is not set | ||
553 | CONFIG_LLC=m | ||
554 | # CONFIG_LLC2 is not set | ||
555 | CONFIG_IPX=m | ||
556 | # CONFIG_IPX_INTERN is not set | ||
557 | CONFIG_ATALK=m | ||
558 | CONFIG_DEV_APPLETALK=y | ||
559 | CONFIG_IPDDP=m | ||
560 | CONFIG_IPDDP_ENCAP=y | ||
561 | CONFIG_IPDDP_DECAP=y | ||
562 | CONFIG_X25=m | ||
563 | CONFIG_LAPB=m | ||
564 | # CONFIG_NET_DIVERT is not set | ||
565 | CONFIG_ECONET=m | ||
566 | CONFIG_ECONET_AUNUDP=y | ||
567 | CONFIG_ECONET_NATIVE=y | ||
568 | CONFIG_WAN_ROUTER=m | ||
569 | |||
570 | # | ||
571 | # QoS and/or fair queueing | ||
572 | # | ||
573 | CONFIG_NET_SCHED=y | ||
574 | CONFIG_NET_SCH_CLK_JIFFIES=y | ||
575 | # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set | ||
576 | # CONFIG_NET_SCH_CLK_CPU is not set | ||
577 | CONFIG_NET_SCH_CBQ=m | ||
578 | CONFIG_NET_SCH_HTB=m | ||
579 | # CONFIG_NET_SCH_HFSC is not set | ||
580 | # CONFIG_NET_SCH_ATM is not set | ||
581 | CONFIG_NET_SCH_PRIO=m | ||
582 | CONFIG_NET_SCH_RED=m | ||
583 | CONFIG_NET_SCH_SFQ=m | ||
584 | CONFIG_NET_SCH_TEQL=m | ||
585 | CONFIG_NET_SCH_TBF=m | ||
586 | CONFIG_NET_SCH_GRED=m | ||
587 | CONFIG_NET_SCH_DSMARK=m | ||
588 | # CONFIG_NET_SCH_NETEM is not set | ||
589 | CONFIG_NET_SCH_INGRESS=m | ||
590 | CONFIG_NET_QOS=y | ||
591 | CONFIG_NET_ESTIMATOR=y | ||
592 | CONFIG_NET_CLS=y | ||
593 | # CONFIG_NET_CLS_BASIC is not set | ||
594 | CONFIG_NET_CLS_TCINDEX=m | ||
595 | CONFIG_NET_CLS_ROUTE4=m | ||
596 | CONFIG_NET_CLS_ROUTE=y | ||
597 | CONFIG_NET_CLS_FW=m | ||
598 | CONFIG_NET_CLS_U32=m | ||
599 | # CONFIG_CLS_U32_PERF is not set | ||
600 | # CONFIG_NET_CLS_IND is not set | ||
601 | # CONFIG_CLS_U32_MARK is not set | ||
602 | CONFIG_NET_CLS_RSVP=m | ||
603 | CONFIG_NET_CLS_RSVP6=m | ||
604 | # CONFIG_NET_EMATCH is not set | ||
605 | # CONFIG_NET_CLS_ACT is not set | ||
606 | CONFIG_NET_CLS_POLICE=y | ||
607 | |||
608 | # | ||
609 | # Network testing | ||
610 | # | ||
611 | CONFIG_NET_PKTGEN=m | ||
612 | # CONFIG_NETPOLL is not set | ||
613 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
614 | # CONFIG_HAMRADIO is not set | ||
615 | # CONFIG_IRDA is not set | ||
616 | # CONFIG_BT is not set | ||
617 | CONFIG_NETDEVICES=y | 648 | CONFIG_NETDEVICES=y |
618 | CONFIG_DUMMY=y | 649 | CONFIG_DUMMY=y |
619 | # CONFIG_BONDING is not set | 650 | # CONFIG_BONDING is not set |
620 | # CONFIG_EQUALIZER is not set | 651 | # CONFIG_EQUALIZER is not set |
621 | # CONFIG_TUN is not set | 652 | # CONFIG_TUN is not set |
622 | # CONFIG_ETHERTAP is not set | ||
623 | 653 | ||
624 | # | 654 | # |
625 | # ARCnet devices | 655 | # ARCnet devices |
@@ -627,6 +657,11 @@ CONFIG_DUMMY=y | |||
627 | # CONFIG_ARCNET is not set | 657 | # CONFIG_ARCNET is not set |
628 | 658 | ||
629 | # | 659 | # |
660 | # PHY device support | ||
661 | # | ||
662 | # CONFIG_PHYLIB is not set | ||
663 | |||
664 | # | ||
630 | # Ethernet (10 or 100Mbit) | 665 | # Ethernet (10 or 100Mbit) |
631 | # | 666 | # |
632 | CONFIG_NET_ETHERNET=y | 667 | CONFIG_NET_ETHERNET=y |
@@ -635,6 +670,7 @@ CONFIG_MII=y | |||
635 | # CONFIG_SUNGEM is not set | 670 | # CONFIG_SUNGEM is not set |
636 | # CONFIG_NET_VENDOR_3COM is not set | 671 | # CONFIG_NET_VENDOR_3COM is not set |
637 | # CONFIG_SMC91X is not set | 672 | # CONFIG_SMC91X is not set |
673 | # CONFIG_DM9000 is not set | ||
638 | 674 | ||
639 | # | 675 | # |
640 | # Tulip family network device support | 676 | # Tulip family network device support |
@@ -671,13 +707,17 @@ CONFIG_EEPRO100=y | |||
671 | # CONFIG_HAMACHI is not set | 707 | # CONFIG_HAMACHI is not set |
672 | # CONFIG_YELLOWFIN is not set | 708 | # CONFIG_YELLOWFIN is not set |
673 | # CONFIG_R8169 is not set | 709 | # CONFIG_R8169 is not set |
710 | # CONFIG_SIS190 is not set | ||
711 | # CONFIG_SKGE is not set | ||
674 | # CONFIG_SK98LIN is not set | 712 | # CONFIG_SK98LIN is not set |
675 | # CONFIG_VIA_VELOCITY is not set | 713 | # CONFIG_VIA_VELOCITY is not set |
676 | # CONFIG_TIGON3 is not set | 714 | # CONFIG_TIGON3 is not set |
715 | # CONFIG_BNX2 is not set | ||
677 | 716 | ||
678 | # | 717 | # |
679 | # Ethernet (10000 Mbit) | 718 | # Ethernet (10000 Mbit) |
680 | # | 719 | # |
720 | # CONFIG_CHELSIO_T1 is not set | ||
681 | # CONFIG_IXGB is not set | 721 | # CONFIG_IXGB is not set |
682 | # CONFIG_S2IO is not set | 722 | # CONFIG_S2IO is not set |
683 | 723 | ||
@@ -702,6 +742,7 @@ CONFIG_NET_RADIO=y | |||
702 | CONFIG_HERMES=y | 742 | CONFIG_HERMES=y |
703 | # CONFIG_PLX_HERMES is not set | 743 | # CONFIG_PLX_HERMES is not set |
704 | # CONFIG_TMD_HERMES is not set | 744 | # CONFIG_TMD_HERMES is not set |
745 | # CONFIG_NORTEL_HERMES is not set | ||
705 | CONFIG_PCI_HERMES=y | 746 | CONFIG_PCI_HERMES=y |
706 | # CONFIG_ATMEL is not set | 747 | # CONFIG_ATMEL is not set |
707 | 748 | ||
@@ -709,6 +750,7 @@ CONFIG_PCI_HERMES=y | |||
709 | # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support | 750 | # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support |
710 | # | 751 | # |
711 | # CONFIG_PRISM54 is not set | 752 | # CONFIG_PRISM54 is not set |
753 | # CONFIG_HOSTAP is not set | ||
712 | CONFIG_NET_WIRELESS=y | 754 | CONFIG_NET_WIRELESS=y |
713 | 755 | ||
714 | # | 756 | # |
@@ -758,6 +800,8 @@ CONFIG_ATM_TCP=m | |||
758 | # CONFIG_SLIP is not set | 800 | # CONFIG_SLIP is not set |
759 | # CONFIG_SHAPER is not set | 801 | # CONFIG_SHAPER is not set |
760 | # CONFIG_NETCONSOLE is not set | 802 | # CONFIG_NETCONSOLE is not set |
803 | # CONFIG_NETPOLL is not set | ||
804 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
761 | 805 | ||
762 | # | 806 | # |
763 | # ISDN subsystem | 807 | # ISDN subsystem |
@@ -795,7 +839,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
795 | # | 839 | # |
796 | # CONFIG_SERIO is not set | 840 | # CONFIG_SERIO is not set |
797 | # CONFIG_GAMEPORT is not set | 841 | # CONFIG_GAMEPORT is not set |
798 | CONFIG_SOUND_GAMEPORT=y | ||
799 | 842 | ||
800 | # | 843 | # |
801 | # Character devices | 844 | # Character devices |
@@ -816,6 +859,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2 | |||
816 | # | 859 | # |
817 | CONFIG_SERIAL_CORE=y | 860 | CONFIG_SERIAL_CORE=y |
818 | CONFIG_SERIAL_CORE_CONSOLE=y | 861 | CONFIG_SERIAL_CORE_CONSOLE=y |
862 | # CONFIG_SERIAL_JSM is not set | ||
819 | CONFIG_UNIX98_PTYS=y | 863 | CONFIG_UNIX98_PTYS=y |
820 | CONFIG_LEGACY_PTYS=y | 864 | CONFIG_LEGACY_PTYS=y |
821 | CONFIG_LEGACY_PTY_COUNT=256 | 865 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -882,12 +926,11 @@ CONFIG_I2C_ALGOBIT=y | |||
882 | # CONFIG_I2C_AMD8111 is not set | 926 | # CONFIG_I2C_AMD8111 is not set |
883 | # CONFIG_I2C_I801 is not set | 927 | # CONFIG_I2C_I801 is not set |
884 | # CONFIG_I2C_I810 is not set | 928 | # CONFIG_I2C_I810 is not set |
929 | # CONFIG_I2C_PIIX4 is not set | ||
885 | # CONFIG_I2C_IOP3XX is not set | 930 | # CONFIG_I2C_IOP3XX is not set |
886 | # CONFIG_I2C_ISA is not set | ||
887 | CONFIG_I2C_IXP4XX=y | 931 | CONFIG_I2C_IXP4XX=y |
888 | # CONFIG_I2C_NFORCE2 is not set | 932 | # CONFIG_I2C_NFORCE2 is not set |
889 | # CONFIG_I2C_PARPORT_LIGHT is not set | 933 | # CONFIG_I2C_PARPORT_LIGHT is not set |
890 | # CONFIG_I2C_PIIX4 is not set | ||
891 | # CONFIG_I2C_PROSAVAGE is not set | 934 | # CONFIG_I2C_PROSAVAGE is not set |
892 | # CONFIG_I2C_SAVAGE4 is not set | 935 | # CONFIG_I2C_SAVAGE4 is not set |
893 | # CONFIG_SCx200_ACB is not set | 936 | # CONFIG_SCx200_ACB is not set |
@@ -901,14 +944,33 @@ CONFIG_I2C_IXP4XX=y | |||
901 | # CONFIG_I2C_PCA_ISA is not set | 944 | # CONFIG_I2C_PCA_ISA is not set |
902 | 945 | ||
903 | # | 946 | # |
904 | # Hardware Sensors Chip support | 947 | # Miscellaneous I2C Chip support |
905 | # | 948 | # |
906 | CONFIG_I2C_SENSOR=y | 949 | # CONFIG_SENSORS_DS1337 is not set |
950 | # CONFIG_SENSORS_DS1374 is not set | ||
951 | CONFIG_SENSORS_EEPROM=y | ||
952 | # CONFIG_SENSORS_PCF8574 is not set | ||
953 | # CONFIG_SENSORS_PCA9539 is not set | ||
954 | # CONFIG_SENSORS_PCF8591 is not set | ||
955 | # CONFIG_SENSORS_RTC8564 is not set | ||
956 | # CONFIG_SENSORS_MAX6875 is not set | ||
957 | # CONFIG_I2C_DEBUG_CORE is not set | ||
958 | # CONFIG_I2C_DEBUG_ALGO is not set | ||
959 | # CONFIG_I2C_DEBUG_BUS is not set | ||
960 | # CONFIG_I2C_DEBUG_CHIP is not set | ||
961 | |||
962 | # | ||
963 | # Hardware Monitoring support | ||
964 | # | ||
965 | CONFIG_HWMON=y | ||
966 | # CONFIG_HWMON_VID is not set | ||
907 | # CONFIG_SENSORS_ADM1021 is not set | 967 | # CONFIG_SENSORS_ADM1021 is not set |
908 | # CONFIG_SENSORS_ADM1025 is not set | 968 | # CONFIG_SENSORS_ADM1025 is not set |
909 | # CONFIG_SENSORS_ADM1026 is not set | 969 | # CONFIG_SENSORS_ADM1026 is not set |
910 | # CONFIG_SENSORS_ADM1031 is not set | 970 | # CONFIG_SENSORS_ADM1031 is not set |
971 | # CONFIG_SENSORS_ADM9240 is not set | ||
911 | # CONFIG_SENSORS_ASB100 is not set | 972 | # CONFIG_SENSORS_ASB100 is not set |
973 | # CONFIG_SENSORS_ATXP1 is not set | ||
912 | # CONFIG_SENSORS_DS1621 is not set | 974 | # CONFIG_SENSORS_DS1621 is not set |
913 | # CONFIG_SENSORS_FSCHER is not set | 975 | # CONFIG_SENSORS_FSCHER is not set |
914 | # CONFIG_SENSORS_FSCPOS is not set | 976 | # CONFIG_SENSORS_FSCPOS is not set |
@@ -924,30 +986,26 @@ CONFIG_I2C_SENSOR=y | |||
924 | # CONFIG_SENSORS_LM85 is not set | 986 | # CONFIG_SENSORS_LM85 is not set |
925 | # CONFIG_SENSORS_LM87 is not set | 987 | # CONFIG_SENSORS_LM87 is not set |
926 | # CONFIG_SENSORS_LM90 is not set | 988 | # CONFIG_SENSORS_LM90 is not set |
989 | # CONFIG_SENSORS_LM92 is not set | ||
927 | # CONFIG_SENSORS_MAX1619 is not set | 990 | # CONFIG_SENSORS_MAX1619 is not set |
928 | # CONFIG_SENSORS_PC87360 is not set | 991 | # CONFIG_SENSORS_PC87360 is not set |
929 | # CONFIG_SENSORS_SMSC47B397 is not set | ||
930 | # CONFIG_SENSORS_SIS5595 is not set | 992 | # CONFIG_SENSORS_SIS5595 is not set |
931 | # CONFIG_SENSORS_SMSC47M1 is not set | 993 | # CONFIG_SENSORS_SMSC47M1 is not set |
994 | # CONFIG_SENSORS_SMSC47B397 is not set | ||
932 | # CONFIG_SENSORS_VIA686A is not set | 995 | # CONFIG_SENSORS_VIA686A is not set |
933 | # CONFIG_SENSORS_W83781D is not set | 996 | # CONFIG_SENSORS_W83781D is not set |
997 | # CONFIG_SENSORS_W83792D is not set | ||
934 | # CONFIG_SENSORS_W83L785TS is not set | 998 | # CONFIG_SENSORS_W83L785TS is not set |
935 | # CONFIG_SENSORS_W83627HF is not set | 999 | # CONFIG_SENSORS_W83627HF is not set |
1000 | # CONFIG_SENSORS_W83627EHF is not set | ||
1001 | # CONFIG_HWMON_DEBUG_CHIP is not set | ||
936 | 1002 | ||
937 | # | 1003 | # |
938 | # Other I2C Chip support | 1004 | # Misc devices |
939 | # | 1005 | # |
940 | CONFIG_SENSORS_EEPROM=y | ||
941 | # CONFIG_SENSORS_PCF8574 is not set | ||
942 | # CONFIG_SENSORS_PCF8591 is not set | ||
943 | # CONFIG_SENSORS_RTC8564 is not set | ||
944 | # CONFIG_I2C_DEBUG_CORE is not set | ||
945 | # CONFIG_I2C_DEBUG_ALGO is not set | ||
946 | # CONFIG_I2C_DEBUG_BUS is not set | ||
947 | # CONFIG_I2C_DEBUG_CHIP is not set | ||
948 | 1006 | ||
949 | # | 1007 | # |
950 | # Misc devices | 1008 | # Multimedia Capabilities Port drivers |
951 | # | 1009 | # |
952 | 1010 | ||
953 | # | 1011 | # |
@@ -994,6 +1052,7 @@ CONFIG_EXT2_FS=y | |||
994 | CONFIG_EXT2_FS_XATTR=y | 1052 | CONFIG_EXT2_FS_XATTR=y |
995 | CONFIG_EXT2_FS_POSIX_ACL=y | 1053 | CONFIG_EXT2_FS_POSIX_ACL=y |
996 | # CONFIG_EXT2_FS_SECURITY is not set | 1054 | # CONFIG_EXT2_FS_SECURITY is not set |
1055 | # CONFIG_EXT2_FS_XIP is not set | ||
997 | CONFIG_EXT3_FS=y | 1056 | CONFIG_EXT3_FS=y |
998 | CONFIG_EXT3_FS_XATTR=y | 1057 | CONFIG_EXT3_FS_XATTR=y |
999 | CONFIG_EXT3_FS_POSIX_ACL=y | 1058 | CONFIG_EXT3_FS_POSIX_ACL=y |
@@ -1004,17 +1063,15 @@ CONFIG_FS_MBCACHE=y | |||
1004 | # CONFIG_REISERFS_FS is not set | 1063 | # CONFIG_REISERFS_FS is not set |
1005 | # CONFIG_JFS_FS is not set | 1064 | # CONFIG_JFS_FS is not set |
1006 | CONFIG_FS_POSIX_ACL=y | 1065 | CONFIG_FS_POSIX_ACL=y |
1007 | |||
1008 | # | ||
1009 | # XFS support | ||
1010 | # | ||
1011 | # CONFIG_XFS_FS is not set | 1066 | # CONFIG_XFS_FS is not set |
1012 | # CONFIG_MINIX_FS is not set | 1067 | # CONFIG_MINIX_FS is not set |
1013 | # CONFIG_ROMFS_FS is not set | 1068 | # CONFIG_ROMFS_FS is not set |
1069 | CONFIG_INOTIFY=y | ||
1014 | # CONFIG_QUOTA is not set | 1070 | # CONFIG_QUOTA is not set |
1015 | CONFIG_DNOTIFY=y | 1071 | CONFIG_DNOTIFY=y |
1016 | # CONFIG_AUTOFS_FS is not set | 1072 | # CONFIG_AUTOFS_FS is not set |
1017 | # CONFIG_AUTOFS4_FS is not set | 1073 | # CONFIG_AUTOFS4_FS is not set |
1074 | # CONFIG_FUSE_FS is not set | ||
1018 | 1075 | ||
1019 | # | 1076 | # |
1020 | # CD-ROM/DVD Filesystems | 1077 | # CD-ROM/DVD Filesystems |
@@ -1034,12 +1091,10 @@ CONFIG_DNOTIFY=y | |||
1034 | # | 1091 | # |
1035 | CONFIG_PROC_FS=y | 1092 | CONFIG_PROC_FS=y |
1036 | CONFIG_SYSFS=y | 1093 | CONFIG_SYSFS=y |
1037 | # CONFIG_DEVFS_FS is not set | ||
1038 | # CONFIG_DEVPTS_FS_XATTR is not set | ||
1039 | CONFIG_TMPFS=y | 1094 | CONFIG_TMPFS=y |
1040 | # CONFIG_TMPFS_XATTR is not set | ||
1041 | # CONFIG_HUGETLB_PAGE is not set | 1095 | # CONFIG_HUGETLB_PAGE is not set |
1042 | CONFIG_RAMFS=y | 1096 | CONFIG_RAMFS=y |
1097 | # CONFIG_RELAYFS_FS is not set | ||
1043 | 1098 | ||
1044 | # | 1099 | # |
1045 | # Miscellaneous filesystems | 1100 | # Miscellaneous filesystems |
@@ -1054,8 +1109,7 @@ CONFIG_RAMFS=y | |||
1054 | # CONFIG_JFFS_FS is not set | 1109 | # CONFIG_JFFS_FS is not set |
1055 | CONFIG_JFFS2_FS=y | 1110 | CONFIG_JFFS2_FS=y |
1056 | CONFIG_JFFS2_FS_DEBUG=0 | 1111 | CONFIG_JFFS2_FS_DEBUG=0 |
1057 | # CONFIG_JFFS2_FS_NAND is not set | 1112 | CONFIG_JFFS2_FS_WRITEBUFFER=y |
1058 | # CONFIG_JFFS2_FS_NOR_ECC is not set | ||
1059 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set | 1113 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set |
1060 | CONFIG_JFFS2_ZLIB=y | 1114 | CONFIG_JFFS2_ZLIB=y |
1061 | CONFIG_JFFS2_RTIME=y | 1115 | CONFIG_JFFS2_RTIME=y |
@@ -1072,12 +1126,14 @@ CONFIG_JFFS2_RTIME=y | |||
1072 | # | 1126 | # |
1073 | CONFIG_NFS_FS=y | 1127 | CONFIG_NFS_FS=y |
1074 | CONFIG_NFS_V3=y | 1128 | CONFIG_NFS_V3=y |
1129 | # CONFIG_NFS_V3_ACL is not set | ||
1075 | # CONFIG_NFS_V4 is not set | 1130 | # CONFIG_NFS_V4 is not set |
1076 | # CONFIG_NFS_DIRECTIO is not set | 1131 | # CONFIG_NFS_DIRECTIO is not set |
1077 | # CONFIG_NFSD is not set | 1132 | # CONFIG_NFSD is not set |
1078 | CONFIG_ROOT_NFS=y | 1133 | CONFIG_ROOT_NFS=y |
1079 | CONFIG_LOCKD=y | 1134 | CONFIG_LOCKD=y |
1080 | CONFIG_LOCKD_V4=y | 1135 | CONFIG_LOCKD_V4=y |
1136 | CONFIG_NFS_COMMON=y | ||
1081 | CONFIG_SUNRPC=y | 1137 | CONFIG_SUNRPC=y |
1082 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 1138 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
1083 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 1139 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
@@ -1086,6 +1142,7 @@ CONFIG_SUNRPC=y | |||
1086 | # CONFIG_NCP_FS is not set | 1142 | # CONFIG_NCP_FS is not set |
1087 | # CONFIG_CODA_FS is not set | 1143 | # CONFIG_CODA_FS is not set |
1088 | # CONFIG_AFS_FS is not set | 1144 | # CONFIG_AFS_FS is not set |
1145 | # CONFIG_9P_FS is not set | ||
1089 | 1146 | ||
1090 | # | 1147 | # |
1091 | # Partition Types | 1148 | # Partition Types |
@@ -1124,6 +1181,7 @@ CONFIG_MSDOS_PARTITION=y | |||
1124 | CONFIG_DEBUG_KERNEL=y | 1181 | CONFIG_DEBUG_KERNEL=y |
1125 | CONFIG_MAGIC_SYSRQ=y | 1182 | CONFIG_MAGIC_SYSRQ=y |
1126 | CONFIG_LOG_BUF_SHIFT=14 | 1183 | CONFIG_LOG_BUF_SHIFT=14 |
1184 | CONFIG_DETECT_SOFTLOCKUP=y | ||
1127 | # CONFIG_SCHEDSTATS is not set | 1185 | # CONFIG_SCHEDSTATS is not set |
1128 | # CONFIG_DEBUG_SLAB is not set | 1186 | # CONFIG_DEBUG_SLAB is not set |
1129 | # CONFIG_DEBUG_SPINLOCK is not set | 1187 | # CONFIG_DEBUG_SPINLOCK is not set |
@@ -1158,6 +1216,7 @@ CONFIG_DEBUG_LL=y | |||
1158 | # Library routines | 1216 | # Library routines |
1159 | # | 1217 | # |
1160 | # CONFIG_CRC_CCITT is not set | 1218 | # CONFIG_CRC_CCITT is not set |
1219 | # CONFIG_CRC16 is not set | ||
1161 | CONFIG_CRC32=y | 1220 | CONFIG_CRC32=y |
1162 | # CONFIG_LIBCRC32C is not set | 1221 | # CONFIG_LIBCRC32C is not set |
1163 | CONFIG_ZLIB_INFLATE=y | 1222 | CONFIG_ZLIB_INFLATE=y |
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 52ad11328e96..36b6045213ee 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c | |||
@@ -125,7 +125,8 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) | |||
125 | } else if (type & IRQT_LOW) { | 125 | } else if (type & IRQT_LOW) { |
126 | int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW; | 126 | int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW; |
127 | irq_type = IXP4XX_IRQ_LEVEL; | 127 | irq_type = IXP4XX_IRQ_LEVEL; |
128 | } | 128 | } else |
129 | return -EINVAL; | ||
129 | 130 | ||
130 | ixp4xx_config_irq(irq, irq_type); | 131 | ixp4xx_config_irq(irq, irq_type); |
131 | 132 | ||
@@ -142,6 +143,8 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) | |||
142 | 143 | ||
143 | /* Set the new style */ | 144 | /* Set the new style */ |
144 | *int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE)); | 145 | *int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE)); |
146 | |||
147 | return 0; | ||
145 | } | 148 | } |
146 | 149 | ||
147 | static void ixp4xx_irq_mask(unsigned int irq) | 150 | static void ixp4xx_irq_mask(unsigned int irq) |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index a63351c085c6..838437b2d241 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/config.h> | 27 | #include <linux/config.h> |
28 | #include <linux/acpi.h> | 28 | #include <linux/acpi.h> |
29 | #include <linux/efi.h> | 29 | #include <linux/efi.h> |
30 | #include <linux/irq.h> | ||
31 | #include <linux/module.h> | 30 | #include <linux/module.h> |
32 | #include <linux/dmi.h> | 31 | #include <linux/dmi.h> |
33 | 32 | ||
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index a22a866de8f9..5546ddebec33 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | 19 | ||
20 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
21 | #include <linux/irq.h> | ||
22 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
23 | #include <linux/bootmem.h> | 22 | #include <linux/bootmem.h> |
24 | #include <linux/smp_lock.h> | 23 | #include <linux/smp_lock.h> |
diff --git a/arch/i386/kernel/cpu/mcheck/k7.c b/arch/i386/kernel/cpu/mcheck/k7.c index c4abe7657397..7c6b9c73522f 100644 --- a/arch/i386/kernel/cpu/mcheck/k7.c +++ b/arch/i386/kernel/cpu/mcheck/k7.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/config.h> | 9 | #include <linux/config.h> |
10 | #include <linux/irq.h> | ||
11 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
12 | #include <linux/smp.h> | 11 | #include <linux/smp.h> |
13 | 12 | ||
diff --git a/arch/i386/kernel/cpu/mcheck/non-fatal.c b/arch/i386/kernel/cpu/mcheck/non-fatal.c index 7864ddfccf07..82dffe0d4954 100644 --- a/arch/i386/kernel/cpu/mcheck/non-fatal.c +++ b/arch/i386/kernel/cpu/mcheck/non-fatal.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/jiffies.h> | 13 | #include <linux/jiffies.h> |
14 | #include <linux/config.h> | 14 | #include <linux/config.h> |
15 | #include <linux/irq.h> | ||
16 | #include <linux/workqueue.h> | 15 | #include <linux/workqueue.h> |
17 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
18 | #include <linux/smp.h> | 17 | #include <linux/smp.h> |
diff --git a/arch/i386/kernel/cpu/mcheck/p4.c b/arch/i386/kernel/cpu/mcheck/p4.c index 0abccb6fdf9e..1d1e885f500a 100644 --- a/arch/i386/kernel/cpu/mcheck/p4.c +++ b/arch/i386/kernel/cpu/mcheck/p4.c | |||
@@ -6,7 +6,6 @@ | |||
6 | #include <linux/types.h> | 6 | #include <linux/types.h> |
7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
8 | #include <linux/config.h> | 8 | #include <linux/config.h> |
9 | #include <linux/irq.h> | ||
10 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
11 | #include <linux/smp.h> | 10 | #include <linux/smp.h> |
12 | 11 | ||
diff --git a/arch/i386/kernel/cpu/mcheck/p5.c b/arch/i386/kernel/cpu/mcheck/p5.c index ec0614cd2925..3a2e24baddc7 100644 --- a/arch/i386/kernel/cpu/mcheck/p5.c +++ b/arch/i386/kernel/cpu/mcheck/p5.c | |||
@@ -6,7 +6,6 @@ | |||
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/irq.h> | ||
10 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
11 | #include <linux/smp.h> | 10 | #include <linux/smp.h> |
12 | 11 | ||
diff --git a/arch/i386/kernel/cpu/mcheck/p6.c b/arch/i386/kernel/cpu/mcheck/p6.c index f01b73f947e1..3c035b8fa3d9 100644 --- a/arch/i386/kernel/cpu/mcheck/p6.c +++ b/arch/i386/kernel/cpu/mcheck/p6.c | |||
@@ -6,7 +6,6 @@ | |||
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/irq.h> | ||
10 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
11 | #include <linux/smp.h> | 10 | #include <linux/smp.h> |
12 | 11 | ||
diff --git a/arch/i386/kernel/cpu/mcheck/winchip.c b/arch/i386/kernel/cpu/mcheck/winchip.c index 7bae68fa168f..5b9d2dd411d3 100644 --- a/arch/i386/kernel/cpu/mcheck/winchip.c +++ b/arch/i386/kernel/cpu/mcheck/winchip.c | |||
@@ -6,7 +6,6 @@ | |||
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/irq.h> | ||
10 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
11 | 10 | ||
12 | #include <asm/processor.h> | 11 | #include <asm/processor.h> |
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c index 913be77bb844..0248e084017c 100644 --- a/arch/i386/kernel/crash.c +++ b/arch/i386/kernel/crash.c | |||
@@ -11,10 +11,8 @@ | |||
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/smp.h> | 13 | #include <linux/smp.h> |
14 | #include <linux/irq.h> | ||
15 | #include <linux/reboot.h> | 14 | #include <linux/reboot.h> |
16 | #include <linux/kexec.h> | 15 | #include <linux/kexec.h> |
17 | #include <linux/irq.h> | ||
18 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
19 | #include <linux/elf.h> | 17 | #include <linux/elf.h> |
20 | #include <linux/elfcore.h> | 18 | #include <linux/elfcore.h> |
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index 178f4e9bac9d..323ef8ab3244 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <asm/atomic.h> | 16 | #include <asm/atomic.h> |
17 | #include <asm/system.h> | 17 | #include <asm/system.h> |
18 | #include <asm/io.h> | 18 | #include <asm/io.h> |
19 | #include <asm/irq.h> | ||
20 | #include <asm/timer.h> | 19 | #include <asm/timer.h> |
21 | #include <asm/pgtable.h> | 20 | #include <asm/pgtable.h> |
22 | #include <asm/delay.h> | 21 | #include <asm/delay.h> |
@@ -25,8 +24,6 @@ | |||
25 | #include <asm/arch_hooks.h> | 24 | #include <asm/arch_hooks.h> |
26 | #include <asm/i8259.h> | 25 | #include <asm/i8259.h> |
27 | 26 | ||
28 | #include <linux/irq.h> | ||
29 | |||
30 | #include <io_ports.h> | 27 | #include <io_ports.h> |
31 | 28 | ||
32 | /* | 29 | /* |
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 378313b0cce9..fb3991e8229e 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -21,7 +21,6 @@ | |||
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/irq.h> | ||
25 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
26 | #include <linux/init.h> | 25 | #include <linux/init.h> |
27 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index 15949fd08109..27aabfceb67e 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c | |||
@@ -14,7 +14,6 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/irq.h> | ||
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
19 | #include <linux/acpi.h> | 18 | #include <linux/acpi.h> |
20 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 0178457db721..72515b8a1b12 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c | |||
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | #include <linux/config.h> | 16 | #include <linux/config.h> |
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/irq.h> | ||
19 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
20 | #include <linux/bootmem.h> | 19 | #include <linux/bootmem.h> |
21 | #include <linux/smp_lock.h> | 20 | #include <linux/smp_lock.h> |
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index b45cbf93d439..7a14fdfd3af9 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c | |||
@@ -47,13 +47,11 @@ | |||
47 | #include <asm/ldt.h> | 47 | #include <asm/ldt.h> |
48 | #include <asm/processor.h> | 48 | #include <asm/processor.h> |
49 | #include <asm/i387.h> | 49 | #include <asm/i387.h> |
50 | #include <asm/irq.h> | ||
51 | #include <asm/desc.h> | 50 | #include <asm/desc.h> |
52 | #ifdef CONFIG_MATH_EMULATION | 51 | #ifdef CONFIG_MATH_EMULATION |
53 | #include <asm/math_emu.h> | 52 | #include <asm/math_emu.h> |
54 | #endif | 53 | #endif |
55 | 54 | ||
56 | #include <linux/irq.h> | ||
57 | #include <linux/err.h> | 55 | #include <linux/err.h> |
58 | 56 | ||
59 | #include <asm/tlbflush.h> | 57 | #include <asm/tlbflush.h> |
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 48b55db3680f..218d725a5a1e 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | 12 | ||
13 | #include <linux/mm.h> | 13 | #include <linux/mm.h> |
14 | #include <linux/irq.h> | ||
15 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
16 | #include <linux/spinlock.h> | 15 | #include <linux/spinlock.h> |
17 | #include <linux/smp_lock.h> | 16 | #include <linux/smp_lock.h> |
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 5f0a95d76a4f..1fb26d0e30b6 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include <linux/sched.h> | 42 | #include <linux/sched.h> |
43 | #include <linux/kernel_stat.h> | 43 | #include <linux/kernel_stat.h> |
44 | #include <linux/smp_lock.h> | 44 | #include <linux/smp_lock.h> |
45 | #include <linux/irq.h> | ||
46 | #include <linux/bootmem.h> | 45 | #include <linux/bootmem.h> |
47 | #include <linux/notifier.h> | 46 | #include <linux/notifier.h> |
48 | #include <linux/cpu.h> | 47 | #include <linux/cpu.h> |
diff --git a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c index eddb64038234..e42e46d35159 100644 --- a/arch/i386/kernel/timers/timer_pit.c +++ b/arch/i386/kernel/timers/timer_pit.c | |||
@@ -6,7 +6,6 @@ | |||
6 | #include <linux/spinlock.h> | 6 | #include <linux/spinlock.h> |
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/device.h> | 8 | #include <linux/device.h> |
9 | #include <linux/irq.h> | ||
10 | #include <linux/sysdev.h> | 9 | #include <linux/sysdev.h> |
11 | #include <linux/timex.h> | 10 | #include <linux/timex.h> |
12 | #include <asm/delay.h> | 11 | #include <asm/delay.h> |
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 431a551e46ea..19e90bdd84ea 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -52,7 +52,6 @@ | |||
52 | #include <asm/arch_hooks.h> | 52 | #include <asm/arch_hooks.h> |
53 | #include <asm/kdebug.h> | 53 | #include <asm/kdebug.h> |
54 | 54 | ||
55 | #include <linux/irq.h> | ||
56 | #include <linux/module.h> | 55 | #include <linux/module.h> |
57 | 56 | ||
58 | #include "mach_traps.h" | 57 | #include "mach_traps.h" |
diff --git a/arch/i386/mach-default/setup.c b/arch/i386/mach-default/setup.c index e5a1a83d09ef..b4a7455c6993 100644 --- a/arch/i386/mach-default/setup.c +++ b/arch/i386/mach-default/setup.c | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <linux/config.h> | 5 | #include <linux/config.h> |
6 | #include <linux/smp.h> | 6 | #include <linux/smp.h> |
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
8 | #include <linux/irq.h> | ||
9 | #include <linux/interrupt.h> | 8 | #include <linux/interrupt.h> |
10 | #include <asm/acpi.h> | 9 | #include <asm/acpi.h> |
11 | #include <asm/arch_hooks.h> | 10 | #include <asm/arch_hooks.h> |
diff --git a/arch/i386/mach-visws/setup.c b/arch/i386/mach-visws/setup.c index 26ada6fc0d77..07fac7e749c7 100644 --- a/arch/i386/mach-visws/setup.c +++ b/arch/i386/mach-visws/setup.c | |||
@@ -5,7 +5,6 @@ | |||
5 | 5 | ||
6 | #include <linux/smp.h> | 6 | #include <linux/smp.h> |
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
8 | #include <linux/irq.h> | ||
9 | #include <linux/interrupt.h> | 8 | #include <linux/interrupt.h> |
10 | 9 | ||
11 | #include <asm/fixmap.h> | 10 | #include <asm/fixmap.h> |
diff --git a/arch/i386/mach-visws/visws_apic.c b/arch/i386/mach-visws/visws_apic.c index 04e6585849a2..3e64fb721291 100644 --- a/arch/i386/mach-visws/visws_apic.c +++ b/arch/i386/mach-visws/visws_apic.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/config.h> | 19 | #include <linux/config.h> |
20 | #include <linux/kernel_stat.h> | 20 | #include <linux/kernel_stat.h> |
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | #include <linux/irq.h> | ||
23 | #include <linux/smp_lock.h> | 22 | #include <linux/smp_lock.h> |
24 | #include <linux/init.h> | 23 | #include <linux/init.h> |
25 | 24 | ||
diff --git a/arch/i386/mach-voyager/setup.c b/arch/i386/mach-voyager/setup.c index df123fc487bb..7d8a3acb9441 100644 --- a/arch/i386/mach-voyager/setup.c +++ b/arch/i386/mach-voyager/setup.c | |||
@@ -4,7 +4,6 @@ | |||
4 | 4 | ||
5 | #include <linux/config.h> | 5 | #include <linux/config.h> |
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/irq.h> | ||
8 | #include <linux/interrupt.h> | 7 | #include <linux/interrupt.h> |
9 | #include <asm/acpi.h> | 8 | #include <asm/acpi.h> |
10 | #include <asm/arch_hooks.h> | 9 | #include <asm/arch_hooks.h> |
diff --git a/arch/i386/mach-voyager/voyager_basic.c b/arch/i386/mach-voyager/voyager_basic.c index cc69875d979b..aa49a33a572c 100644 --- a/arch/i386/mach-voyager/voyager_basic.c +++ b/arch/i386/mach-voyager/voyager_basic.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <asm/voyager.h> | 27 | #include <asm/voyager.h> |
28 | #include <asm/vic.h> | 28 | #include <asm/vic.h> |
29 | #include <linux/pm.h> | 29 | #include <linux/pm.h> |
30 | #include <linux/irq.h> | ||
31 | #include <asm/tlbflush.h> | 30 | #include <asm/tlbflush.h> |
32 | #include <asm/arch_hooks.h> | 31 | #include <asm/arch_hooks.h> |
33 | #include <asm/i8253.h> | 32 | #include <asm/i8253.h> |
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index 46b0cf4a31e0..72a1b9cae2e4 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c | |||
@@ -30,8 +30,6 @@ | |||
30 | #include <asm/tlbflush.h> | 30 | #include <asm/tlbflush.h> |
31 | #include <asm/arch_hooks.h> | 31 | #include <asm/arch_hooks.h> |
32 | 32 | ||
33 | #include <linux/irq.h> | ||
34 | |||
35 | /* TLB state -- visible externally, indexed physically */ | 33 | /* TLB state -- visible externally, indexed physically */ |
36 | DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0 }; | 34 | DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0 }; |
37 | 35 | ||
diff --git a/arch/i386/mach-voyager/voyager_thread.c b/arch/i386/mach-voyager/voyager_thread.c index a9341b0eebff..2b03884fdb2a 100644 --- a/arch/i386/mach-voyager/voyager_thread.c +++ b/arch/i386/mach-voyager/voyager_thread.c | |||
@@ -31,8 +31,6 @@ | |||
31 | #include <asm/mtrr.h> | 31 | #include <asm/mtrr.h> |
32 | #include <asm/msr.h> | 32 | #include <asm/msr.h> |
33 | 33 | ||
34 | #include <linux/irq.h> | ||
35 | |||
36 | #define THREAD_NAME "kvoyagerd" | 34 | #define THREAD_NAME "kvoyagerd" |
37 | 35 | ||
38 | /* external variables */ | 36 | /* external variables */ |
diff --git a/arch/i386/oprofile/nmi_timer_int.c b/arch/i386/oprofile/nmi_timer_int.c index ad93cdd55d63..930a1127bb30 100644 --- a/arch/i386/oprofile/nmi_timer_int.c +++ b/arch/i386/oprofile/nmi_timer_int.c | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/smp.h> | 11 | #include <linux/smp.h> |
12 | #include <linux/irq.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/oprofile.h> | 13 | #include <linux/oprofile.h> |
14 | #include <linux/rcupdate.h> | 14 | #include <linux/rcupdate.h> |
15 | 15 | ||
diff --git a/arch/i386/pci/acpi.c b/arch/i386/pci/acpi.c index 2941674f35eb..7e7a202df3c8 100644 --- a/arch/i386/pci/acpi.c +++ b/arch/i386/pci/acpi.c | |||
@@ -1,7 +1,6 @@ | |||
1 | #include <linux/pci.h> | 1 | #include <linux/pci.h> |
2 | #include <linux/acpi.h> | 2 | #include <linux/acpi.h> |
3 | #include <linux/init.h> | 3 | #include <linux/init.h> |
4 | #include <linux/irq.h> | ||
5 | #include <asm/hw_irq.h> | 4 | #include <asm/hw_irq.h> |
6 | #include <asm/numa.h> | 5 | #include <asm/numa.h> |
7 | #include "pci.h" | 6 | #include "pci.h" |
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 326a2edc3834..281ed8ab347a 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | #include <linux/irq.h> | ||
15 | #include <linux/dmi.h> | 14 | #include <linux/dmi.h> |
16 | #include <asm/io.h> | 15 | #include <asm/io.h> |
17 | #include <asm/smp.h> | 16 | #include <asm/smp.h> |
diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c index 7b0b9ad848e5..b27c5acc79d0 100644 --- a/arch/i386/power/cpu.c +++ b/arch/i386/power/cpu.c | |||
@@ -8,25 +8,8 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/config.h> | 10 | #include <linux/config.h> |
11 | #include <linux/kernel.h> | ||
12 | #include <linux/module.h> | 11 | #include <linux/module.h> |
13 | #include <linux/init.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/poll.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/sysrq.h> | ||
19 | #include <linux/proc_fs.h> | ||
20 | #include <linux/irq.h> | ||
21 | #include <linux/pm.h> | ||
22 | #include <linux/device.h> | ||
23 | #include <linux/suspend.h> | 12 | #include <linux/suspend.h> |
24 | #include <linux/acpi.h> | ||
25 | |||
26 | #include <asm/uaccess.h> | ||
27 | #include <asm/acpi.h> | ||
28 | #include <asm/tlbflush.h> | ||
29 | #include <asm/processor.h> | ||
30 | 13 | ||
31 | static struct saved_context saved_context; | 14 | static struct saved_context saved_context; |
32 | 15 | ||
diff --git a/arch/m32r/Makefile b/arch/m32r/Makefile index dd4418d846e9..983d438b14b6 100644 --- a/arch/m32r/Makefile +++ b/arch/m32r/Makefile | |||
@@ -24,7 +24,7 @@ aflags-$(CONFIG_ISA_M32R) += -DNO_FPU -Wa,-no-bitinst | |||
24 | CFLAGS += $(cflags-y) | 24 | CFLAGS += $(cflags-y) |
25 | AFLAGS += $(aflags-y) | 25 | AFLAGS += $(aflags-y) |
26 | 26 | ||
27 | CHECKFLAGS := $(CHECK) -D__m32r__ | 27 | CHECKFLAGS += -D__m32r__ -D__BIG_ENDIAN__=1 |
28 | 28 | ||
29 | head-y := arch/m32r/kernel/head.o arch/m32r/kernel/init_task.o | 29 | head-y := arch/m32r/kernel/head.o arch/m32r/kernel/init_task.o |
30 | 30 | ||
diff --git a/arch/m32r/lib/usercopy.c b/arch/m32r/lib/usercopy.c index 6c6855f1aa05..ce16bbe26a52 100644 --- a/arch/m32r/lib/usercopy.c +++ b/arch/m32r/lib/usercopy.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
14 | 14 | ||
15 | unsigned long | 15 | unsigned long |
16 | __generic_copy_to_user(void *to, const void *from, unsigned long n) | 16 | __generic_copy_to_user(void __user *to, const void *from, unsigned long n) |
17 | { | 17 | { |
18 | prefetch(from); | 18 | prefetch(from); |
19 | if (access_ok(VERIFY_WRITE, to, n)) | 19 | if (access_ok(VERIFY_WRITE, to, n)) |
@@ -22,7 +22,7 @@ __generic_copy_to_user(void *to, const void *from, unsigned long n) | |||
22 | } | 22 | } |
23 | 23 | ||
24 | unsigned long | 24 | unsigned long |
25 | __generic_copy_from_user(void *to, const void *from, unsigned long n) | 25 | __generic_copy_from_user(void *to, const void __user *from, unsigned long n) |
26 | { | 26 | { |
27 | prefetchw(to); | 27 | prefetchw(to); |
28 | if (access_ok(VERIFY_READ, from, n)) | 28 | if (access_ok(VERIFY_READ, from, n)) |
@@ -111,7 +111,7 @@ do { \ | |||
111 | #endif /* CONFIG_ISA_DUAL_ISSUE */ | 111 | #endif /* CONFIG_ISA_DUAL_ISSUE */ |
112 | 112 | ||
113 | long | 113 | long |
114 | __strncpy_from_user(char *dst, const char *src, long count) | 114 | __strncpy_from_user(char *dst, const char __user *src, long count) |
115 | { | 115 | { |
116 | long res; | 116 | long res; |
117 | __do_strncpy_from_user(dst, src, count, res); | 117 | __do_strncpy_from_user(dst, src, count, res); |
@@ -119,7 +119,7 @@ __strncpy_from_user(char *dst, const char *src, long count) | |||
119 | } | 119 | } |
120 | 120 | ||
121 | long | 121 | long |
122 | strncpy_from_user(char *dst, const char *src, long count) | 122 | strncpy_from_user(char *dst, const char __user *src, long count) |
123 | { | 123 | { |
124 | long res = -EFAULT; | 124 | long res = -EFAULT; |
125 | if (access_ok(VERIFY_READ, src, 1)) | 125 | if (access_ok(VERIFY_READ, src, 1)) |
@@ -222,7 +222,7 @@ do { \ | |||
222 | #endif /* not CONFIG_ISA_DUAL_ISSUE */ | 222 | #endif /* not CONFIG_ISA_DUAL_ISSUE */ |
223 | 223 | ||
224 | unsigned long | 224 | unsigned long |
225 | clear_user(void *to, unsigned long n) | 225 | clear_user(void __user *to, unsigned long n) |
226 | { | 226 | { |
227 | if (access_ok(VERIFY_WRITE, to, n)) | 227 | if (access_ok(VERIFY_WRITE, to, n)) |
228 | __do_clear_user(to, n); | 228 | __do_clear_user(to, n); |
@@ -230,7 +230,7 @@ clear_user(void *to, unsigned long n) | |||
230 | } | 230 | } |
231 | 231 | ||
232 | unsigned long | 232 | unsigned long |
233 | __clear_user(void *to, unsigned long n) | 233 | __clear_user(void __user *to, unsigned long n) |
234 | { | 234 | { |
235 | __do_clear_user(to, n); | 235 | __do_clear_user(to, n); |
236 | return n; | 236 | return n; |
@@ -244,7 +244,7 @@ __clear_user(void *to, unsigned long n) | |||
244 | 244 | ||
245 | #ifdef CONFIG_ISA_DUAL_ISSUE | 245 | #ifdef CONFIG_ISA_DUAL_ISSUE |
246 | 246 | ||
247 | long strnlen_user(const char *s, long n) | 247 | long strnlen_user(const char __user *s, long n) |
248 | { | 248 | { |
249 | unsigned long mask = -__addr_ok(s); | 249 | unsigned long mask = -__addr_ok(s); |
250 | unsigned long res; | 250 | unsigned long res; |
@@ -313,7 +313,7 @@ long strnlen_user(const char *s, long n) | |||
313 | 313 | ||
314 | #else /* not CONFIG_ISA_DUAL_ISSUE */ | 314 | #else /* not CONFIG_ISA_DUAL_ISSUE */ |
315 | 315 | ||
316 | long strnlen_user(const char *s, long n) | 316 | long strnlen_user(const char __user *s, long n) |
317 | { | 317 | { |
318 | unsigned long mask = -__addr_ok(s); | 318 | unsigned long mask = -__addr_ok(s); |
319 | unsigned long res; | 319 | unsigned long res; |
diff --git a/arch/ppc/kernel/perfmon.c b/arch/ppc/kernel/perfmon.c index f9b27d939f76..c9a38dd0cdc4 100644 --- a/arch/ppc/kernel/perfmon.c +++ b/arch/ppc/kernel/perfmon.c | |||
@@ -45,9 +45,8 @@ static void dummy_perf(struct pt_regs *regs) | |||
45 | mtpmr(PMRN_PMGC0, pmgc0); | 45 | mtpmr(PMRN_PMGC0, pmgc0); |
46 | } | 46 | } |
47 | 47 | ||
48 | #elif CONFIG_6xx | 48 | #elif defined(CONFIG_6xx) |
49 | /* Ensure exceptions are disabled */ | 49 | /* Ensure exceptions are disabled */ |
50 | |||
51 | static void dummy_perf(struct pt_regs *regs) | 50 | static void dummy_perf(struct pt_regs *regs) |
52 | { | 51 | { |
53 | unsigned int mmcr0 = mfspr(SPRN_MMCR0); | 52 | unsigned int mmcr0 = mfspr(SPRN_MMCR0); |
diff --git a/arch/ppc64/kernel/machine_kexec.c b/arch/ppc64/kernel/machine_kexec.c index 4775f12a013c..bf7cc4f8210f 100644 --- a/arch/ppc64/kernel/machine_kexec.c +++ b/arch/ppc64/kernel/machine_kexec.c | |||
@@ -205,6 +205,7 @@ static void kexec_prepare_cpus(void) | |||
205 | continue; | 205 | continue; |
206 | 206 | ||
207 | while (paca[i].hw_cpu_id != -1) { | 207 | while (paca[i].hw_cpu_id != -1) { |
208 | barrier(); | ||
208 | if (!cpu_possible(i)) { | 209 | if (!cpu_possible(i)) { |
209 | printk("kexec: cpu %d hw_cpu_id %d is not" | 210 | printk("kexec: cpu %d hw_cpu_id %d is not" |
210 | " possible, ignoring\n", | 211 | " possible, ignoring\n", |
diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c index 874cf96938ff..174d14576c28 100644 --- a/arch/ppc64/mm/hash_native.c +++ b/arch/ppc64/mm/hash_native.c | |||
@@ -342,14 +342,13 @@ static void native_flush_hash_range(unsigned long number, int local) | |||
342 | hpte_t *hptep; | 342 | hpte_t *hptep; |
343 | unsigned long hpte_v; | 343 | unsigned long hpte_v; |
344 | struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); | 344 | struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); |
345 | unsigned long large; | 345 | unsigned long large = batch->large; |
346 | 346 | ||
347 | local_irq_save(flags); | 347 | local_irq_save(flags); |
348 | 348 | ||
349 | j = 0; | 349 | j = 0; |
350 | for (i = 0; i < number; i++) { | 350 | for (i = 0; i < number; i++) { |
351 | va = batch->vaddr[j]; | 351 | va = batch->vaddr[j]; |
352 | large = pte_huge(batch->pte[i]); | ||
353 | if (large) | 352 | if (large) |
354 | vpn = va >> HPAGE_SHIFT; | 353 | vpn = va >> HPAGE_SHIFT; |
355 | else | 354 | else |
@@ -399,7 +398,7 @@ static void native_flush_hash_range(unsigned long number, int local) | |||
399 | asm volatile("ptesync":::"memory"); | 398 | asm volatile("ptesync":::"memory"); |
400 | 399 | ||
401 | for (i = 0; i < j; i++) | 400 | for (i = 0; i < j; i++) |
402 | __tlbie(batch->vaddr[i], 0); | 401 | __tlbie(batch->vaddr[i], large); |
403 | 402 | ||
404 | asm volatile("eieio; tlbsync; ptesync":::"memory"); | 403 | asm volatile("eieio; tlbsync; ptesync":::"memory"); |
405 | 404 | ||
diff --git a/arch/ppc64/mm/tlb.c b/arch/ppc64/mm/tlb.c index 31afd95bf870..09ab81a10f4f 100644 --- a/arch/ppc64/mm/tlb.c +++ b/arch/ppc64/mm/tlb.c | |||
@@ -141,12 +141,14 @@ void hpte_update(struct mm_struct *mm, unsigned long addr, | |||
141 | * up scanning and resetting referenced bits then our batch context | 141 | * up scanning and resetting referenced bits then our batch context |
142 | * will change mid stream. | 142 | * will change mid stream. |
143 | */ | 143 | */ |
144 | if (unlikely(i != 0 && mm != batch->mm)) { | 144 | if (i != 0 && (mm != batch->mm || batch->large != pte_huge(pte))) { |
145 | flush_tlb_pending(); | 145 | flush_tlb_pending(); |
146 | i = 0; | 146 | i = 0; |
147 | } | 147 | } |
148 | if (i == 0) | 148 | if (i == 0) { |
149 | batch->mm = mm; | 149 | batch->mm = mm; |
150 | batch->large = pte_huge(pte); | ||
151 | } | ||
150 | if (addr < KERNELBASE) { | 152 | if (addr < KERNELBASE) { |
151 | vsid = get_vsid(mm->context.id, addr); | 153 | vsid = get_vsid(mm->context.id, addr); |
152 | WARN_ON(vsid == 0); | 154 | WARN_ON(vsid == 0); |
diff --git a/arch/sparc64/Kconfig.debug b/arch/sparc64/Kconfig.debug index af0e9411b83e..fa06ea04837b 100644 --- a/arch/sparc64/Kconfig.debug +++ b/arch/sparc64/Kconfig.debug | |||
@@ -33,6 +33,14 @@ config DEBUG_BOOTMEM | |||
33 | depends on DEBUG_KERNEL | 33 | depends on DEBUG_KERNEL |
34 | bool "Debug BOOTMEM initialization" | 34 | bool "Debug BOOTMEM initialization" |
35 | 35 | ||
36 | config DEBUG_PAGEALLOC | ||
37 | bool "Page alloc debugging" | ||
38 | depends on DEBUG_KERNEL && !SOFTWARE_SUSPEND | ||
39 | help | ||
40 | Unmap pages from the kernel linear mapping after free_pages(). | ||
41 | This results in a large slowdown, but helps to find certain types | ||
42 | of memory corruptions. | ||
43 | |||
36 | config MCOUNT | 44 | config MCOUNT |
37 | bool | 45 | bool |
38 | depends on STACK_DEBUG | 46 | depends on STACK_DEBUG |
diff --git a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c index d710274e516b..df9a1ca8fd77 100644 --- a/arch/sparc64/kernel/devices.c +++ b/arch/sparc64/kernel/devices.c | |||
@@ -135,6 +135,28 @@ void __init device_scan(void) | |||
135 | cpu_data(0).clock_tick = prom_getintdefault(cpu_node, | 135 | cpu_data(0).clock_tick = prom_getintdefault(cpu_node, |
136 | "clock-frequency", | 136 | "clock-frequency", |
137 | 0); | 137 | 0); |
138 | cpu_data(0).dcache_size = prom_getintdefault(cpu_node, | ||
139 | "dcache-size", | ||
140 | 16 * 1024); | ||
141 | cpu_data(0).dcache_line_size = | ||
142 | prom_getintdefault(cpu_node, "dcache-line-size", 32); | ||
143 | cpu_data(0).icache_size = prom_getintdefault(cpu_node, | ||
144 | "icache-size", | ||
145 | 16 * 1024); | ||
146 | cpu_data(0).icache_line_size = | ||
147 | prom_getintdefault(cpu_node, "icache-line-size", 32); | ||
148 | cpu_data(0).ecache_size = prom_getintdefault(cpu_node, | ||
149 | "ecache-size", | ||
150 | 4 * 1024 * 1024); | ||
151 | cpu_data(0).ecache_line_size = | ||
152 | prom_getintdefault(cpu_node, "ecache-line-size", 64); | ||
153 | printk("CPU[0]: Caches " | ||
154 | "D[sz(%d):line_sz(%d)] " | ||
155 | "I[sz(%d):line_sz(%d)] " | ||
156 | "E[sz(%d):line_sz(%d)]\n", | ||
157 | cpu_data(0).dcache_size, cpu_data(0).dcache_line_size, | ||
158 | cpu_data(0).icache_size, cpu_data(0).icache_line_size, | ||
159 | cpu_data(0).ecache_size, cpu_data(0).ecache_line_size); | ||
138 | } | 160 | } |
139 | #endif | 161 | #endif |
140 | 162 | ||
diff --git a/arch/sparc64/kernel/dtlb_backend.S b/arch/sparc64/kernel/dtlb_backend.S index 538522848ad4..acc889a7f9c1 100644 --- a/arch/sparc64/kernel/dtlb_backend.S +++ b/arch/sparc64/kernel/dtlb_backend.S | |||
@@ -9,17 +9,7 @@ | |||
9 | #include <asm/pgtable.h> | 9 | #include <asm/pgtable.h> |
10 | #include <asm/mmu.h> | 10 | #include <asm/mmu.h> |
11 | 11 | ||
12 | #if PAGE_SHIFT == 13 | 12 | #define VALID_SZ_BITS (_PAGE_VALID | _PAGE_SZBITS) |
13 | #define SZ_BITS _PAGE_SZ8K | ||
14 | #elif PAGE_SHIFT == 16 | ||
15 | #define SZ_BITS _PAGE_SZ64K | ||
16 | #elif PAGE_SHIFT == 19 | ||
17 | #define SZ_BITS _PAGE_SZ512K | ||
18 | #elif PAGE_SHIFT == 22 | ||
19 | #define SZ_BITS _PAGE_SZ4MB | ||
20 | #endif | ||
21 | |||
22 | #define VALID_SZ_BITS (_PAGE_VALID | SZ_BITS) | ||
23 | 13 | ||
24 | #define VPTE_BITS (_PAGE_CP | _PAGE_CV | _PAGE_P ) | 14 | #define VPTE_BITS (_PAGE_CP | _PAGE_CV | _PAGE_P ) |
25 | #define VPTE_SHIFT (PAGE_SHIFT - 3) | 15 | #define VPTE_SHIFT (PAGE_SHIFT - 3) |
@@ -163,7 +153,6 @@ sparc64_vpte_continue: | |||
163 | stxa %g4, [%g1 + %g1] ASI_DMMU ! Restore previous TAG_ACCESS | 153 | stxa %g4, [%g1 + %g1] ASI_DMMU ! Restore previous TAG_ACCESS |
164 | retry ! Load PTE once again | 154 | retry ! Load PTE once again |
165 | 155 | ||
166 | #undef SZ_BITS | ||
167 | #undef VALID_SZ_BITS | 156 | #undef VALID_SZ_BITS |
168 | #undef VPTE_SHIFT | 157 | #undef VPTE_SHIFT |
169 | #undef VPTE_BITS | 158 | #undef VPTE_BITS |
diff --git a/arch/sparc64/kernel/dtlb_base.S b/arch/sparc64/kernel/dtlb_base.S index ded2fed23fcc..702d349c1e88 100644 --- a/arch/sparc64/kernel/dtlb_base.S +++ b/arch/sparc64/kernel/dtlb_base.S | |||
@@ -71,7 +71,7 @@ | |||
71 | from_tl1_trap: | 71 | from_tl1_trap: |
72 | rdpr %tl, %g5 ! For TL==3 test | 72 | rdpr %tl, %g5 ! For TL==3 test |
73 | CREATE_VPTE_OFFSET1(%g4, %g6) ! Create VPTE offset | 73 | CREATE_VPTE_OFFSET1(%g4, %g6) ! Create VPTE offset |
74 | be,pn %xcc, 3f ! Yep, special processing | 74 | be,pn %xcc, kvmap ! Yep, special processing |
75 | CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset | 75 | CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset |
76 | cmp %g5, 4 ! Last trap level? | 76 | cmp %g5, 4 ! Last trap level? |
77 | be,pn %xcc, longpath ! Yep, cannot risk VPTE miss | 77 | be,pn %xcc, longpath ! Yep, cannot risk VPTE miss |
@@ -83,9 +83,9 @@ from_tl1_trap: | |||
83 | nop ! Delay-slot | 83 | nop ! Delay-slot |
84 | 9: stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB | 84 | 9: stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB |
85 | retry ! Trap return | 85 | retry ! Trap return |
86 | 3: brlz,pt %g4, 9b ! Kernel virtual map? | 86 | nop |
87 | xor %g2, %g4, %g5 ! Finish bit twiddles | 87 | nop |
88 | ba,a,pt %xcc, kvmap ! Yep, go check for obp/vmalloc | 88 | nop |
89 | 89 | ||
90 | /* DTLB ** ICACHE line 3: winfixups+real_faults */ | 90 | /* DTLB ** ICACHE line 3: winfixups+real_faults */ |
91 | longpath: | 91 | longpath: |
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index b48349527853..2879b1072921 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S | |||
@@ -30,159 +30,6 @@ | |||
30 | .text | 30 | .text |
31 | .align 32 | 31 | .align 32 |
32 | 32 | ||
33 | .globl sparc64_vpte_patchme1 | ||
34 | .globl sparc64_vpte_patchme2 | ||
35 | /* | ||
36 | * On a second level vpte miss, check whether the original fault is to the OBP | ||
37 | * range (note that this is only possible for instruction miss, data misses to | ||
38 | * obp range do not use vpte). If so, go back directly to the faulting address. | ||
39 | * This is because we want to read the tpc, otherwise we have no way of knowing | ||
40 | * the 8k aligned faulting address if we are using >8k kernel pagesize. This | ||
41 | * also ensures no vpte range addresses are dropped into tlb while obp is | ||
42 | * executing (see inherit_locked_prom_mappings() rant). | ||
43 | */ | ||
44 | sparc64_vpte_nucleus: | ||
45 | /* Note that kvmap below has verified that the address is | ||
46 | * in the range MODULES_VADDR --> VMALLOC_END already. So | ||
47 | * here we need only check if it is an OBP address or not. | ||
48 | */ | ||
49 | sethi %hi(LOW_OBP_ADDRESS), %g5 | ||
50 | cmp %g4, %g5 | ||
51 | blu,pn %xcc, sparc64_vpte_patchme1 | ||
52 | mov 0x1, %g5 | ||
53 | sllx %g5, 32, %g5 | ||
54 | cmp %g4, %g5 | ||
55 | blu,pn %xcc, obp_iaddr_patch | ||
56 | nop | ||
57 | |||
58 | /* These two instructions are patched by paginig_init(). */ | ||
59 | sparc64_vpte_patchme1: | ||
60 | sethi %hi(0), %g5 | ||
61 | sparc64_vpte_patchme2: | ||
62 | or %g5, %lo(0), %g5 | ||
63 | |||
64 | /* With kernel PGD in %g5, branch back into dtlb_backend. */ | ||
65 | ba,pt %xcc, sparc64_kpte_continue | ||
66 | andn %g1, 0x3, %g1 /* Finish PMD offset adjustment. */ | ||
67 | |||
68 | vpte_noent: | ||
69 | /* Restore previous TAG_ACCESS, %g5 is zero, and we will | ||
70 | * skip over the trap instruction so that the top level | ||
71 | * TLB miss handler will thing this %g5 value is just an | ||
72 | * invalid PTE, thus branching to full fault processing. | ||
73 | */ | ||
74 | mov TLB_SFSR, %g1 | ||
75 | stxa %g4, [%g1 + %g1] ASI_DMMU | ||
76 | done | ||
77 | |||
78 | .globl obp_iaddr_patch | ||
79 | obp_iaddr_patch: | ||
80 | /* These two instructions patched by inherit_prom_mappings(). */ | ||
81 | sethi %hi(0), %g5 | ||
82 | or %g5, %lo(0), %g5 | ||
83 | |||
84 | /* Behave as if we are at TL0. */ | ||
85 | wrpr %g0, 1, %tl | ||
86 | rdpr %tpc, %g4 /* Find original faulting iaddr */ | ||
87 | srlx %g4, 13, %g4 /* Throw out context bits */ | ||
88 | sllx %g4, 13, %g4 /* g4 has vpn + ctx0 now */ | ||
89 | |||
90 | /* Restore previous TAG_ACCESS. */ | ||
91 | mov TLB_SFSR, %g1 | ||
92 | stxa %g4, [%g1 + %g1] ASI_IMMU | ||
93 | |||
94 | /* Get PMD offset. */ | ||
95 | srlx %g4, 23, %g6 | ||
96 | and %g6, 0x7ff, %g6 | ||
97 | sllx %g6, 2, %g6 | ||
98 | |||
99 | /* Load PMD, is it valid? */ | ||
100 | lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 | ||
101 | brz,pn %g5, longpath | ||
102 | sllx %g5, 11, %g5 | ||
103 | |||
104 | /* Get PTE offset. */ | ||
105 | srlx %g4, 13, %g6 | ||
106 | and %g6, 0x3ff, %g6 | ||
107 | sllx %g6, 3, %g6 | ||
108 | |||
109 | /* Load PTE. */ | ||
110 | ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 | ||
111 | brgez,pn %g5, longpath | ||
112 | nop | ||
113 | |||
114 | /* TLB load and return from trap. */ | ||
115 | stxa %g5, [%g0] ASI_ITLB_DATA_IN | ||
116 | retry | ||
117 | |||
118 | .globl obp_daddr_patch | ||
119 | obp_daddr_patch: | ||
120 | /* These two instructions patched by inherit_prom_mappings(). */ | ||
121 | sethi %hi(0), %g5 | ||
122 | or %g5, %lo(0), %g5 | ||
123 | |||
124 | /* Get PMD offset. */ | ||
125 | srlx %g4, 23, %g6 | ||
126 | and %g6, 0x7ff, %g6 | ||
127 | sllx %g6, 2, %g6 | ||
128 | |||
129 | /* Load PMD, is it valid? */ | ||
130 | lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 | ||
131 | brz,pn %g5, longpath | ||
132 | sllx %g5, 11, %g5 | ||
133 | |||
134 | /* Get PTE offset. */ | ||
135 | srlx %g4, 13, %g6 | ||
136 | and %g6, 0x3ff, %g6 | ||
137 | sllx %g6, 3, %g6 | ||
138 | |||
139 | /* Load PTE. */ | ||
140 | ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 | ||
141 | brgez,pn %g5, longpath | ||
142 | nop | ||
143 | |||
144 | /* TLB load and return from trap. */ | ||
145 | stxa %g5, [%g0] ASI_DTLB_DATA_IN | ||
146 | retry | ||
147 | |||
148 | /* | ||
149 | * On a first level data miss, check whether this is to the OBP range (note | ||
150 | * that such accesses can be made by prom, as well as by kernel using | ||
151 | * prom_getproperty on "address"), and if so, do not use vpte access ... | ||
152 | * rather, use information saved during inherit_prom_mappings() using 8k | ||
153 | * pagesize. | ||
154 | */ | ||
155 | .align 32 | ||
156 | kvmap: | ||
157 | sethi %hi(MODULES_VADDR), %g5 | ||
158 | cmp %g4, %g5 | ||
159 | blu,pn %xcc, longpath | ||
160 | mov (VMALLOC_END >> 24), %g5 | ||
161 | sllx %g5, 24, %g5 | ||
162 | cmp %g4, %g5 | ||
163 | bgeu,pn %xcc, longpath | ||
164 | nop | ||
165 | |||
166 | kvmap_check_obp: | ||
167 | sethi %hi(LOW_OBP_ADDRESS), %g5 | ||
168 | cmp %g4, %g5 | ||
169 | blu,pn %xcc, kvmap_vmalloc_addr | ||
170 | mov 0x1, %g5 | ||
171 | sllx %g5, 32, %g5 | ||
172 | cmp %g4, %g5 | ||
173 | blu,pn %xcc, obp_daddr_patch | ||
174 | nop | ||
175 | |||
176 | kvmap_vmalloc_addr: | ||
177 | /* If we get here, a vmalloc addr was accessed, load kernel VPTE. */ | ||
178 | ldxa [%g3 + %g6] ASI_N, %g5 | ||
179 | brgez,pn %g5, longpath | ||
180 | nop | ||
181 | |||
182 | /* PTE is valid, load into TLB and return from trap. */ | ||
183 | stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB | ||
184 | retry | ||
185 | |||
186 | /* This is trivial with the new code... */ | 33 | /* This is trivial with the new code... */ |
187 | .globl do_fpdis | 34 | .globl do_fpdis |
188 | do_fpdis: | 35 | do_fpdis: |
@@ -525,14 +372,13 @@ cheetah_plus_patch_fpdis: | |||
525 | * | 372 | * |
526 | * DATA 0: [low 32-bits] Address of function to call, jmp to this | 373 | * DATA 0: [low 32-bits] Address of function to call, jmp to this |
527 | * [high 32-bits] MMU Context Argument 0, place in %g5 | 374 | * [high 32-bits] MMU Context Argument 0, place in %g5 |
528 | * DATA 1: Address Argument 1, place in %g6 | 375 | * DATA 1: Address Argument 1, place in %g1 |
529 | * DATA 2: Address Argument 2, place in %g7 | 376 | * DATA 2: Address Argument 2, place in %g7 |
530 | * | 377 | * |
531 | * With this method we can do most of the cross-call tlb/cache | 378 | * With this method we can do most of the cross-call tlb/cache |
532 | * flushing very quickly. | 379 | * flushing very quickly. |
533 | * | 380 | * |
534 | * Current CPU's IRQ worklist table is locked into %g1, | 381 | * Current CPU's IRQ worklist table is locked into %g6, don't touch. |
535 | * don't touch. | ||
536 | */ | 382 | */ |
537 | .text | 383 | .text |
538 | .align 32 | 384 | .align 32 |
@@ -1006,13 +852,14 @@ cheetah_plus_dcpe_trap_vector: | |||
1006 | nop | 852 | nop |
1007 | 853 | ||
1008 | do_cheetah_plus_data_parity: | 854 | do_cheetah_plus_data_parity: |
1009 | ba,pt %xcc, etrap | 855 | rdpr %pil, %g2 |
856 | wrpr %g0, 15, %pil | ||
857 | ba,pt %xcc, etrap_irq | ||
1010 | rd %pc, %g7 | 858 | rd %pc, %g7 |
1011 | mov 0x0, %o0 | 859 | mov 0x0, %o0 |
1012 | call cheetah_plus_parity_error | 860 | call cheetah_plus_parity_error |
1013 | add %sp, PTREGS_OFF, %o1 | 861 | add %sp, PTREGS_OFF, %o1 |
1014 | ba,pt %xcc, rtrap | 862 | ba,a,pt %xcc, rtrap_irq |
1015 | clr %l6 | ||
1016 | 863 | ||
1017 | cheetah_plus_dcpe_trap_vector_tl1: | 864 | cheetah_plus_dcpe_trap_vector_tl1: |
1018 | membar #Sync | 865 | membar #Sync |
@@ -1036,13 +883,14 @@ cheetah_plus_icpe_trap_vector: | |||
1036 | nop | 883 | nop |
1037 | 884 | ||
1038 | do_cheetah_plus_insn_parity: | 885 | do_cheetah_plus_insn_parity: |
1039 | ba,pt %xcc, etrap | 886 | rdpr %pil, %g2 |
887 | wrpr %g0, 15, %pil | ||
888 | ba,pt %xcc, etrap_irq | ||
1040 | rd %pc, %g7 | 889 | rd %pc, %g7 |
1041 | mov 0x1, %o0 | 890 | mov 0x1, %o0 |
1042 | call cheetah_plus_parity_error | 891 | call cheetah_plus_parity_error |
1043 | add %sp, PTREGS_OFF, %o1 | 892 | add %sp, PTREGS_OFF, %o1 |
1044 | ba,pt %xcc, rtrap | 893 | ba,a,pt %xcc, rtrap_irq |
1045 | clr %l6 | ||
1046 | 894 | ||
1047 | cheetah_plus_icpe_trap_vector_tl1: | 895 | cheetah_plus_icpe_trap_vector_tl1: |
1048 | membar #Sync | 896 | membar #Sync |
@@ -1075,6 +923,10 @@ do_dcpe_tl1: | |||
1075 | nop | 923 | nop |
1076 | wrpr %g1, %tl ! Restore original trap level | 924 | wrpr %g1, %tl ! Restore original trap level |
1077 | do_dcpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ | 925 | do_dcpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ |
926 | sethi %hi(dcache_parity_tl1_occurred), %g2 | ||
927 | lduw [%g2 + %lo(dcache_parity_tl1_occurred)], %g1 | ||
928 | add %g1, 1, %g1 | ||
929 | stw %g1, [%g2 + %lo(dcache_parity_tl1_occurred)] | ||
1078 | /* Reset D-cache parity */ | 930 | /* Reset D-cache parity */ |
1079 | sethi %hi(1 << 16), %g1 ! D-cache size | 931 | sethi %hi(1 << 16), %g1 ! D-cache size |
1080 | mov (1 << 5), %g2 ! D-cache line size | 932 | mov (1 << 5), %g2 ! D-cache line size |
@@ -1121,6 +973,10 @@ do_icpe_tl1: | |||
1121 | nop | 973 | nop |
1122 | wrpr %g1, %tl ! Restore original trap level | 974 | wrpr %g1, %tl ! Restore original trap level |
1123 | do_icpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ | 975 | do_icpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */ |
976 | sethi %hi(icache_parity_tl1_occurred), %g2 | ||
977 | lduw [%g2 + %lo(icache_parity_tl1_occurred)], %g1 | ||
978 | add %g1, 1, %g1 | ||
979 | stw %g1, [%g2 + %lo(icache_parity_tl1_occurred)] | ||
1124 | /* Flush I-cache */ | 980 | /* Flush I-cache */ |
1125 | sethi %hi(1 << 15), %g1 ! I-cache size | 981 | sethi %hi(1 << 15), %g1 ! I-cache size |
1126 | mov (1 << 5), %g2 ! I-cache line size | 982 | mov (1 << 5), %g2 ! I-cache line size |
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index 1fa06c4e3bdb..ecc748fb9ad7 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S | |||
@@ -80,15 +80,165 @@ sparc_ramdisk_image64: | |||
80 | .xword 0 | 80 | .xword 0 |
81 | .word _end | 81 | .word _end |
82 | 82 | ||
83 | /* We must be careful, 32-bit OpenBOOT will get confused if it | 83 | /* PROM cif handler code address is in %o4. */ |
84 | * tries to save away a register window to a 64-bit kernel | 84 | sparc64_boot: |
85 | * stack address. Flush all windows, disable interrupts, | 85 | 1: rd %pc, %g7 |
86 | * remap if necessary, jump onto kernel trap table, then kernel | 86 | set 1b, %g1 |
87 | * stack, or else we die. | 87 | cmp %g1, %g7 |
88 | be,pn %xcc, sparc64_boot_after_remap | ||
89 | mov %o4, %l7 | ||
90 | |||
91 | /* We need to remap the kernel. Use position independant | ||
92 | * code to remap us to KERNBASE. | ||
88 | * | 93 | * |
89 | * PROM entry point is on %o4 | 94 | * SILO can invoke us with 32-bit address masking enabled, |
95 | * so make sure that's clear. | ||
90 | */ | 96 | */ |
91 | sparc64_boot: | 97 | rdpr %pstate, %g1 |
98 | andn %g1, PSTATE_AM, %g1 | ||
99 | wrpr %g1, 0x0, %pstate | ||
100 | ba,a,pt %xcc, 1f | ||
101 | |||
102 | .globl prom_finddev_name, prom_chosen_path | ||
103 | .globl prom_getprop_name, prom_mmu_name | ||
104 | .globl prom_callmethod_name, prom_translate_name | ||
105 | .globl prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache | ||
106 | .globl prom_boot_mapped_pc, prom_boot_mapping_mode | ||
107 | .globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low | ||
108 | prom_finddev_name: | ||
109 | .asciz "finddevice" | ||
110 | prom_chosen_path: | ||
111 | .asciz "/chosen" | ||
112 | prom_getprop_name: | ||
113 | .asciz "getprop" | ||
114 | prom_mmu_name: | ||
115 | .asciz "mmu" | ||
116 | prom_callmethod_name: | ||
117 | .asciz "call-method" | ||
118 | prom_translate_name: | ||
119 | .asciz "translate" | ||
120 | prom_map_name: | ||
121 | .asciz "map" | ||
122 | prom_unmap_name: | ||
123 | .asciz "unmap" | ||
124 | .align 4 | ||
125 | prom_mmu_ihandle_cache: | ||
126 | .word 0 | ||
127 | prom_boot_mapped_pc: | ||
128 | .word 0 | ||
129 | prom_boot_mapping_mode: | ||
130 | .word 0 | ||
131 | .align 8 | ||
132 | prom_boot_mapping_phys_high: | ||
133 | .xword 0 | ||
134 | prom_boot_mapping_phys_low: | ||
135 | .xword 0 | ||
136 | 1: | ||
137 | rd %pc, %l0 | ||
138 | mov (1b - prom_finddev_name), %l1 | ||
139 | mov (1b - prom_chosen_path), %l2 | ||
140 | mov (1b - prom_boot_mapped_pc), %l3 | ||
141 | sub %l0, %l1, %l1 | ||
142 | sub %l0, %l2, %l2 | ||
143 | sub %l0, %l3, %l3 | ||
144 | stw %l0, [%l3] | ||
145 | sub %sp, (192 + 128), %sp | ||
146 | |||
147 | /* chosen_node = prom_finddevice("/chosen") */ | ||
148 | stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "finddevice" | ||
149 | mov 1, %l3 | ||
150 | stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 1 | ||
151 | stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 | ||
152 | stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1, "/chosen" | ||
153 | stx %g0, [%sp + 2047 + 128 + 0x20] ! ret1 | ||
154 | call %l7 | ||
155 | add %sp, (2047 + 128), %o0 ! argument array | ||
156 | |||
157 | ldx [%sp + 2047 + 128 + 0x20], %l4 ! chosen device node | ||
158 | |||
159 | mov (1b - prom_getprop_name), %l1 | ||
160 | mov (1b - prom_mmu_name), %l2 | ||
161 | mov (1b - prom_mmu_ihandle_cache), %l5 | ||
162 | sub %l0, %l1, %l1 | ||
163 | sub %l0, %l2, %l2 | ||
164 | sub %l0, %l5, %l5 | ||
165 | |||
166 | /* prom_mmu_ihandle_cache = prom_getint(chosen_node, "mmu") */ | ||
167 | stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "getprop" | ||
168 | mov 4, %l3 | ||
169 | stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 4 | ||
170 | mov 1, %l3 | ||
171 | stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 | ||
172 | stx %l4, [%sp + 2047 + 128 + 0x18] ! arg1, chosen_node | ||
173 | stx %l2, [%sp + 2047 + 128 + 0x20] ! arg2, "mmu" | ||
174 | stx %l5, [%sp + 2047 + 128 + 0x28] ! arg3, &prom_mmu_ihandle_cache | ||
175 | mov 4, %l3 | ||
176 | stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4, sizeof(arg3) | ||
177 | stx %g0, [%sp + 2047 + 128 + 0x38] ! ret1 | ||
178 | call %l7 | ||
179 | add %sp, (2047 + 128), %o0 ! argument array | ||
180 | |||
181 | mov (1b - prom_callmethod_name), %l1 | ||
182 | mov (1b - prom_translate_name), %l2 | ||
183 | sub %l0, %l1, %l1 | ||
184 | sub %l0, %l2, %l2 | ||
185 | lduw [%l5], %l5 ! prom_mmu_ihandle_cache | ||
186 | |||
187 | stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "call-method" | ||
188 | mov 3, %l3 | ||
189 | stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 3 | ||
190 | mov 5, %l3 | ||
191 | stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 5 | ||
192 | stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1: "translate" | ||
193 | stx %l5, [%sp + 2047 + 128 + 0x20] ! arg2: prom_mmu_ihandle_cache | ||
194 | srlx %l0, 22, %l3 | ||
195 | sllx %l3, 22, %l3 | ||
196 | stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: vaddr, our PC | ||
197 | stx %g0, [%sp + 2047 + 128 + 0x30] ! res1 | ||
198 | stx %g0, [%sp + 2047 + 128 + 0x38] ! res2 | ||
199 | stx %g0, [%sp + 2047 + 128 + 0x40] ! res3 | ||
200 | stx %g0, [%sp + 2047 + 128 + 0x48] ! res4 | ||
201 | stx %g0, [%sp + 2047 + 128 + 0x50] ! res5 | ||
202 | call %l7 | ||
203 | add %sp, (2047 + 128), %o0 ! argument array | ||
204 | |||
205 | ldx [%sp + 2047 + 128 + 0x40], %l1 ! translation mode | ||
206 | mov (1b - prom_boot_mapping_mode), %l4 | ||
207 | sub %l0, %l4, %l4 | ||
208 | stw %l1, [%l4] | ||
209 | mov (1b - prom_boot_mapping_phys_high), %l4 | ||
210 | sub %l0, %l4, %l4 | ||
211 | ldx [%sp + 2047 + 128 + 0x48], %l2 ! physaddr high | ||
212 | stx %l2, [%l4 + 0x0] | ||
213 | ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low | ||
214 | stx %l3, [%l4 + 0x8] | ||
215 | |||
216 | /* Leave service as-is, "call-method" */ | ||
217 | mov 7, %l3 | ||
218 | stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 7 | ||
219 | mov 1, %l3 | ||
220 | stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 | ||
221 | mov (1b - prom_map_name), %l3 | ||
222 | sub %l0, %l3, %l3 | ||
223 | stx %l3, [%sp + 2047 + 128 + 0x18] ! arg1: "map" | ||
224 | /* Leave arg2 as-is, prom_mmu_ihandle_cache */ | ||
225 | mov -1, %l3 | ||
226 | stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: mode (-1 default) | ||
227 | sethi %hi(8 * 1024 * 1024), %l3 | ||
228 | stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4: size (8MB) | ||
229 | sethi %hi(KERNBASE), %l3 | ||
230 | stx %l3, [%sp + 2047 + 128 + 0x38] ! arg5: vaddr (KERNBASE) | ||
231 | stx %g0, [%sp + 2047 + 128 + 0x40] ! arg6: empty | ||
232 | mov (1b - prom_boot_mapping_phys_low), %l3 | ||
233 | sub %l0, %l3, %l3 | ||
234 | ldx [%l3], %l3 | ||
235 | stx %l3, [%sp + 2047 + 128 + 0x48] ! arg7: phys addr | ||
236 | call %l7 | ||
237 | add %sp, (2047 + 128), %o0 ! argument array | ||
238 | |||
239 | add %sp, (192 + 128), %sp | ||
240 | |||
241 | sparc64_boot_after_remap: | ||
92 | BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot) | 242 | BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot) |
93 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot) | 243 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot) |
94 | ba,pt %xcc, spitfire_boot | 244 | ba,pt %xcc, spitfire_boot |
@@ -125,185 +275,7 @@ cheetah_generic_boot: | |||
125 | stxa %g0, [%g3] ASI_IMMU | 275 | stxa %g0, [%g3] ASI_IMMU |
126 | membar #Sync | 276 | membar #Sync |
127 | 277 | ||
128 | wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate | 278 | ba,a,pt %xcc, jump_to_sun4u_init |
129 | wr %g0, 0, %fprs | ||
130 | |||
131 | /* Just like for Spitfire, we probe itlb-2 for a mapping which | ||
132 | * matches our current %pc. We take the physical address in | ||
133 | * that mapping and use it to make our own. | ||
134 | */ | ||
135 | |||
136 | /* %g5 holds the tlb data */ | ||
137 | sethi %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5 | ||
138 | sllx %g5, 32, %g5 | ||
139 | or %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5 | ||
140 | |||
141 | /* Put PADDR tlb data mask into %g3. */ | ||
142 | sethi %uhi(_PAGE_PADDR), %g3 | ||
143 | or %g3, %ulo(_PAGE_PADDR), %g3 | ||
144 | sllx %g3, 32, %g3 | ||
145 | sethi %hi(_PAGE_PADDR), %g7 | ||
146 | or %g7, %lo(_PAGE_PADDR), %g7 | ||
147 | or %g3, %g7, %g3 | ||
148 | |||
149 | set 2 << 16, %l0 /* TLB entry walker. */ | ||
150 | set 0x1fff, %l2 /* Page mask. */ | ||
151 | rd %pc, %l3 | ||
152 | andn %l3, %l2, %g2 /* vaddr comparator */ | ||
153 | |||
154 | 1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1 | ||
155 | membar #Sync | ||
156 | andn %g1, %l2, %g1 | ||
157 | cmp %g1, %g2 | ||
158 | be,pn %xcc, cheetah_got_tlbentry | ||
159 | nop | ||
160 | and %l0, (127 << 3), %g1 | ||
161 | cmp %g1, (127 << 3) | ||
162 | blu,pt %xcc, 1b | ||
163 | add %l0, (1 << 3), %l0 | ||
164 | |||
165 | /* Search the small TLB. OBP never maps us like that but | ||
166 | * newer SILO can. | ||
167 | */ | ||
168 | clr %l0 | ||
169 | |||
170 | 1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1 | ||
171 | membar #Sync | ||
172 | andn %g1, %l2, %g1 | ||
173 | cmp %g1, %g2 | ||
174 | be,pn %xcc, cheetah_got_tlbentry | ||
175 | nop | ||
176 | cmp %l0, (15 << 3) | ||
177 | blu,pt %xcc, 1b | ||
178 | add %l0, (1 << 3), %l0 | ||
179 | |||
180 | /* BUG() if we get here... */ | ||
181 | ta 0x5 | ||
182 | |||
183 | cheetah_got_tlbentry: | ||
184 | ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g0 | ||
185 | ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1 | ||
186 | membar #Sync | ||
187 | and %g1, %g3, %g1 | ||
188 | set 0x5fff, %l0 | ||
189 | andn %g1, %l0, %g1 | ||
190 | or %g5, %g1, %g5 | ||
191 | |||
192 | /* Clear out any KERNBASE area entries. */ | ||
193 | set 2 << 16, %l0 | ||
194 | sethi %hi(KERNBASE), %g3 | ||
195 | sethi %hi(KERNBASE<<1), %g7 | ||
196 | mov TLB_TAG_ACCESS, %l7 | ||
197 | |||
198 | /* First, check ITLB */ | ||
199 | 1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1 | ||
200 | membar #Sync | ||
201 | andn %g1, %l2, %g1 | ||
202 | cmp %g1, %g3 | ||
203 | blu,pn %xcc, 2f | ||
204 | cmp %g1, %g7 | ||
205 | bgeu,pn %xcc, 2f | ||
206 | nop | ||
207 | stxa %g0, [%l7] ASI_IMMU | ||
208 | membar #Sync | ||
209 | stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS | ||
210 | membar #Sync | ||
211 | |||
212 | 2: and %l0, (127 << 3), %g1 | ||
213 | cmp %g1, (127 << 3) | ||
214 | blu,pt %xcc, 1b | ||
215 | add %l0, (1 << 3), %l0 | ||
216 | |||
217 | /* Next, check DTLB */ | ||
218 | set 2 << 16, %l0 | ||
219 | 1: ldxa [%l0] ASI_DTLB_TAG_READ, %g1 | ||
220 | membar #Sync | ||
221 | andn %g1, %l2, %g1 | ||
222 | cmp %g1, %g3 | ||
223 | blu,pn %xcc, 2f | ||
224 | cmp %g1, %g7 | ||
225 | bgeu,pn %xcc, 2f | ||
226 | nop | ||
227 | stxa %g0, [%l7] ASI_DMMU | ||
228 | membar #Sync | ||
229 | stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS | ||
230 | membar #Sync | ||
231 | |||
232 | 2: and %l0, (511 << 3), %g1 | ||
233 | cmp %g1, (511 << 3) | ||
234 | blu,pt %xcc, 1b | ||
235 | add %l0, (1 << 3), %l0 | ||
236 | |||
237 | /* On Cheetah+, have to check second DTLB. */ | ||
238 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,l0,2f) | ||
239 | ba,pt %xcc, 9f | ||
240 | nop | ||
241 | |||
242 | 2: set 3 << 16, %l0 | ||
243 | 1: ldxa [%l0] ASI_DTLB_TAG_READ, %g1 | ||
244 | membar #Sync | ||
245 | andn %g1, %l2, %g1 | ||
246 | cmp %g1, %g3 | ||
247 | blu,pn %xcc, 2f | ||
248 | cmp %g1, %g7 | ||
249 | bgeu,pn %xcc, 2f | ||
250 | nop | ||
251 | stxa %g0, [%l7] ASI_DMMU | ||
252 | membar #Sync | ||
253 | stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS | ||
254 | membar #Sync | ||
255 | |||
256 | 2: and %l0, (511 << 3), %g1 | ||
257 | cmp %g1, (511 << 3) | ||
258 | blu,pt %xcc, 1b | ||
259 | add %l0, (1 << 3), %l0 | ||
260 | |||
261 | 9: | ||
262 | |||
263 | /* Now lock the TTE we created into ITLB-0 and DTLB-0, | ||
264 | * entry 15 (and maybe 14 too). | ||
265 | */ | ||
266 | sethi %hi(KERNBASE), %g3 | ||
267 | set (0 << 16) | (15 << 3), %g7 | ||
268 | stxa %g3, [%l7] ASI_DMMU | ||
269 | membar #Sync | ||
270 | stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS | ||
271 | membar #Sync | ||
272 | stxa %g3, [%l7] ASI_IMMU | ||
273 | membar #Sync | ||
274 | stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS | ||
275 | membar #Sync | ||
276 | flush %g3 | ||
277 | membar #Sync | ||
278 | sethi %hi(_end), %g3 /* Check for bigkernel case */ | ||
279 | or %g3, %lo(_end), %g3 | ||
280 | srl %g3, 23, %g3 /* Check if _end > 8M */ | ||
281 | brz,pt %g3, 1f | ||
282 | sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */ | ||
283 | sethi %hi(0x400000), %g3 | ||
284 | or %g3, %lo(0x400000), %g3 | ||
285 | add %g5, %g3, %g5 /* New tte data */ | ||
286 | andn %g5, (_PAGE_G), %g5 | ||
287 | sethi %hi(KERNBASE+0x400000), %g3 | ||
288 | or %g3, %lo(KERNBASE+0x400000), %g3 | ||
289 | set (0 << 16) | (14 << 3), %g7 | ||
290 | stxa %g3, [%l7] ASI_DMMU | ||
291 | membar #Sync | ||
292 | stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS | ||
293 | membar #Sync | ||
294 | stxa %g3, [%l7] ASI_IMMU | ||
295 | membar #Sync | ||
296 | stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS | ||
297 | membar #Sync | ||
298 | flush %g3 | ||
299 | membar #Sync | ||
300 | sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */ | ||
301 | ba,pt %xcc, 1f | ||
302 | nop | ||
303 | |||
304 | 1: set sun4u_init, %g2 | ||
305 | jmpl %g2 + %g0, %g0 | ||
306 | nop | ||
307 | 279 | ||
308 | spitfire_boot: | 280 | spitfire_boot: |
309 | /* Typically PROM has already enabled both MMU's and both on-chip | 281 | /* Typically PROM has already enabled both MMU's and both on-chip |
@@ -313,6 +285,7 @@ spitfire_boot: | |||
313 | stxa %g1, [%g0] ASI_LSU_CONTROL | 285 | stxa %g1, [%g0] ASI_LSU_CONTROL |
314 | membar #Sync | 286 | membar #Sync |
315 | 287 | ||
288 | jump_to_sun4u_init: | ||
316 | /* | 289 | /* |
317 | * Make sure we are in privileged mode, have address masking, | 290 | * Make sure we are in privileged mode, have address masking, |
318 | * using the ordinary globals and have enabled floating | 291 | * using the ordinary globals and have enabled floating |
@@ -324,151 +297,6 @@ spitfire_boot: | |||
324 | wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate | 297 | wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate |
325 | wr %g0, 0, %fprs | 298 | wr %g0, 0, %fprs |
326 | 299 | ||
327 | spitfire_create_mappings: | ||
328 | /* %g5 holds the tlb data */ | ||
329 | sethi %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5 | ||
330 | sllx %g5, 32, %g5 | ||
331 | or %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5 | ||
332 | |||
333 | /* Base of physical memory cannot reliably be assumed to be | ||
334 | * at 0x0! Figure out where it happens to be. -DaveM | ||
335 | */ | ||
336 | |||
337 | /* Put PADDR tlb data mask into %g3. */ | ||
338 | sethi %uhi(_PAGE_PADDR_SF), %g3 | ||
339 | or %g3, %ulo(_PAGE_PADDR_SF), %g3 | ||
340 | sllx %g3, 32, %g3 | ||
341 | sethi %hi(_PAGE_PADDR_SF), %g7 | ||
342 | or %g7, %lo(_PAGE_PADDR_SF), %g7 | ||
343 | or %g3, %g7, %g3 | ||
344 | |||
345 | /* Walk through entire ITLB, looking for entry which maps | ||
346 | * our %pc currently, stick PADDR from there into %g5 tlb data. | ||
347 | */ | ||
348 | clr %l0 /* TLB entry walker. */ | ||
349 | set 0x1fff, %l2 /* Page mask. */ | ||
350 | rd %pc, %l3 | ||
351 | andn %l3, %l2, %g2 /* vaddr comparator */ | ||
352 | 1: | ||
353 | /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */ | ||
354 | ldxa [%l0] ASI_ITLB_TAG_READ, %g1 | ||
355 | nop | ||
356 | nop | ||
357 | nop | ||
358 | andn %g1, %l2, %g1 /* Get vaddr */ | ||
359 | cmp %g1, %g2 | ||
360 | be,a,pn %xcc, spitfire_got_tlbentry | ||
361 | ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1 | ||
362 | cmp %l0, (63 << 3) | ||
363 | blu,pt %xcc, 1b | ||
364 | add %l0, (1 << 3), %l0 | ||
365 | |||
366 | /* BUG() if we get here... */ | ||
367 | ta 0x5 | ||
368 | |||
369 | spitfire_got_tlbentry: | ||
370 | /* Nops here again, perhaps Cheetah/Blackbird are better behaved... */ | ||
371 | nop | ||
372 | nop | ||
373 | nop | ||
374 | and %g1, %g3, %g1 /* Mask to just get paddr bits. */ | ||
375 | set 0x5fff, %l3 /* Mask offset to get phys base. */ | ||
376 | andn %g1, %l3, %g1 | ||
377 | |||
378 | /* NOTE: We hold on to %g1 paddr base as we need it below to lock | ||
379 | * NOTE: the PROM cif code into the TLB. | ||
380 | */ | ||
381 | |||
382 | or %g5, %g1, %g5 /* Or it into TAG being built. */ | ||
383 | |||
384 | clr %l0 /* TLB entry walker. */ | ||
385 | sethi %hi(KERNBASE), %g3 /* 4M lower limit */ | ||
386 | sethi %hi(KERNBASE<<1), %g7 /* 8M upper limit */ | ||
387 | mov TLB_TAG_ACCESS, %l7 | ||
388 | 1: | ||
389 | /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */ | ||
390 | ldxa [%l0] ASI_ITLB_TAG_READ, %g1 | ||
391 | nop | ||
392 | nop | ||
393 | nop | ||
394 | andn %g1, %l2, %g1 /* Get vaddr */ | ||
395 | cmp %g1, %g3 | ||
396 | blu,pn %xcc, 2f | ||
397 | cmp %g1, %g7 | ||
398 | bgeu,pn %xcc, 2f | ||
399 | nop | ||
400 | stxa %g0, [%l7] ASI_IMMU | ||
401 | stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS | ||
402 | membar #Sync | ||
403 | 2: | ||
404 | cmp %l0, (63 << 3) | ||
405 | blu,pt %xcc, 1b | ||
406 | add %l0, (1 << 3), %l0 | ||
407 | |||
408 | nop; nop; nop | ||
409 | |||
410 | clr %l0 /* TLB entry walker. */ | ||
411 | 1: | ||
412 | /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */ | ||
413 | ldxa [%l0] ASI_DTLB_TAG_READ, %g1 | ||
414 | nop | ||
415 | nop | ||
416 | nop | ||
417 | andn %g1, %l2, %g1 /* Get vaddr */ | ||
418 | cmp %g1, %g3 | ||
419 | blu,pn %xcc, 2f | ||
420 | cmp %g1, %g7 | ||
421 | bgeu,pn %xcc, 2f | ||
422 | nop | ||
423 | stxa %g0, [%l7] ASI_DMMU | ||
424 | stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS | ||
425 | membar #Sync | ||
426 | 2: | ||
427 | cmp %l0, (63 << 3) | ||
428 | blu,pt %xcc, 1b | ||
429 | add %l0, (1 << 3), %l0 | ||
430 | |||
431 | nop; nop; nop | ||
432 | |||
433 | |||
434 | /* PROM never puts any TLB entries into the MMU with the lock bit | ||
435 | * set. So we gladly use tlb entry 63 for KERNBASE. And maybe 62 too. | ||
436 | */ | ||
437 | |||
438 | sethi %hi(KERNBASE), %g3 | ||
439 | mov (63 << 3), %g7 | ||
440 | stxa %g3, [%l7] ASI_DMMU /* KERNBASE into TLB TAG */ | ||
441 | stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS /* TTE into TLB DATA */ | ||
442 | membar #Sync | ||
443 | stxa %g3, [%l7] ASI_IMMU /* KERNBASE into TLB TAG */ | ||
444 | stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS /* TTE into TLB DATA */ | ||
445 | membar #Sync | ||
446 | flush %g3 | ||
447 | membar #Sync | ||
448 | sethi %hi(_end), %g3 /* Check for bigkernel case */ | ||
449 | or %g3, %lo(_end), %g3 | ||
450 | srl %g3, 23, %g3 /* Check if _end > 8M */ | ||
451 | brz,pt %g3, 2f | ||
452 | sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */ | ||
453 | sethi %hi(0x400000), %g3 | ||
454 | or %g3, %lo(0x400000), %g3 | ||
455 | add %g5, %g3, %g5 /* New tte data */ | ||
456 | andn %g5, (_PAGE_G), %g5 | ||
457 | sethi %hi(KERNBASE+0x400000), %g3 | ||
458 | or %g3, %lo(KERNBASE+0x400000), %g3 | ||
459 | mov (62 << 3), %g7 | ||
460 | stxa %g3, [%l7] ASI_DMMU | ||
461 | stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS | ||
462 | membar #Sync | ||
463 | stxa %g3, [%l7] ASI_IMMU | ||
464 | stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS | ||
465 | membar #Sync | ||
466 | flush %g3 | ||
467 | membar #Sync | ||
468 | sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */ | ||
469 | 2: ba,pt %xcc, 1f | ||
470 | nop | ||
471 | 1: | ||
472 | set sun4u_init, %g2 | 300 | set sun4u_init, %g2 |
473 | jmpl %g2 + %g0, %g0 | 301 | jmpl %g2 + %g0, %g0 |
474 | nop | 302 | nop |
@@ -483,38 +311,12 @@ sun4u_init: | |||
483 | stxa %g0, [%g7] ASI_DMMU | 311 | stxa %g0, [%g7] ASI_DMMU |
484 | membar #Sync | 312 | membar #Sync |
485 | 313 | ||
486 | /* We are now safely (we hope) in Nucleus context (0), rewrite | ||
487 | * the KERNBASE TTE's so they no longer have the global bit set. | ||
488 | * Don't forget to setup TAG_ACCESS first 8-) | ||
489 | */ | ||
490 | mov TLB_TAG_ACCESS, %g2 | ||
491 | stxa %g3, [%g2] ASI_IMMU | ||
492 | stxa %g3, [%g2] ASI_DMMU | ||
493 | membar #Sync | ||
494 | |||
495 | BRANCH_IF_ANY_CHEETAH(g1,g7,cheetah_tlb_fixup) | 314 | BRANCH_IF_ANY_CHEETAH(g1,g7,cheetah_tlb_fixup) |
496 | 315 | ||
497 | ba,pt %xcc, spitfire_tlb_fixup | 316 | ba,pt %xcc, spitfire_tlb_fixup |
498 | nop | 317 | nop |
499 | 318 | ||
500 | cheetah_tlb_fixup: | 319 | cheetah_tlb_fixup: |
501 | set (0 << 16) | (15 << 3), %g7 | ||
502 | ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g0 | ||
503 | ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1 | ||
504 | andn %g1, (_PAGE_G), %g1 | ||
505 | stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS | ||
506 | membar #Sync | ||
507 | |||
508 | ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g0 | ||
509 | ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1 | ||
510 | andn %g1, (_PAGE_G), %g1 | ||
511 | stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS | ||
512 | membar #Sync | ||
513 | |||
514 | /* Kill instruction prefetch queues. */ | ||
515 | flush %g3 | ||
516 | membar #Sync | ||
517 | |||
518 | mov 2, %g2 /* Set TLB type to cheetah+. */ | 320 | mov 2, %g2 /* Set TLB type to cheetah+. */ |
519 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f) | 321 | BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f) |
520 | 322 | ||
@@ -551,21 +353,6 @@ cheetah_tlb_fixup: | |||
551 | nop | 353 | nop |
552 | 354 | ||
553 | spitfire_tlb_fixup: | 355 | spitfire_tlb_fixup: |
554 | mov (63 << 3), %g7 | ||
555 | ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1 | ||
556 | andn %g1, (_PAGE_G), %g1 | ||
557 | stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS | ||
558 | membar #Sync | ||
559 | |||
560 | ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1 | ||
561 | andn %g1, (_PAGE_G), %g1 | ||
562 | stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS | ||
563 | membar #Sync | ||
564 | |||
565 | /* Kill instruction prefetch queues. */ | ||
566 | flush %g3 | ||
567 | membar #Sync | ||
568 | |||
569 | /* Set TLB type to spitfire. */ | 356 | /* Set TLB type to spitfire. */ |
570 | mov 0, %g2 | 357 | mov 0, %g2 |
571 | sethi %hi(tlb_type), %g1 | 358 | sethi %hi(tlb_type), %g1 |
@@ -578,24 +365,6 @@ tlb_fixup_done: | |||
578 | mov %sp, %l6 | 365 | mov %sp, %l6 |
579 | mov %o4, %l7 | 366 | mov %o4, %l7 |
580 | 367 | ||
581 | #if 0 /* We don't do it like this anymore, but for historical hack value | ||
582 | * I leave this snippet here to show how crazy we can be sometimes. 8-) | ||
583 | */ | ||
584 | |||
585 | /* Setup "Linux Current Register", thanks Sun 8-) */ | ||
586 | wr %g0, 0x1, %pcr | ||
587 | |||
588 | /* Blackbird errata workaround. See commentary in | ||
589 | * smp.c:smp_percpu_timer_interrupt() for more | ||
590 | * information. | ||
591 | */ | ||
592 | ba,pt %xcc, 99f | ||
593 | nop | ||
594 | .align 64 | ||
595 | 99: wr %g6, %g0, %pic | ||
596 | rd %pic, %g0 | ||
597 | #endif | ||
598 | |||
599 | wr %g0, ASI_P, %asi | 368 | wr %g0, ASI_P, %asi |
600 | mov 1, %g1 | 369 | mov 1, %g1 |
601 | sllx %g1, THREAD_SHIFT, %g1 | 370 | sllx %g1, THREAD_SHIFT, %g1 |
@@ -756,12 +525,7 @@ bootup_user_stack_end: | |||
756 | 525 | ||
757 | #include "ttable.S" | 526 | #include "ttable.S" |
758 | #include "systbls.S" | 527 | #include "systbls.S" |
759 | 528 | #include "ktlb.S" | |
760 | .align 1024 | ||
761 | .globl swapper_pg_dir | ||
762 | swapper_pg_dir: | ||
763 | .word 0 | ||
764 | |||
765 | #include "etrap.S" | 529 | #include "etrap.S" |
766 | #include "rtrap.S" | 530 | #include "rtrap.S" |
767 | #include "winfixup.S" | 531 | #include "winfixup.S" |
diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S new file mode 100644 index 000000000000..7796b37f478c --- /dev/null +++ b/arch/sparc64/kernel/ktlb.S | |||
@@ -0,0 +1,198 @@ | |||
1 | /* arch/sparc64/kernel/ktlb.S: Kernel mapping TLB miss handling. | ||
2 | * | ||
3 | * Copyright (C) 1995, 1997, 2005 David S. Miller <davem@davemloft.net> | ||
4 | * Copyright (C) 1996 Eddie C. Dost (ecd@brainaid.de) | ||
5 | * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) | ||
6 | * Copyright (C) 1996,98,99 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
7 | */ | ||
8 | |||
9 | #include <linux/config.h> | ||
10 | #include <asm/head.h> | ||
11 | #include <asm/asi.h> | ||
12 | #include <asm/page.h> | ||
13 | #include <asm/pgtable.h> | ||
14 | |||
15 | .text | ||
16 | .align 32 | ||
17 | |||
18 | /* | ||
19 | * On a second level vpte miss, check whether the original fault is to the OBP | ||
20 | * range (note that this is only possible for instruction miss, data misses to | ||
21 | * obp range do not use vpte). If so, go back directly to the faulting address. | ||
22 | * This is because we want to read the tpc, otherwise we have no way of knowing | ||
23 | * the 8k aligned faulting address if we are using >8k kernel pagesize. This | ||
24 | * also ensures no vpte range addresses are dropped into tlb while obp is | ||
25 | * executing (see inherit_locked_prom_mappings() rant). | ||
26 | */ | ||
27 | sparc64_vpte_nucleus: | ||
28 | /* Note that kvmap below has verified that the address is | ||
29 | * in the range MODULES_VADDR --> VMALLOC_END already. So | ||
30 | * here we need only check if it is an OBP address or not. | ||
31 | */ | ||
32 | sethi %hi(LOW_OBP_ADDRESS), %g5 | ||
33 | cmp %g4, %g5 | ||
34 | blu,pn %xcc, kern_vpte | ||
35 | mov 0x1, %g5 | ||
36 | sllx %g5, 32, %g5 | ||
37 | cmp %g4, %g5 | ||
38 | blu,pn %xcc, vpte_insn_obp | ||
39 | nop | ||
40 | |||
41 | /* These two instructions are patched by paginig_init(). */ | ||
42 | kern_vpte: | ||
43 | sethi %hi(swapper_pgd_zero), %g5 | ||
44 | lduw [%g5 + %lo(swapper_pgd_zero)], %g5 | ||
45 | |||
46 | /* With kernel PGD in %g5, branch back into dtlb_backend. */ | ||
47 | ba,pt %xcc, sparc64_kpte_continue | ||
48 | andn %g1, 0x3, %g1 /* Finish PMD offset adjustment. */ | ||
49 | |||
50 | vpte_noent: | ||
51 | /* Restore previous TAG_ACCESS, %g5 is zero, and we will | ||
52 | * skip over the trap instruction so that the top level | ||
53 | * TLB miss handler will thing this %g5 value is just an | ||
54 | * invalid PTE, thus branching to full fault processing. | ||
55 | */ | ||
56 | mov TLB_SFSR, %g1 | ||
57 | stxa %g4, [%g1 + %g1] ASI_DMMU | ||
58 | done | ||
59 | |||
60 | vpte_insn_obp: | ||
61 | sethi %hi(prom_pmd_phys), %g5 | ||
62 | ldx [%g5 + %lo(prom_pmd_phys)], %g5 | ||
63 | |||
64 | /* Behave as if we are at TL0. */ | ||
65 | wrpr %g0, 1, %tl | ||
66 | rdpr %tpc, %g4 /* Find original faulting iaddr */ | ||
67 | srlx %g4, 13, %g4 /* Throw out context bits */ | ||
68 | sllx %g4, 13, %g4 /* g4 has vpn + ctx0 now */ | ||
69 | |||
70 | /* Restore previous TAG_ACCESS. */ | ||
71 | mov TLB_SFSR, %g1 | ||
72 | stxa %g4, [%g1 + %g1] ASI_IMMU | ||
73 | |||
74 | /* Get PMD offset. */ | ||
75 | srlx %g4, 23, %g6 | ||
76 | and %g6, 0x7ff, %g6 | ||
77 | sllx %g6, 2, %g6 | ||
78 | |||
79 | /* Load PMD, is it valid? */ | ||
80 | lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 | ||
81 | brz,pn %g5, longpath | ||
82 | sllx %g5, 11, %g5 | ||
83 | |||
84 | /* Get PTE offset. */ | ||
85 | srlx %g4, 13, %g6 | ||
86 | and %g6, 0x3ff, %g6 | ||
87 | sllx %g6, 3, %g6 | ||
88 | |||
89 | /* Load PTE. */ | ||
90 | ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 | ||
91 | brgez,pn %g5, longpath | ||
92 | nop | ||
93 | |||
94 | /* TLB load and return from trap. */ | ||
95 | stxa %g5, [%g0] ASI_ITLB_DATA_IN | ||
96 | retry | ||
97 | |||
98 | kvmap_do_obp: | ||
99 | sethi %hi(prom_pmd_phys), %g5 | ||
100 | ldx [%g5 + %lo(prom_pmd_phys)], %g5 | ||
101 | |||
102 | /* Get PMD offset. */ | ||
103 | srlx %g4, 23, %g6 | ||
104 | and %g6, 0x7ff, %g6 | ||
105 | sllx %g6, 2, %g6 | ||
106 | |||
107 | /* Load PMD, is it valid? */ | ||
108 | lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 | ||
109 | brz,pn %g5, longpath | ||
110 | sllx %g5, 11, %g5 | ||
111 | |||
112 | /* Get PTE offset. */ | ||
113 | srlx %g4, 13, %g6 | ||
114 | and %g6, 0x3ff, %g6 | ||
115 | sllx %g6, 3, %g6 | ||
116 | |||
117 | /* Load PTE. */ | ||
118 | ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 | ||
119 | brgez,pn %g5, longpath | ||
120 | nop | ||
121 | |||
122 | /* TLB load and return from trap. */ | ||
123 | stxa %g5, [%g0] ASI_DTLB_DATA_IN | ||
124 | retry | ||
125 | |||
126 | /* | ||
127 | * On a first level data miss, check whether this is to the OBP range (note | ||
128 | * that such accesses can be made by prom, as well as by kernel using | ||
129 | * prom_getproperty on "address"), and if so, do not use vpte access ... | ||
130 | * rather, use information saved during inherit_prom_mappings() using 8k | ||
131 | * pagesize. | ||
132 | */ | ||
133 | .align 32 | ||
134 | kvmap: | ||
135 | brgez,pn %g4, kvmap_nonlinear | ||
136 | nop | ||
137 | |||
138 | #ifdef CONFIG_DEBUG_PAGEALLOC | ||
139 | .globl kvmap_linear_patch | ||
140 | kvmap_linear_patch: | ||
141 | #endif | ||
142 | ba,pt %xcc, kvmap_load | ||
143 | xor %g2, %g4, %g5 | ||
144 | |||
145 | #ifdef CONFIG_DEBUG_PAGEALLOC | ||
146 | sethi %hi(swapper_pg_dir), %g5 | ||
147 | or %g5, %lo(swapper_pg_dir), %g5 | ||
148 | sllx %g4, 64 - (PGDIR_SHIFT + PGDIR_BITS), %g6 | ||
149 | srlx %g6, 64 - PAGE_SHIFT, %g6 | ||
150 | andn %g6, 0x3, %g6 | ||
151 | lduw [%g5 + %g6], %g5 | ||
152 | brz,pn %g5, longpath | ||
153 | sllx %g4, 64 - (PMD_SHIFT + PMD_BITS), %g6 | ||
154 | srlx %g6, 64 - PAGE_SHIFT, %g6 | ||
155 | sllx %g5, 11, %g5 | ||
156 | andn %g6, 0x3, %g6 | ||
157 | lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 | ||
158 | brz,pn %g5, longpath | ||
159 | sllx %g4, 64 - PMD_SHIFT, %g6 | ||
160 | srlx %g6, 64 - PAGE_SHIFT, %g6 | ||
161 | sllx %g5, 11, %g5 | ||
162 | andn %g6, 0x7, %g6 | ||
163 | ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 | ||
164 | brz,pn %g5, longpath | ||
165 | nop | ||
166 | ba,a,pt %xcc, kvmap_load | ||
167 | #endif | ||
168 | |||
169 | kvmap_nonlinear: | ||
170 | sethi %hi(MODULES_VADDR), %g5 | ||
171 | cmp %g4, %g5 | ||
172 | blu,pn %xcc, longpath | ||
173 | mov (VMALLOC_END >> 24), %g5 | ||
174 | sllx %g5, 24, %g5 | ||
175 | cmp %g4, %g5 | ||
176 | bgeu,pn %xcc, longpath | ||
177 | nop | ||
178 | |||
179 | kvmap_check_obp: | ||
180 | sethi %hi(LOW_OBP_ADDRESS), %g5 | ||
181 | cmp %g4, %g5 | ||
182 | blu,pn %xcc, kvmap_vmalloc_addr | ||
183 | mov 0x1, %g5 | ||
184 | sllx %g5, 32, %g5 | ||
185 | cmp %g4, %g5 | ||
186 | blu,pn %xcc, kvmap_do_obp | ||
187 | nop | ||
188 | |||
189 | kvmap_vmalloc_addr: | ||
190 | /* If we get here, a vmalloc addr was accessed, load kernel VPTE. */ | ||
191 | ldxa [%g3 + %g6] ASI_N, %g5 | ||
192 | brgez,pn %g5, longpath | ||
193 | nop | ||
194 | |||
195 | kvmap_load: | ||
196 | /* PTE is valid, load into TLB and return from trap. */ | ||
197 | stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB | ||
198 | retry | ||
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 331382e1a75d..cae5b61fe2f0 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c | |||
@@ -330,7 +330,7 @@ static int schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino) | |||
330 | static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) | 330 | static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) |
331 | { | 331 | { |
332 | unsigned long sync_reg = (unsigned long) _arg2; | 332 | unsigned long sync_reg = (unsigned long) _arg2; |
333 | u64 mask = 1 << (__irq_ino(__irq(bucket)) & IMAP_INO); | 333 | u64 mask = 1UL << (__irq_ino(__irq(bucket)) & IMAP_INO); |
334 | u64 val; | 334 | u64 val; |
335 | int limit; | 335 | int limit; |
336 | 336 | ||
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index ddbed3341a23..8e8baf2354df 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -496,7 +496,6 @@ extern void paging_init(void); | |||
496 | 496 | ||
497 | void __init setup_arch(char **cmdline_p) | 497 | void __init setup_arch(char **cmdline_p) |
498 | { | 498 | { |
499 | unsigned long highest_paddr; | ||
500 | int i; | 499 | int i; |
501 | 500 | ||
502 | /* Initialize PROM console and command line. */ | 501 | /* Initialize PROM console and command line. */ |
@@ -519,11 +518,7 @@ void __init setup_arch(char **cmdline_p) | |||
519 | idprom_init(); | 518 | idprom_init(); |
520 | (void) prom_probe_memory(); | 519 | (void) prom_probe_memory(); |
521 | 520 | ||
522 | /* In paging_init() we tip off this value to see if we need | ||
523 | * to change init_mm.pgd to point to the real alias mapping. | ||
524 | */ | ||
525 | phys_base = 0xffffffffffffffffUL; | 521 | phys_base = 0xffffffffffffffffUL; |
526 | highest_paddr = 0UL; | ||
527 | for (i = 0; sp_banks[i].num_bytes != 0; i++) { | 522 | for (i = 0; sp_banks[i].num_bytes != 0; i++) { |
528 | unsigned long top; | 523 | unsigned long top; |
529 | 524 | ||
@@ -531,25 +526,10 @@ void __init setup_arch(char **cmdline_p) | |||
531 | phys_base = sp_banks[i].base_addr; | 526 | phys_base = sp_banks[i].base_addr; |
532 | top = sp_banks[i].base_addr + | 527 | top = sp_banks[i].base_addr + |
533 | sp_banks[i].num_bytes; | 528 | sp_banks[i].num_bytes; |
534 | if (highest_paddr < top) | ||
535 | highest_paddr = top; | ||
536 | } | 529 | } |
537 | pfn_base = phys_base >> PAGE_SHIFT; | 530 | pfn_base = phys_base >> PAGE_SHIFT; |
538 | 531 | ||
539 | switch (tlb_type) { | 532 | kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL; |
540 | default: | ||
541 | case spitfire: | ||
542 | kern_base = spitfire_get_itlb_data(sparc64_highest_locked_tlbent()); | ||
543 | kern_base &= _PAGE_PADDR_SF; | ||
544 | break; | ||
545 | |||
546 | case cheetah: | ||
547 | case cheetah_plus: | ||
548 | kern_base = cheetah_get_litlb_data(sparc64_highest_locked_tlbent()); | ||
549 | kern_base &= _PAGE_PADDR; | ||
550 | break; | ||
551 | }; | ||
552 | |||
553 | kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; | 533 | kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; |
554 | 534 | ||
555 | if (!root_flags) | 535 | if (!root_flags) |
@@ -625,6 +605,9 @@ extern void smp_info(struct seq_file *); | |||
625 | extern void smp_bogo(struct seq_file *); | 605 | extern void smp_bogo(struct seq_file *); |
626 | extern void mmu_info(struct seq_file *); | 606 | extern void mmu_info(struct seq_file *); |
627 | 607 | ||
608 | unsigned int dcache_parity_tl1_occurred; | ||
609 | unsigned int icache_parity_tl1_occurred; | ||
610 | |||
628 | static int show_cpuinfo(struct seq_file *m, void *__unused) | 611 | static int show_cpuinfo(struct seq_file *m, void *__unused) |
629 | { | 612 | { |
630 | seq_printf(m, | 613 | seq_printf(m, |
@@ -635,6 +618,8 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) | |||
635 | "type\t\t: sun4u\n" | 618 | "type\t\t: sun4u\n" |
636 | "ncpus probed\t: %ld\n" | 619 | "ncpus probed\t: %ld\n" |
637 | "ncpus active\t: %ld\n" | 620 | "ncpus active\t: %ld\n" |
621 | "D$ parity tl1\t: %u\n" | ||
622 | "I$ parity tl1\t: %u\n" | ||
638 | #ifndef CONFIG_SMP | 623 | #ifndef CONFIG_SMP |
639 | "Cpu0Bogo\t: %lu.%02lu\n" | 624 | "Cpu0Bogo\t: %lu.%02lu\n" |
640 | "Cpu0ClkTck\t: %016lx\n" | 625 | "Cpu0ClkTck\t: %016lx\n" |
@@ -647,7 +632,9 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) | |||
647 | (prom_prev >> 8) & 0xff, | 632 | (prom_prev >> 8) & 0xff, |
648 | prom_prev & 0xff, | 633 | prom_prev & 0xff, |
649 | (long)num_possible_cpus(), | 634 | (long)num_possible_cpus(), |
650 | (long)num_online_cpus() | 635 | (long)num_online_cpus(), |
636 | dcache_parity_tl1_occurred, | ||
637 | icache_parity_tl1_occurred | ||
651 | #ifndef CONFIG_SMP | 638 | #ifndef CONFIG_SMP |
652 | , cpu_data(0).udelay_val/(500000/HZ), | 639 | , cpu_data(0).udelay_val/(500000/HZ), |
653 | (cpu_data(0).udelay_val/(5000/HZ)) % 100, | 640 | (cpu_data(0).udelay_val/(5000/HZ)) % 100, |
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index b4fc6a5462b2..590df5a16f5a 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -93,6 +93,27 @@ void __init smp_store_cpu_info(int id) | |||
93 | cpu_data(id).pte_cache[1] = NULL; | 93 | cpu_data(id).pte_cache[1] = NULL; |
94 | cpu_data(id).pgd_cache = NULL; | 94 | cpu_data(id).pgd_cache = NULL; |
95 | cpu_data(id).idle_volume = 1; | 95 | cpu_data(id).idle_volume = 1; |
96 | |||
97 | cpu_data(id).dcache_size = prom_getintdefault(cpu_node, "dcache-size", | ||
98 | 16 * 1024); | ||
99 | cpu_data(id).dcache_line_size = | ||
100 | prom_getintdefault(cpu_node, "dcache-line-size", 32); | ||
101 | cpu_data(id).icache_size = prom_getintdefault(cpu_node, "icache-size", | ||
102 | 16 * 1024); | ||
103 | cpu_data(id).icache_line_size = | ||
104 | prom_getintdefault(cpu_node, "icache-line-size", 32); | ||
105 | cpu_data(id).ecache_size = prom_getintdefault(cpu_node, "ecache-size", | ||
106 | 4 * 1024 * 1024); | ||
107 | cpu_data(id).ecache_line_size = | ||
108 | prom_getintdefault(cpu_node, "ecache-line-size", 64); | ||
109 | printk("CPU[%d]: Caches " | ||
110 | "D[sz(%d):line_sz(%d)] " | ||
111 | "I[sz(%d):line_sz(%d)] " | ||
112 | "E[sz(%d):line_sz(%d)]\n", | ||
113 | id, | ||
114 | cpu_data(id).dcache_size, cpu_data(id).dcache_line_size, | ||
115 | cpu_data(id).icache_size, cpu_data(id).icache_line_size, | ||
116 | cpu_data(id).ecache_size, cpu_data(id).ecache_line_size); | ||
96 | } | 117 | } |
97 | 118 | ||
98 | static void smp_setup_percpu_timer(void); | 119 | static void smp_setup_percpu_timer(void); |
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S index 3a145fc39cf2..89f2fcfcd662 100644 --- a/arch/sparc64/kernel/trampoline.S +++ b/arch/sparc64/kernel/trampoline.S | |||
@@ -119,8 +119,8 @@ startup_continue: | |||
119 | sethi %hi(itlb_load), %g2 | 119 | sethi %hi(itlb_load), %g2 |
120 | or %g2, %lo(itlb_load), %g2 | 120 | or %g2, %lo(itlb_load), %g2 |
121 | stx %g2, [%sp + 2047 + 128 + 0x18] | 121 | stx %g2, [%sp + 2047 + 128 + 0x18] |
122 | sethi %hi(mmu_ihandle_cache), %g2 | 122 | sethi %hi(prom_mmu_ihandle_cache), %g2 |
123 | lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 | 123 | lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2 |
124 | stx %g2, [%sp + 2047 + 128 + 0x20] | 124 | stx %g2, [%sp + 2047 + 128 + 0x20] |
125 | sethi %hi(KERNBASE), %g2 | 125 | sethi %hi(KERNBASE), %g2 |
126 | stx %g2, [%sp + 2047 + 128 + 0x28] | 126 | stx %g2, [%sp + 2047 + 128 + 0x28] |
@@ -156,8 +156,8 @@ startup_continue: | |||
156 | sethi %hi(itlb_load), %g2 | 156 | sethi %hi(itlb_load), %g2 |
157 | or %g2, %lo(itlb_load), %g2 | 157 | or %g2, %lo(itlb_load), %g2 |
158 | stx %g2, [%sp + 2047 + 128 + 0x18] | 158 | stx %g2, [%sp + 2047 + 128 + 0x18] |
159 | sethi %hi(mmu_ihandle_cache), %g2 | 159 | sethi %hi(prom_mmu_ihandle_cache), %g2 |
160 | lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 | 160 | lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2 |
161 | stx %g2, [%sp + 2047 + 128 + 0x20] | 161 | stx %g2, [%sp + 2047 + 128 + 0x20] |
162 | sethi %hi(KERNBASE + 0x400000), %g2 | 162 | sethi %hi(KERNBASE + 0x400000), %g2 |
163 | stx %g2, [%sp + 2047 + 128 + 0x28] | 163 | stx %g2, [%sp + 2047 + 128 + 0x28] |
@@ -190,8 +190,8 @@ do_dtlb: | |||
190 | sethi %hi(dtlb_load), %g2 | 190 | sethi %hi(dtlb_load), %g2 |
191 | or %g2, %lo(dtlb_load), %g2 | 191 | or %g2, %lo(dtlb_load), %g2 |
192 | stx %g2, [%sp + 2047 + 128 + 0x18] | 192 | stx %g2, [%sp + 2047 + 128 + 0x18] |
193 | sethi %hi(mmu_ihandle_cache), %g2 | 193 | sethi %hi(prom_mmu_ihandle_cache), %g2 |
194 | lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 | 194 | lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2 |
195 | stx %g2, [%sp + 2047 + 128 + 0x20] | 195 | stx %g2, [%sp + 2047 + 128 + 0x20] |
196 | sethi %hi(KERNBASE), %g2 | 196 | sethi %hi(KERNBASE), %g2 |
197 | stx %g2, [%sp + 2047 + 128 + 0x28] | 197 | stx %g2, [%sp + 2047 + 128 + 0x28] |
@@ -228,8 +228,8 @@ do_dtlb: | |||
228 | sethi %hi(dtlb_load), %g2 | 228 | sethi %hi(dtlb_load), %g2 |
229 | or %g2, %lo(dtlb_load), %g2 | 229 | or %g2, %lo(dtlb_load), %g2 |
230 | stx %g2, [%sp + 2047 + 128 + 0x18] | 230 | stx %g2, [%sp + 2047 + 128 + 0x18] |
231 | sethi %hi(mmu_ihandle_cache), %g2 | 231 | sethi %hi(prom_mmu_ihandle_cache), %g2 |
232 | lduw [%g2 + %lo(mmu_ihandle_cache)], %g2 | 232 | lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2 |
233 | stx %g2, [%sp + 2047 + 128 + 0x20] | 233 | stx %g2, [%sp + 2047 + 128 + 0x20] |
234 | sethi %hi(KERNBASE + 0x400000), %g2 | 234 | sethi %hi(KERNBASE + 0x400000), %g2 |
235 | stx %g2, [%sp + 2047 + 128 + 0x28] | 235 | stx %g2, [%sp + 2047 + 128 + 0x28] |
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index b280b2ef674f..f8e7005fede9 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
@@ -869,14 +869,19 @@ static void cheetah_flush_ecache_line(unsigned long physaddr) | |||
869 | */ | 869 | */ |
870 | static void __cheetah_flush_icache(void) | 870 | static void __cheetah_flush_icache(void) |
871 | { | 871 | { |
872 | unsigned long i; | 872 | unsigned int icache_size, icache_line_size; |
873 | unsigned long addr; | ||
874 | |||
875 | icache_size = local_cpu_data().icache_size; | ||
876 | icache_line_size = local_cpu_data().icache_line_size; | ||
873 | 877 | ||
874 | /* Clear the valid bits in all the tags. */ | 878 | /* Clear the valid bits in all the tags. */ |
875 | for (i = 0; i < (1 << 15); i += (1 << 5)) { | 879 | for (addr = 0; addr < icache_size; addr += icache_line_size) { |
876 | __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" | 880 | __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" |
877 | "membar #Sync" | 881 | "membar #Sync" |
878 | : /* no outputs */ | 882 | : /* no outputs */ |
879 | : "r" (i | (2 << 3)), "i" (ASI_IC_TAG)); | 883 | : "r" (addr | (2 << 3)), |
884 | "i" (ASI_IC_TAG)); | ||
880 | } | 885 | } |
881 | } | 886 | } |
882 | 887 | ||
@@ -904,13 +909,17 @@ static void cheetah_flush_icache(void) | |||
904 | 909 | ||
905 | static void cheetah_flush_dcache(void) | 910 | static void cheetah_flush_dcache(void) |
906 | { | 911 | { |
907 | unsigned long i; | 912 | unsigned int dcache_size, dcache_line_size; |
913 | unsigned long addr; | ||
914 | |||
915 | dcache_size = local_cpu_data().dcache_size; | ||
916 | dcache_line_size = local_cpu_data().dcache_line_size; | ||
908 | 917 | ||
909 | for (i = 0; i < (1 << 16); i += (1 << 5)) { | 918 | for (addr = 0; addr < dcache_size; addr += dcache_line_size) { |
910 | __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" | 919 | __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" |
911 | "membar #Sync" | 920 | "membar #Sync" |
912 | : /* no outputs */ | 921 | : /* no outputs */ |
913 | : "r" (i), "i" (ASI_DCACHE_TAG)); | 922 | : "r" (addr), "i" (ASI_DCACHE_TAG)); |
914 | } | 923 | } |
915 | } | 924 | } |
916 | 925 | ||
@@ -921,24 +930,29 @@ static void cheetah_flush_dcache(void) | |||
921 | */ | 930 | */ |
922 | static void cheetah_plus_zap_dcache_parity(void) | 931 | static void cheetah_plus_zap_dcache_parity(void) |
923 | { | 932 | { |
924 | unsigned long i; | 933 | unsigned int dcache_size, dcache_line_size; |
934 | unsigned long addr; | ||
935 | |||
936 | dcache_size = local_cpu_data().dcache_size; | ||
937 | dcache_line_size = local_cpu_data().dcache_line_size; | ||
925 | 938 | ||
926 | for (i = 0; i < (1 << 16); i += (1 << 5)) { | 939 | for (addr = 0; addr < dcache_size; addr += dcache_line_size) { |
927 | unsigned long tag = (i >> 14); | 940 | unsigned long tag = (addr >> 14); |
928 | unsigned long j; | 941 | unsigned long line; |
929 | 942 | ||
930 | __asm__ __volatile__("membar #Sync\n\t" | 943 | __asm__ __volatile__("membar #Sync\n\t" |
931 | "stxa %0, [%1] %2\n\t" | 944 | "stxa %0, [%1] %2\n\t" |
932 | "membar #Sync" | 945 | "membar #Sync" |
933 | : /* no outputs */ | 946 | : /* no outputs */ |
934 | : "r" (tag), "r" (i), | 947 | : "r" (tag), "r" (addr), |
935 | "i" (ASI_DCACHE_UTAG)); | 948 | "i" (ASI_DCACHE_UTAG)); |
936 | for (j = i; j < i + (1 << 5); j += (1 << 3)) | 949 | for (line = addr; line < addr + dcache_line_size; line += 8) |
937 | __asm__ __volatile__("membar #Sync\n\t" | 950 | __asm__ __volatile__("membar #Sync\n\t" |
938 | "stxa %%g0, [%0] %1\n\t" | 951 | "stxa %%g0, [%0] %1\n\t" |
939 | "membar #Sync" | 952 | "membar #Sync" |
940 | : /* no outputs */ | 953 | : /* no outputs */ |
941 | : "r" (j), "i" (ASI_DCACHE_DATA)); | 954 | : "r" (line), |
955 | "i" (ASI_DCACHE_DATA)); | ||
942 | } | 956 | } |
943 | } | 957 | } |
944 | 958 | ||
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S index f47d0be39378..2af0cf0a8640 100644 --- a/arch/sparc64/kernel/vmlinux.lds.S +++ b/arch/sparc64/kernel/vmlinux.lds.S | |||
@@ -9,8 +9,7 @@ ENTRY(_start) | |||
9 | jiffies = jiffies_64; | 9 | jiffies = jiffies_64; |
10 | SECTIONS | 10 | SECTIONS |
11 | { | 11 | { |
12 | swapper_pmd_dir = 0x0000000000402000; | 12 | swapper_low_pmd_dir = 0x0000000000402000; |
13 | empty_pg_dir = 0x0000000000403000; | ||
14 | . = 0x4000; | 13 | . = 0x4000; |
15 | .text 0x0000000000404000 : | 14 | .text 0x0000000000404000 : |
16 | { | 15 | { |
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index fdb1ebb308c9..9f6ca624892d 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
21 | #include <linux/seq_file.h> | 21 | #include <linux/seq_file.h> |
22 | #include <linux/kprobes.h> | 22 | #include <linux/kprobes.h> |
23 | #include <linux/cache.h> | ||
23 | 24 | ||
24 | #include <asm/head.h> | 25 | #include <asm/head.h> |
25 | #include <asm/system.h> | 26 | #include <asm/system.h> |
@@ -42,22 +43,13 @@ extern void device_scan(void); | |||
42 | 43 | ||
43 | struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; | 44 | struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; |
44 | 45 | ||
45 | unsigned long *sparc64_valid_addr_bitmap; | 46 | unsigned long *sparc64_valid_addr_bitmap __read_mostly; |
46 | 47 | ||
47 | /* Ugly, but necessary... -DaveM */ | 48 | /* Ugly, but necessary... -DaveM */ |
48 | unsigned long phys_base; | 49 | unsigned long phys_base __read_mostly; |
49 | unsigned long kern_base; | 50 | unsigned long kern_base __read_mostly; |
50 | unsigned long kern_size; | 51 | unsigned long kern_size __read_mostly; |
51 | unsigned long pfn_base; | 52 | unsigned long pfn_base __read_mostly; |
52 | |||
53 | /* This is even uglier. We have a problem where the kernel may not be | ||
54 | * located at phys_base. However, initial __alloc_bootmem() calls need to | ||
55 | * be adjusted to be within the 4-8Megs that the kernel is mapped to, else | ||
56 | * those page mappings wont work. Things are ok after inherit_prom_mappings | ||
57 | * is called though. Dave says he'll clean this up some other time. | ||
58 | * -- BenC | ||
59 | */ | ||
60 | static unsigned long bootmap_base; | ||
61 | 53 | ||
62 | /* get_new_mmu_context() uses "cache + 1". */ | 54 | /* get_new_mmu_context() uses "cache + 1". */ |
63 | DEFINE_SPINLOCK(ctx_alloc_lock); | 55 | DEFINE_SPINLOCK(ctx_alloc_lock); |
@@ -73,7 +65,7 @@ extern unsigned long sparc_ramdisk_image64; | |||
73 | extern unsigned int sparc_ramdisk_image; | 65 | extern unsigned int sparc_ramdisk_image; |
74 | extern unsigned int sparc_ramdisk_size; | 66 | extern unsigned int sparc_ramdisk_size; |
75 | 67 | ||
76 | struct page *mem_map_zero; | 68 | struct page *mem_map_zero __read_mostly; |
77 | 69 | ||
78 | int bigkernel = 0; | 70 | int bigkernel = 0; |
79 | 71 | ||
@@ -179,8 +171,6 @@ static __inline__ void clear_dcache_dirty_cpu(struct page *page, unsigned long c | |||
179 | : "g1", "g7"); | 171 | : "g1", "g7"); |
180 | } | 172 | } |
181 | 173 | ||
182 | extern void __update_mmu_cache(unsigned long mmu_context_hw, unsigned long address, pte_t pte, int code); | ||
183 | |||
184 | void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) | 174 | void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) |
185 | { | 175 | { |
186 | struct page *page; | 176 | struct page *page; |
@@ -207,10 +197,6 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p | |||
207 | 197 | ||
208 | put_cpu(); | 198 | put_cpu(); |
209 | } | 199 | } |
210 | |||
211 | if (get_thread_fault_code()) | ||
212 | __update_mmu_cache(CTX_NRBITS(vma->vm_mm->context), | ||
213 | address, pte, get_thread_fault_code()); | ||
214 | } | 200 | } |
215 | 201 | ||
216 | void flush_dcache_page(struct page *page) | 202 | void flush_dcache_page(struct page *page) |
@@ -309,6 +295,7 @@ struct linux_prom_translation { | |||
309 | unsigned long size; | 295 | unsigned long size; |
310 | unsigned long data; | 296 | unsigned long data; |
311 | }; | 297 | }; |
298 | static struct linux_prom_translation prom_trans[512] __initdata; | ||
312 | 299 | ||
313 | extern unsigned long prom_boot_page; | 300 | extern unsigned long prom_boot_page; |
314 | extern void prom_remap(unsigned long physpage, unsigned long virtpage, int mmu_ihandle); | 301 | extern void prom_remap(unsigned long physpage, unsigned long virtpage, int mmu_ihandle); |
@@ -318,14 +305,63 @@ extern void register_prom_callbacks(void); | |||
318 | /* Exported for SMP bootup purposes. */ | 305 | /* Exported for SMP bootup purposes. */ |
319 | unsigned long kern_locked_tte_data; | 306 | unsigned long kern_locked_tte_data; |
320 | 307 | ||
321 | void __init early_pgtable_allocfail(char *type) | 308 | /* Exported for kernel TLB miss handling in ktlb.S */ |
309 | unsigned long prom_pmd_phys __read_mostly; | ||
310 | unsigned int swapper_pgd_zero __read_mostly; | ||
311 | |||
312 | /* Allocate power-of-2 aligned chunks from the end of the | ||
313 | * kernel image. Return physical address. | ||
314 | */ | ||
315 | static inline unsigned long early_alloc_phys(unsigned long size) | ||
316 | { | ||
317 | unsigned long base; | ||
318 | |||
319 | BUILD_BUG_ON(size & (size - 1)); | ||
320 | |||
321 | kern_size = (kern_size + (size - 1)) & ~(size - 1); | ||
322 | base = kern_base + kern_size; | ||
323 | kern_size += size; | ||
324 | |||
325 | return base; | ||
326 | } | ||
327 | |||
328 | static inline unsigned long load_phys32(unsigned long pa) | ||
329 | { | ||
330 | unsigned long val; | ||
331 | |||
332 | __asm__ __volatile__("lduwa [%1] %2, %0" | ||
333 | : "=&r" (val) | ||
334 | : "r" (pa), "i" (ASI_PHYS_USE_EC)); | ||
335 | |||
336 | return val; | ||
337 | } | ||
338 | |||
339 | static inline unsigned long load_phys64(unsigned long pa) | ||
340 | { | ||
341 | unsigned long val; | ||
342 | |||
343 | __asm__ __volatile__("ldxa [%1] %2, %0" | ||
344 | : "=&r" (val) | ||
345 | : "r" (pa), "i" (ASI_PHYS_USE_EC)); | ||
346 | |||
347 | return val; | ||
348 | } | ||
349 | |||
350 | static inline void store_phys32(unsigned long pa, unsigned long val) | ||
351 | { | ||
352 | __asm__ __volatile__("stwa %0, [%1] %2" | ||
353 | : /* no outputs */ | ||
354 | : "r" (val), "r" (pa), "i" (ASI_PHYS_USE_EC)); | ||
355 | } | ||
356 | |||
357 | static inline void store_phys64(unsigned long pa, unsigned long val) | ||
322 | { | 358 | { |
323 | prom_printf("inherit_prom_mappings: Cannot alloc kernel %s.\n", type); | 359 | __asm__ __volatile__("stxa %0, [%1] %2" |
324 | prom_halt(); | 360 | : /* no outputs */ |
361 | : "r" (val), "r" (pa), "i" (ASI_PHYS_USE_EC)); | ||
325 | } | 362 | } |
326 | 363 | ||
327 | #define BASE_PAGE_SIZE 8192 | 364 | #define BASE_PAGE_SIZE 8192 |
328 | static pmd_t *prompmd; | ||
329 | 365 | ||
330 | /* | 366 | /* |
331 | * Translate PROM's mapping we capture at boot time into physical address. | 367 | * Translate PROM's mapping we capture at boot time into physical address. |
@@ -333,278 +369,172 @@ static pmd_t *prompmd; | |||
333 | */ | 369 | */ |
334 | unsigned long prom_virt_to_phys(unsigned long promva, int *error) | 370 | unsigned long prom_virt_to_phys(unsigned long promva, int *error) |
335 | { | 371 | { |
336 | pmd_t *pmdp = prompmd + ((promva >> 23) & 0x7ff); | 372 | unsigned long pmd_phys = (prom_pmd_phys + |
337 | pte_t *ptep; | 373 | ((promva >> 23) & 0x7ff) * sizeof(pmd_t)); |
374 | unsigned long pte_phys; | ||
375 | pmd_t pmd_ent; | ||
376 | pte_t pte_ent; | ||
338 | unsigned long base; | 377 | unsigned long base; |
339 | 378 | ||
340 | if (pmd_none(*pmdp)) { | 379 | pmd_val(pmd_ent) = load_phys32(pmd_phys); |
380 | if (pmd_none(pmd_ent)) { | ||
341 | if (error) | 381 | if (error) |
342 | *error = 1; | 382 | *error = 1; |
343 | return(0); | 383 | return 0; |
344 | } | 384 | } |
345 | ptep = (pte_t *)__pmd_page(*pmdp) + ((promva >> 13) & 0x3ff); | 385 | |
346 | if (!pte_present(*ptep)) { | 386 | pte_phys = (unsigned long)pmd_val(pmd_ent) << 11UL; |
387 | pte_phys += ((promva >> 13) & 0x3ff) * sizeof(pte_t); | ||
388 | pte_val(pte_ent) = load_phys64(pte_phys); | ||
389 | if (!pte_present(pte_ent)) { | ||
347 | if (error) | 390 | if (error) |
348 | *error = 1; | 391 | *error = 1; |
349 | return(0); | 392 | return 0; |
350 | } | 393 | } |
351 | if (error) { | 394 | if (error) { |
352 | *error = 0; | 395 | *error = 0; |
353 | return(pte_val(*ptep)); | 396 | return pte_val(pte_ent); |
354 | } | 397 | } |
355 | base = pte_val(*ptep) & _PAGE_PADDR; | 398 | base = pte_val(pte_ent) & _PAGE_PADDR; |
356 | return(base + (promva & (BASE_PAGE_SIZE - 1))); | 399 | return (base + (promva & (BASE_PAGE_SIZE - 1))); |
357 | } | 400 | } |
358 | 401 | ||
359 | static void inherit_prom_mappings(void) | 402 | /* The obp translations are saved based on 8k pagesize, since obp can |
403 | * use a mixture of pagesizes. Misses to the LOW_OBP_ADDRESS -> | ||
404 | * HI_OBP_ADDRESS range are handled in entry.S and do not use the vpte | ||
405 | * scheme (also, see rant in inherit_locked_prom_mappings()). | ||
406 | */ | ||
407 | static void __init build_obp_range(unsigned long start, unsigned long end, unsigned long data) | ||
360 | { | 408 | { |
361 | struct linux_prom_translation *trans; | 409 | unsigned long vaddr; |
362 | unsigned long phys_page, tte_vaddr, tte_data; | ||
363 | void (*remap_func)(unsigned long, unsigned long, int); | ||
364 | pmd_t *pmdp; | ||
365 | pte_t *ptep; | ||
366 | int node, n, i, tsz; | ||
367 | extern unsigned int obp_iaddr_patch[2], obp_daddr_patch[2]; | ||
368 | 410 | ||
369 | node = prom_finddevice("/virtual-memory"); | 411 | for (vaddr = start; vaddr < end; vaddr += BASE_PAGE_SIZE) { |
370 | n = prom_getproplen(node, "translations"); | 412 | unsigned long val, pte_phys, pmd_phys; |
371 | if (n == 0 || n == -1) { | 413 | pmd_t pmd_ent; |
372 | prom_printf("Couldn't get translation property\n"); | 414 | int i; |
373 | prom_halt(); | ||
374 | } | ||
375 | n += 5 * sizeof(struct linux_prom_translation); | ||
376 | for (tsz = 1; tsz < n; tsz <<= 1) | ||
377 | /* empty */; | ||
378 | trans = __alloc_bootmem(tsz, SMP_CACHE_BYTES, bootmap_base); | ||
379 | if (trans == NULL) { | ||
380 | prom_printf("inherit_prom_mappings: Cannot alloc translations.\n"); | ||
381 | prom_halt(); | ||
382 | } | ||
383 | memset(trans, 0, tsz); | ||
384 | 415 | ||
385 | if ((n = prom_getproperty(node, "translations", (char *)trans, tsz)) == -1) { | 416 | pmd_phys = (prom_pmd_phys + |
386 | prom_printf("Couldn't get translation property\n"); | 417 | (((vaddr >> 23) & 0x7ff) * sizeof(pmd_t))); |
387 | prom_halt(); | 418 | pmd_val(pmd_ent) = load_phys32(pmd_phys); |
388 | } | 419 | if (pmd_none(pmd_ent)) { |
389 | n = n / sizeof(*trans); | 420 | pte_phys = early_alloc_phys(BASE_PAGE_SIZE); |
390 | 421 | ||
391 | /* | 422 | for (i = 0; i < BASE_PAGE_SIZE / sizeof(pte_t); i++) |
392 | * The obp translations are saved based on 8k pagesize, since obp can | 423 | store_phys64(pte_phys+i*sizeof(pte_t),0); |
393 | * use a mixture of pagesizes. Misses to the 0xf0000000 - 0x100000000, | ||
394 | * ie obp range, are handled in entry.S and do not use the vpte scheme | ||
395 | * (see rant in inherit_locked_prom_mappings()). | ||
396 | */ | ||
397 | #define OBP_PMD_SIZE 2048 | ||
398 | prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, bootmap_base); | ||
399 | if (prompmd == NULL) | ||
400 | early_pgtable_allocfail("pmd"); | ||
401 | memset(prompmd, 0, OBP_PMD_SIZE); | ||
402 | for (i = 0; i < n; i++) { | ||
403 | unsigned long vaddr; | ||
404 | |||
405 | if (trans[i].virt >= LOW_OBP_ADDRESS && trans[i].virt < HI_OBP_ADDRESS) { | ||
406 | for (vaddr = trans[i].virt; | ||
407 | ((vaddr < trans[i].virt + trans[i].size) && | ||
408 | (vaddr < HI_OBP_ADDRESS)); | ||
409 | vaddr += BASE_PAGE_SIZE) { | ||
410 | unsigned long val; | ||
411 | |||
412 | pmdp = prompmd + ((vaddr >> 23) & 0x7ff); | ||
413 | if (pmd_none(*pmdp)) { | ||
414 | ptep = __alloc_bootmem(BASE_PAGE_SIZE, | ||
415 | BASE_PAGE_SIZE, | ||
416 | bootmap_base); | ||
417 | if (ptep == NULL) | ||
418 | early_pgtable_allocfail("pte"); | ||
419 | memset(ptep, 0, BASE_PAGE_SIZE); | ||
420 | pmd_set(pmdp, ptep); | ||
421 | } | ||
422 | ptep = (pte_t *)__pmd_page(*pmdp) + | ||
423 | ((vaddr >> 13) & 0x3ff); | ||
424 | 424 | ||
425 | val = trans[i].data; | 425 | pmd_val(pmd_ent) = pte_phys >> 11UL; |
426 | store_phys32(pmd_phys, pmd_val(pmd_ent)); | ||
427 | } | ||
426 | 428 | ||
427 | /* Clear diag TTE bits. */ | 429 | pte_phys = (unsigned long)pmd_val(pmd_ent) << 11UL; |
428 | if (tlb_type == spitfire) | 430 | pte_phys += (((vaddr >> 13) & 0x3ff) * sizeof(pte_t)); |
429 | val &= ~0x0003fe0000000000UL; | ||
430 | 431 | ||
431 | set_pte_at(&init_mm, vaddr, | 432 | val = data; |
432 | ptep, __pte(val | _PAGE_MODIFIED)); | ||
433 | trans[i].data += BASE_PAGE_SIZE; | ||
434 | } | ||
435 | } | ||
436 | } | ||
437 | phys_page = __pa(prompmd); | ||
438 | obp_iaddr_patch[0] |= (phys_page >> 10); | ||
439 | obp_iaddr_patch[1] |= (phys_page & 0x3ff); | ||
440 | flushi((long)&obp_iaddr_patch[0]); | ||
441 | obp_daddr_patch[0] |= (phys_page >> 10); | ||
442 | obp_daddr_patch[1] |= (phys_page & 0x3ff); | ||
443 | flushi((long)&obp_daddr_patch[0]); | ||
444 | 433 | ||
445 | /* Now fixup OBP's idea about where we really are mapped. */ | 434 | /* Clear diag TTE bits. */ |
446 | prom_printf("Remapping the kernel... "); | 435 | if (tlb_type == spitfire) |
436 | val &= ~0x0003fe0000000000UL; | ||
447 | 437 | ||
448 | /* Spitfire Errata #32 workaround */ | 438 | store_phys64(pte_phys, val | _PAGE_MODIFIED); |
449 | /* NOTE: Using plain zero for the context value is | ||
450 | * correct here, we are not using the Linux trap | ||
451 | * tables yet so we should not use the special | ||
452 | * UltraSPARC-III+ page size encodings yet. | ||
453 | */ | ||
454 | __asm__ __volatile__("stxa %0, [%1] %2\n\t" | ||
455 | "flush %%g6" | ||
456 | : /* No outputs */ | ||
457 | : "r" (0), "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); | ||
458 | |||
459 | switch (tlb_type) { | ||
460 | default: | ||
461 | case spitfire: | ||
462 | phys_page = spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()); | ||
463 | break; | ||
464 | |||
465 | case cheetah: | ||
466 | case cheetah_plus: | ||
467 | phys_page = cheetah_get_litlb_data(sparc64_highest_locked_tlbent()); | ||
468 | break; | ||
469 | }; | ||
470 | |||
471 | phys_page &= _PAGE_PADDR; | ||
472 | phys_page += ((unsigned long)&prom_boot_page - | ||
473 | (unsigned long)KERNBASE); | ||
474 | 439 | ||
475 | if (tlb_type == spitfire) { | 440 | data += BASE_PAGE_SIZE; |
476 | /* Lock this into i/d tlb entry 59 */ | ||
477 | __asm__ __volatile__( | ||
478 | "stxa %%g0, [%2] %3\n\t" | ||
479 | "stxa %0, [%1] %4\n\t" | ||
480 | "membar #Sync\n\t" | ||
481 | "flush %%g6\n\t" | ||
482 | "stxa %%g0, [%2] %5\n\t" | ||
483 | "stxa %0, [%1] %6\n\t" | ||
484 | "membar #Sync\n\t" | ||
485 | "flush %%g6" | ||
486 | : : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP | | ||
487 | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), | ||
488 | "r" (59 << 3), "r" (TLB_TAG_ACCESS), | ||
489 | "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), | ||
490 | "i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS) | ||
491 | : "memory"); | ||
492 | } else if (tlb_type == cheetah || tlb_type == cheetah_plus) { | ||
493 | /* Lock this into i/d tlb-0 entry 11 */ | ||
494 | __asm__ __volatile__( | ||
495 | "stxa %%g0, [%2] %3\n\t" | ||
496 | "stxa %0, [%1] %4\n\t" | ||
497 | "membar #Sync\n\t" | ||
498 | "flush %%g6\n\t" | ||
499 | "stxa %%g0, [%2] %5\n\t" | ||
500 | "stxa %0, [%1] %6\n\t" | ||
501 | "membar #Sync\n\t" | ||
502 | "flush %%g6" | ||
503 | : : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP | | ||
504 | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), | ||
505 | "r" ((0 << 16) | (11 << 3)), "r" (TLB_TAG_ACCESS), | ||
506 | "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), | ||
507 | "i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS) | ||
508 | : "memory"); | ||
509 | } else { | ||
510 | /* Implement me :-) */ | ||
511 | BUG(); | ||
512 | } | 441 | } |
442 | } | ||
513 | 443 | ||
514 | tte_vaddr = (unsigned long) KERNBASE; | 444 | static inline int in_obp_range(unsigned long vaddr) |
445 | { | ||
446 | return (vaddr >= LOW_OBP_ADDRESS && | ||
447 | vaddr < HI_OBP_ADDRESS); | ||
448 | } | ||
515 | 449 | ||
516 | /* Spitfire Errata #32 workaround */ | 450 | #define OBP_PMD_SIZE 2048 |
517 | /* NOTE: Using plain zero for the context value is | 451 | static void __init build_obp_pgtable(int prom_trans_ents) |
518 | * correct here, we are not using the Linux trap | 452 | { |
519 | * tables yet so we should not use the special | 453 | unsigned long i; |
520 | * UltraSPARC-III+ page size encodings yet. | ||
521 | */ | ||
522 | __asm__ __volatile__("stxa %0, [%1] %2\n\t" | ||
523 | "flush %%g6" | ||
524 | : /* No outputs */ | ||
525 | : "r" (0), | ||
526 | "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); | ||
527 | |||
528 | if (tlb_type == spitfire) | ||
529 | tte_data = spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()); | ||
530 | else | ||
531 | tte_data = cheetah_get_ldtlb_data(sparc64_highest_locked_tlbent()); | ||
532 | 454 | ||
533 | kern_locked_tte_data = tte_data; | 455 | prom_pmd_phys = early_alloc_phys(OBP_PMD_SIZE); |
456 | for (i = 0; i < OBP_PMD_SIZE; i += 4) | ||
457 | store_phys32(prom_pmd_phys + i, 0); | ||
458 | |||
459 | for (i = 0; i < prom_trans_ents; i++) { | ||
460 | unsigned long start, end; | ||
534 | 461 | ||
535 | remap_func = (void *) ((unsigned long) &prom_remap - | 462 | if (!in_obp_range(prom_trans[i].virt)) |
536 | (unsigned long) &prom_boot_page); | 463 | continue; |
537 | 464 | ||
465 | start = prom_trans[i].virt; | ||
466 | end = start + prom_trans[i].size; | ||
467 | if (end > HI_OBP_ADDRESS) | ||
468 | end = HI_OBP_ADDRESS; | ||
538 | 469 | ||
539 | /* Spitfire Errata #32 workaround */ | 470 | build_obp_range(start, end, prom_trans[i].data); |
540 | /* NOTE: Using plain zero for the context value is | ||
541 | * correct here, we are not using the Linux trap | ||
542 | * tables yet so we should not use the special | ||
543 | * UltraSPARC-III+ page size encodings yet. | ||
544 | */ | ||
545 | __asm__ __volatile__("stxa %0, [%1] %2\n\t" | ||
546 | "flush %%g6" | ||
547 | : /* No outputs */ | ||
548 | : "r" (0), | ||
549 | "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU)); | ||
550 | |||
551 | remap_func((tlb_type == spitfire ? | ||
552 | (spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR) : | ||
553 | (cheetah_get_litlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR)), | ||
554 | (unsigned long) KERNBASE, | ||
555 | prom_get_mmu_ihandle()); | ||
556 | |||
557 | if (bigkernel) | ||
558 | remap_func(((tte_data + 0x400000) & _PAGE_PADDR), | ||
559 | (unsigned long) KERNBASE + 0x400000, prom_get_mmu_ihandle()); | ||
560 | |||
561 | /* Flush out that temporary mapping. */ | ||
562 | spitfire_flush_dtlb_nucleus_page(0x0); | ||
563 | spitfire_flush_itlb_nucleus_page(0x0); | ||
564 | |||
565 | /* Now lock us back into the TLBs via OBP. */ | ||
566 | prom_dtlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr); | ||
567 | prom_itlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr); | ||
568 | if (bigkernel) { | ||
569 | prom_dtlb_load(sparc64_highest_locked_tlbent()-1, tte_data + 0x400000, | ||
570 | tte_vaddr + 0x400000); | ||
571 | prom_itlb_load(sparc64_highest_locked_tlbent()-1, tte_data + 0x400000, | ||
572 | tte_vaddr + 0x400000); | ||
573 | } | 471 | } |
472 | } | ||
574 | 473 | ||
575 | /* Re-read translations property. */ | 474 | /* Read OBP translations property into 'prom_trans[]'. |
576 | if ((n = prom_getproperty(node, "translations", (char *)trans, tsz)) == -1) { | 475 | * Return the number of entries. |
577 | prom_printf("Couldn't get translation property\n"); | 476 | */ |
477 | static int __init read_obp_translations(void) | ||
478 | { | ||
479 | int n, node; | ||
480 | |||
481 | node = prom_finddevice("/virtual-memory"); | ||
482 | n = prom_getproplen(node, "translations"); | ||
483 | if (unlikely(n == 0 || n == -1)) { | ||
484 | prom_printf("prom_mappings: Couldn't get size.\n"); | ||
485 | prom_halt(); | ||
486 | } | ||
487 | if (unlikely(n > sizeof(prom_trans))) { | ||
488 | prom_printf("prom_mappings: Size %Zd is too big.\n", n); | ||
578 | prom_halt(); | 489 | prom_halt(); |
579 | } | 490 | } |
580 | n = n / sizeof(*trans); | ||
581 | 491 | ||
582 | for (i = 0; i < n; i++) { | 492 | if ((n = prom_getproperty(node, "translations", |
583 | unsigned long vaddr = trans[i].virt; | 493 | (char *)&prom_trans[0], |
584 | unsigned long size = trans[i].size; | 494 | sizeof(prom_trans))) == -1) { |
495 | prom_printf("prom_mappings: Couldn't get property.\n"); | ||
496 | prom_halt(); | ||
497 | } | ||
498 | n = n / sizeof(struct linux_prom_translation); | ||
499 | return n; | ||
500 | } | ||
585 | 501 | ||
586 | if (vaddr < 0xf0000000UL) { | 502 | static void __init remap_kernel(void) |
587 | unsigned long avoid_start = (unsigned long) KERNBASE; | 503 | { |
588 | unsigned long avoid_end = avoid_start + (4 * 1024 * 1024); | 504 | unsigned long phys_page, tte_vaddr, tte_data; |
505 | int tlb_ent = sparc64_highest_locked_tlbent(); | ||
589 | 506 | ||
590 | if (bigkernel) | 507 | tte_vaddr = (unsigned long) KERNBASE; |
591 | avoid_end += (4 * 1024 * 1024); | 508 | phys_page = (prom_boot_mapping_phys_low >> 22UL) << 22UL; |
592 | if (vaddr < avoid_start) { | 509 | tte_data = (phys_page | (_PAGE_VALID | _PAGE_SZ4MB | |
593 | unsigned long top = vaddr + size; | 510 | _PAGE_CP | _PAGE_CV | _PAGE_P | |
511 | _PAGE_L | _PAGE_W)); | ||
594 | 512 | ||
595 | if (top > avoid_start) | 513 | kern_locked_tte_data = tte_data; |
596 | top = avoid_start; | ||
597 | prom_unmap(top - vaddr, vaddr); | ||
598 | } | ||
599 | if ((vaddr + size) > avoid_end) { | ||
600 | unsigned long bottom = vaddr; | ||
601 | 514 | ||
602 | if (bottom < avoid_end) | 515 | /* Now lock us into the TLBs via OBP. */ |
603 | bottom = avoid_end; | 516 | prom_dtlb_load(tlb_ent, tte_data, tte_vaddr); |
604 | prom_unmap((vaddr + size) - bottom, bottom); | 517 | prom_itlb_load(tlb_ent, tte_data, tte_vaddr); |
605 | } | 518 | if (bigkernel) { |
606 | } | 519 | prom_dtlb_load(tlb_ent - 1, |
520 | tte_data + 0x400000, | ||
521 | tte_vaddr + 0x400000); | ||
522 | prom_itlb_load(tlb_ent - 1, | ||
523 | tte_data + 0x400000, | ||
524 | tte_vaddr + 0x400000); | ||
607 | } | 525 | } |
526 | } | ||
527 | |||
528 | static void __init inherit_prom_mappings(void) | ||
529 | { | ||
530 | int n; | ||
531 | |||
532 | n = read_obp_translations(); | ||
533 | build_obp_pgtable(n); | ||
534 | |||
535 | /* Now fixup OBP's idea about where we really are mapped. */ | ||
536 | prom_printf("Remapping the kernel... "); | ||
537 | remap_kernel(); | ||
608 | 538 | ||
609 | prom_printf("done.\n"); | 539 | prom_printf("done.\n"); |
610 | 540 | ||
@@ -1347,8 +1277,6 @@ unsigned long __init bootmem_init(unsigned long *pages_avail) | |||
1347 | #endif | 1277 | #endif |
1348 | bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, pfn_base, end_pfn); | 1278 | bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, pfn_base, end_pfn); |
1349 | 1279 | ||
1350 | bootmap_base = bootmap_pfn << PAGE_SHIFT; | ||
1351 | |||
1352 | /* Now register the available physical memory with the | 1280 | /* Now register the available physical memory with the |
1353 | * allocator. | 1281 | * allocator. |
1354 | */ | 1282 | */ |
@@ -1398,120 +1326,142 @@ unsigned long __init bootmem_init(unsigned long *pages_avail) | |||
1398 | return end_pfn; | 1326 | return end_pfn; |
1399 | } | 1327 | } |
1400 | 1328 | ||
1329 | #ifdef CONFIG_DEBUG_PAGEALLOC | ||
1330 | static unsigned long kernel_map_range(unsigned long pstart, unsigned long pend, pgprot_t prot) | ||
1331 | { | ||
1332 | unsigned long vstart = PAGE_OFFSET + pstart; | ||
1333 | unsigned long vend = PAGE_OFFSET + pend; | ||
1334 | unsigned long alloc_bytes = 0UL; | ||
1335 | |||
1336 | if ((vstart & ~PAGE_MASK) || (vend & ~PAGE_MASK)) { | ||
1337 | prom_printf("kernel_map: Unaligned sp_banks[%lx:%lx]\n", | ||
1338 | vstart, vend); | ||
1339 | prom_halt(); | ||
1340 | } | ||
1341 | |||
1342 | while (vstart < vend) { | ||
1343 | unsigned long this_end, paddr = __pa(vstart); | ||
1344 | pgd_t *pgd = pgd_offset_k(vstart); | ||
1345 | pud_t *pud; | ||
1346 | pmd_t *pmd; | ||
1347 | pte_t *pte; | ||
1348 | |||
1349 | pud = pud_offset(pgd, vstart); | ||
1350 | if (pud_none(*pud)) { | ||
1351 | pmd_t *new; | ||
1352 | |||
1353 | new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE); | ||
1354 | alloc_bytes += PAGE_SIZE; | ||
1355 | pud_populate(&init_mm, pud, new); | ||
1356 | } | ||
1357 | |||
1358 | pmd = pmd_offset(pud, vstart); | ||
1359 | if (!pmd_present(*pmd)) { | ||
1360 | pte_t *new; | ||
1361 | |||
1362 | new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE); | ||
1363 | alloc_bytes += PAGE_SIZE; | ||
1364 | pmd_populate_kernel(&init_mm, pmd, new); | ||
1365 | } | ||
1366 | |||
1367 | pte = pte_offset_kernel(pmd, vstart); | ||
1368 | this_end = (vstart + PMD_SIZE) & PMD_MASK; | ||
1369 | if (this_end > vend) | ||
1370 | this_end = vend; | ||
1371 | |||
1372 | while (vstart < this_end) { | ||
1373 | pte_val(*pte) = (paddr | pgprot_val(prot)); | ||
1374 | |||
1375 | vstart += PAGE_SIZE; | ||
1376 | paddr += PAGE_SIZE; | ||
1377 | pte++; | ||
1378 | } | ||
1379 | } | ||
1380 | |||
1381 | return alloc_bytes; | ||
1382 | } | ||
1383 | |||
1384 | extern struct linux_mlist_p1275 *prom_ptot_ptr; | ||
1385 | extern unsigned int kvmap_linear_patch[1]; | ||
1386 | |||
1387 | static void __init kernel_physical_mapping_init(void) | ||
1388 | { | ||
1389 | struct linux_mlist_p1275 *p = prom_ptot_ptr; | ||
1390 | unsigned long mem_alloced = 0UL; | ||
1391 | |||
1392 | while (p) { | ||
1393 | unsigned long phys_start, phys_end; | ||
1394 | |||
1395 | phys_start = p->start_adr; | ||
1396 | phys_end = phys_start + p->num_bytes; | ||
1397 | mem_alloced += kernel_map_range(phys_start, phys_end, | ||
1398 | PAGE_KERNEL); | ||
1399 | |||
1400 | p = p->theres_more; | ||
1401 | } | ||
1402 | |||
1403 | printk("Allocated %ld bytes for kernel page tables.\n", | ||
1404 | mem_alloced); | ||
1405 | |||
1406 | kvmap_linear_patch[0] = 0x01000000; /* nop */ | ||
1407 | flushi(&kvmap_linear_patch[0]); | ||
1408 | |||
1409 | __flush_tlb_all(); | ||
1410 | } | ||
1411 | |||
1412 | void kernel_map_pages(struct page *page, int numpages, int enable) | ||
1413 | { | ||
1414 | unsigned long phys_start = page_to_pfn(page) << PAGE_SHIFT; | ||
1415 | unsigned long phys_end = phys_start + (numpages * PAGE_SIZE); | ||
1416 | |||
1417 | kernel_map_range(phys_start, phys_end, | ||
1418 | (enable ? PAGE_KERNEL : __pgprot(0))); | ||
1419 | |||
1420 | /* we should perform an IPI and flush all tlbs, | ||
1421 | * but that can deadlock->flush only current cpu. | ||
1422 | */ | ||
1423 | __flush_tlb_kernel_range(PAGE_OFFSET + phys_start, | ||
1424 | PAGE_OFFSET + phys_end); | ||
1425 | } | ||
1426 | #endif | ||
1427 | |||
1401 | /* paging_init() sets up the page tables */ | 1428 | /* paging_init() sets up the page tables */ |
1402 | 1429 | ||
1403 | extern void cheetah_ecache_flush_init(void); | 1430 | extern void cheetah_ecache_flush_init(void); |
1404 | 1431 | ||
1405 | static unsigned long last_valid_pfn; | 1432 | static unsigned long last_valid_pfn; |
1433 | pgd_t swapper_pg_dir[2048]; | ||
1406 | 1434 | ||
1407 | void __init paging_init(void) | 1435 | void __init paging_init(void) |
1408 | { | 1436 | { |
1409 | extern pmd_t swapper_pmd_dir[1024]; | 1437 | unsigned long end_pfn, pages_avail, shift; |
1410 | extern unsigned int sparc64_vpte_patchme1[1]; | ||
1411 | extern unsigned int sparc64_vpte_patchme2[1]; | ||
1412 | unsigned long alias_base = kern_base + PAGE_OFFSET; | ||
1413 | unsigned long second_alias_page = 0; | ||
1414 | unsigned long pt, flags, end_pfn, pages_avail; | ||
1415 | unsigned long shift = alias_base - ((unsigned long)KERNBASE); | ||
1416 | unsigned long real_end; | 1438 | unsigned long real_end; |
1417 | 1439 | ||
1418 | set_bit(0, mmu_context_bmap); | 1440 | set_bit(0, mmu_context_bmap); |
1419 | 1441 | ||
1442 | shift = kern_base + PAGE_OFFSET - ((unsigned long)KERNBASE); | ||
1443 | |||
1420 | real_end = (unsigned long)_end; | 1444 | real_end = (unsigned long)_end; |
1421 | if ((real_end > ((unsigned long)KERNBASE + 0x400000))) | 1445 | if ((real_end > ((unsigned long)KERNBASE + 0x400000))) |
1422 | bigkernel = 1; | 1446 | bigkernel = 1; |
1423 | #ifdef CONFIG_BLK_DEV_INITRD | 1447 | if ((real_end > ((unsigned long)KERNBASE + 0x800000))) { |
1424 | if (sparc_ramdisk_image || sparc_ramdisk_image64) | 1448 | prom_printf("paging_init: Kernel > 8MB, too large.\n"); |
1425 | real_end = (PAGE_ALIGN(real_end) + PAGE_ALIGN(sparc_ramdisk_size)); | 1449 | prom_halt(); |
1426 | #endif | ||
1427 | |||
1428 | /* We assume physical memory starts at some 4mb multiple, | ||
1429 | * if this were not true we wouldn't boot up to this point | ||
1430 | * anyways. | ||
1431 | */ | ||
1432 | pt = kern_base | _PAGE_VALID | _PAGE_SZ4MB; | ||
1433 | pt |= _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W; | ||
1434 | local_irq_save(flags); | ||
1435 | if (tlb_type == spitfire) { | ||
1436 | __asm__ __volatile__( | ||
1437 | " stxa %1, [%0] %3\n" | ||
1438 | " stxa %2, [%5] %4\n" | ||
1439 | " membar #Sync\n" | ||
1440 | " flush %%g6\n" | ||
1441 | " nop\n" | ||
1442 | " nop\n" | ||
1443 | " nop\n" | ||
1444 | : /* No outputs */ | ||
1445 | : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt), | ||
1446 | "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (61 << 3) | ||
1447 | : "memory"); | ||
1448 | if (real_end >= KERNBASE + 0x340000) { | ||
1449 | second_alias_page = alias_base + 0x400000; | ||
1450 | __asm__ __volatile__( | ||
1451 | " stxa %1, [%0] %3\n" | ||
1452 | " stxa %2, [%5] %4\n" | ||
1453 | " membar #Sync\n" | ||
1454 | " flush %%g6\n" | ||
1455 | " nop\n" | ||
1456 | " nop\n" | ||
1457 | " nop\n" | ||
1458 | : /* No outputs */ | ||
1459 | : "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000), | ||
1460 | "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (60 << 3) | ||
1461 | : "memory"); | ||
1462 | } | ||
1463 | } else if (tlb_type == cheetah || tlb_type == cheetah_plus) { | ||
1464 | __asm__ __volatile__( | ||
1465 | " stxa %1, [%0] %3\n" | ||
1466 | " stxa %2, [%5] %4\n" | ||
1467 | " membar #Sync\n" | ||
1468 | " flush %%g6\n" | ||
1469 | " nop\n" | ||
1470 | " nop\n" | ||
1471 | " nop\n" | ||
1472 | : /* No outputs */ | ||
1473 | : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt), | ||
1474 | "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (13<<3)) | ||
1475 | : "memory"); | ||
1476 | if (real_end >= KERNBASE + 0x340000) { | ||
1477 | second_alias_page = alias_base + 0x400000; | ||
1478 | __asm__ __volatile__( | ||
1479 | " stxa %1, [%0] %3\n" | ||
1480 | " stxa %2, [%5] %4\n" | ||
1481 | " membar #Sync\n" | ||
1482 | " flush %%g6\n" | ||
1483 | " nop\n" | ||
1484 | " nop\n" | ||
1485 | " nop\n" | ||
1486 | : /* No outputs */ | ||
1487 | : "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000), | ||
1488 | "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (12<<3)) | ||
1489 | : "memory"); | ||
1490 | } | ||
1491 | } | 1450 | } |
1492 | local_irq_restore(flags); | 1451 | |
1493 | 1452 | /* Set kernel pgd to upper alias so physical page computations | |
1494 | /* Now set kernel pgd to upper alias so physical page computations | ||
1495 | * work. | 1453 | * work. |
1496 | */ | 1454 | */ |
1497 | init_mm.pgd += ((shift) / (sizeof(pgd_t))); | 1455 | init_mm.pgd += ((shift) / (sizeof(pgd_t))); |
1498 | 1456 | ||
1499 | memset(swapper_pmd_dir, 0, sizeof(swapper_pmd_dir)); | 1457 | memset(swapper_low_pmd_dir, 0, sizeof(swapper_low_pmd_dir)); |
1500 | 1458 | ||
1501 | /* Now can init the kernel/bad page tables. */ | 1459 | /* Now can init the kernel/bad page tables. */ |
1502 | pud_set(pud_offset(&swapper_pg_dir[0], 0), | 1460 | pud_set(pud_offset(&swapper_pg_dir[0], 0), |
1503 | swapper_pmd_dir + (shift / sizeof(pgd_t))); | 1461 | swapper_low_pmd_dir + (shift / sizeof(pgd_t))); |
1504 | 1462 | ||
1505 | sparc64_vpte_patchme1[0] |= | 1463 | swapper_pgd_zero = pgd_val(swapper_pg_dir[0]); |
1506 | (((unsigned long)pgd_val(init_mm.pgd[0])) >> 10); | ||
1507 | sparc64_vpte_patchme2[0] |= | ||
1508 | (((unsigned long)pgd_val(init_mm.pgd[0])) & 0x3ff); | ||
1509 | flushi((long)&sparc64_vpte_patchme1[0]); | ||
1510 | 1464 | ||
1511 | /* Setup bootmem... */ | ||
1512 | pages_avail = 0; | ||
1513 | last_valid_pfn = end_pfn = bootmem_init(&pages_avail); | ||
1514 | |||
1515 | /* Inherit non-locked OBP mappings. */ | 1465 | /* Inherit non-locked OBP mappings. */ |
1516 | inherit_prom_mappings(); | 1466 | inherit_prom_mappings(); |
1517 | 1467 | ||
@@ -1527,13 +1477,16 @@ void __init paging_init(void) | |||
1527 | 1477 | ||
1528 | inherit_locked_prom_mappings(1); | 1478 | inherit_locked_prom_mappings(1); |
1529 | 1479 | ||
1530 | /* We only created DTLB mapping of this stuff. */ | ||
1531 | spitfire_flush_dtlb_nucleus_page(alias_base); | ||
1532 | if (second_alias_page) | ||
1533 | spitfire_flush_dtlb_nucleus_page(second_alias_page); | ||
1534 | |||
1535 | __flush_tlb_all(); | 1480 | __flush_tlb_all(); |
1536 | 1481 | ||
1482 | /* Setup bootmem... */ | ||
1483 | pages_avail = 0; | ||
1484 | last_valid_pfn = end_pfn = bootmem_init(&pages_avail); | ||
1485 | |||
1486 | #ifdef CONFIG_DEBUG_PAGEALLOC | ||
1487 | kernel_physical_mapping_init(); | ||
1488 | #endif | ||
1489 | |||
1537 | { | 1490 | { |
1538 | unsigned long zones_size[MAX_NR_ZONES]; | 1491 | unsigned long zones_size[MAX_NR_ZONES]; |
1539 | unsigned long zholes_size[MAX_NR_ZONES]; | 1492 | unsigned long zholes_size[MAX_NR_ZONES]; |
@@ -1695,8 +1648,7 @@ void __init mem_init(void) | |||
1695 | 1648 | ||
1696 | i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6); | 1649 | i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6); |
1697 | i += 1; | 1650 | i += 1; |
1698 | sparc64_valid_addr_bitmap = (unsigned long *) | 1651 | sparc64_valid_addr_bitmap = (unsigned long *) alloc_bootmem(i << 3); |
1699 | __alloc_bootmem(i << 3, SMP_CACHE_BYTES, bootmap_base); | ||
1700 | if (sparc64_valid_addr_bitmap == NULL) { | 1652 | if (sparc64_valid_addr_bitmap == NULL) { |
1701 | prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n"); | 1653 | prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n"); |
1702 | prom_halt(); | 1654 | prom_halt(); |
@@ -1749,7 +1701,7 @@ void __init mem_init(void) | |||
1749 | cheetah_ecache_flush_init(); | 1701 | cheetah_ecache_flush_init(); |
1750 | } | 1702 | } |
1751 | 1703 | ||
1752 | void free_initmem (void) | 1704 | void free_initmem(void) |
1753 | { | 1705 | { |
1754 | unsigned long addr, initend; | 1706 | unsigned long addr, initend; |
1755 | 1707 | ||
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index b2ee9b53227f..058b8126c1a7 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S | |||
@@ -144,42 +144,29 @@ __flush_icache_page: /* %o0 = phys_page */ | |||
144 | 144 | ||
145 | #define DTAG_MASK 0x3 | 145 | #define DTAG_MASK 0x3 |
146 | 146 | ||
147 | /* This routine is Spitfire specific so the hardcoded | ||
148 | * D-cache size and line-size are OK. | ||
149 | */ | ||
147 | .align 64 | 150 | .align 64 |
148 | .globl __flush_dcache_page | 151 | .globl __flush_dcache_page |
149 | __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */ | 152 | __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */ |
150 | sethi %uhi(PAGE_OFFSET), %g1 | 153 | sethi %uhi(PAGE_OFFSET), %g1 |
151 | sllx %g1, 32, %g1 | 154 | sllx %g1, 32, %g1 |
152 | sub %o0, %g1, %o0 | 155 | sub %o0, %g1, %o0 ! physical address |
153 | clr %o4 | 156 | srlx %o0, 11, %o0 ! make D-cache TAG |
154 | srlx %o0, 11, %o0 | 157 | sethi %hi(1 << 14), %o2 ! D-cache size |
155 | sethi %hi(1 << 14), %o2 | 158 | sub %o2, (1 << 5), %o2 ! D-cache line size |
156 | 1: ldxa [%o4] ASI_DCACHE_TAG, %o3 ! LSU Group | 159 | 1: ldxa [%o2] ASI_DCACHE_TAG, %o3 ! load D-cache TAG |
157 | add %o4, (1 << 5), %o4 ! IEU0 | 160 | andcc %o3, DTAG_MASK, %g0 ! Valid? |
158 | ldxa [%o4] ASI_DCACHE_TAG, %g1 ! LSU Group | 161 | be,pn %xcc, 2f ! Nope, branch |
159 | add %o4, (1 << 5), %o4 ! IEU0 | 162 | andn %o3, DTAG_MASK, %o3 ! Clear valid bits |
160 | ldxa [%o4] ASI_DCACHE_TAG, %g2 ! LSU Group o3 available | 163 | cmp %o3, %o0 ! TAG match? |
161 | add %o4, (1 << 5), %o4 ! IEU0 | 164 | bne,pt %xcc, 2f ! Nope, branch |
162 | andn %o3, DTAG_MASK, %o3 ! IEU1 | 165 | nop |
163 | ldxa [%o4] ASI_DCACHE_TAG, %g3 ! LSU Group | 166 | stxa %g0, [%o2] ASI_DCACHE_TAG ! Invalidate TAG |
164 | add %o4, (1 << 5), %o4 ! IEU0 | 167 | membar #Sync |
165 | andn %g1, DTAG_MASK, %g1 ! IEU1 | 168 | 2: brnz,pt %o2, 1b |
166 | cmp %o0, %o3 ! IEU1 Group | 169 | sub %o2, (1 << 5), %o2 ! D-cache line size |
167 | be,a,pn %xcc, dflush1 ! CTI | ||
168 | sub %o4, (4 << 5), %o4 ! IEU0 (Group) | ||
169 | cmp %o0, %g1 ! IEU1 Group | ||
170 | andn %g2, DTAG_MASK, %g2 ! IEU0 | ||
171 | be,a,pn %xcc, dflush2 ! CTI | ||
172 | sub %o4, (3 << 5), %o4 ! IEU0 (Group) | ||
173 | cmp %o0, %g2 ! IEU1 Group | ||
174 | andn %g3, DTAG_MASK, %g3 ! IEU0 | ||
175 | be,a,pn %xcc, dflush3 ! CTI | ||
176 | sub %o4, (2 << 5), %o4 ! IEU0 (Group) | ||
177 | cmp %o0, %g3 ! IEU1 Group | ||
178 | be,a,pn %xcc, dflush4 ! CTI | ||
179 | sub %o4, (1 << 5), %o4 ! IEU0 | ||
180 | 2: cmp %o4, %o2 ! IEU1 Group | ||
181 | bne,pt %xcc, 1b ! CTI | ||
182 | nop ! IEU0 | ||
183 | 170 | ||
184 | /* The I-cache does not snoop local stores so we | 171 | /* The I-cache does not snoop local stores so we |
185 | * better flush that too when necessary. | 172 | * better flush that too when necessary. |
@@ -189,48 +176,9 @@ __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */ | |||
189 | retl | 176 | retl |
190 | nop | 177 | nop |
191 | 178 | ||
192 | dflush1:stxa %g0, [%o4] ASI_DCACHE_TAG | ||
193 | add %o4, (1 << 5), %o4 | ||
194 | dflush2:stxa %g0, [%o4] ASI_DCACHE_TAG | ||
195 | add %o4, (1 << 5), %o4 | ||
196 | dflush3:stxa %g0, [%o4] ASI_DCACHE_TAG | ||
197 | add %o4, (1 << 5), %o4 | ||
198 | dflush4:stxa %g0, [%o4] ASI_DCACHE_TAG | ||
199 | add %o4, (1 << 5), %o4 | ||
200 | membar #Sync | ||
201 | ba,pt %xcc, 2b | ||
202 | nop | ||
203 | #endif /* DCACHE_ALIASING_POSSIBLE */ | 179 | #endif /* DCACHE_ALIASING_POSSIBLE */ |
204 | 180 | ||
205 | .previous .text | 181 | .previous |
206 | .align 32 | ||
207 | __prefill_dtlb: | ||
208 | rdpr %pstate, %g7 | ||
209 | wrpr %g7, PSTATE_IE, %pstate | ||
210 | mov TLB_TAG_ACCESS, %g1 | ||
211 | stxa %o5, [%g1] ASI_DMMU | ||
212 | stxa %o2, [%g0] ASI_DTLB_DATA_IN | ||
213 | flush %g6 | ||
214 | retl | ||
215 | wrpr %g7, %pstate | ||
216 | __prefill_itlb: | ||
217 | rdpr %pstate, %g7 | ||
218 | wrpr %g7, PSTATE_IE, %pstate | ||
219 | mov TLB_TAG_ACCESS, %g1 | ||
220 | stxa %o5, [%g1] ASI_IMMU | ||
221 | stxa %o2, [%g0] ASI_ITLB_DATA_IN | ||
222 | flush %g6 | ||
223 | retl | ||
224 | wrpr %g7, %pstate | ||
225 | |||
226 | .globl __update_mmu_cache | ||
227 | __update_mmu_cache: /* %o0=hw_context, %o1=address, %o2=pte, %o3=fault_code */ | ||
228 | srlx %o1, PAGE_SHIFT, %o1 | ||
229 | andcc %o3, FAULT_CODE_DTLB, %g0 | ||
230 | sllx %o1, PAGE_SHIFT, %o5 | ||
231 | bne,pt %xcc, __prefill_dtlb | ||
232 | or %o5, %o0, %o5 | ||
233 | ba,a,pt %xcc, __prefill_itlb | ||
234 | 182 | ||
235 | /* Cheetah specific versions, patched at boot time. */ | 183 | /* Cheetah specific versions, patched at boot time. */ |
236 | __cheetah_flush_tlb_mm: /* 18 insns */ | 184 | __cheetah_flush_tlb_mm: /* 18 insns */ |
@@ -283,7 +231,7 @@ __cheetah_flush_tlb_pending: /* 26 insns */ | |||
283 | wrpr %g7, 0x0, %pstate | 231 | wrpr %g7, 0x0, %pstate |
284 | 232 | ||
285 | #ifdef DCACHE_ALIASING_POSSIBLE | 233 | #ifdef DCACHE_ALIASING_POSSIBLE |
286 | flush_dcpage_cheetah: /* 11 insns */ | 234 | __cheetah_flush_dcache_page: /* 11 insns */ |
287 | sethi %uhi(PAGE_OFFSET), %g1 | 235 | sethi %uhi(PAGE_OFFSET), %g1 |
288 | sllx %g1, 32, %g1 | 236 | sllx %g1, 32, %g1 |
289 | sub %o0, %g1, %o0 | 237 | sub %o0, %g1, %o0 |
@@ -329,8 +277,8 @@ cheetah_patch_cachetlbops: | |||
329 | #ifdef DCACHE_ALIASING_POSSIBLE | 277 | #ifdef DCACHE_ALIASING_POSSIBLE |
330 | sethi %hi(__flush_dcache_page), %o0 | 278 | sethi %hi(__flush_dcache_page), %o0 |
331 | or %o0, %lo(__flush_dcache_page), %o0 | 279 | or %o0, %lo(__flush_dcache_page), %o0 |
332 | sethi %hi(flush_dcpage_cheetah), %o1 | 280 | sethi %hi(__cheetah_flush_dcache_page), %o1 |
333 | or %o1, %lo(flush_dcpage_cheetah), %o1 | 281 | or %o1, %lo(__cheetah_flush_dcache_page), %o1 |
334 | call cheetah_patch_one | 282 | call cheetah_patch_one |
335 | mov 11, %o2 | 283 | mov 11, %o2 |
336 | #endif /* DCACHE_ALIASING_POSSIBLE */ | 284 | #endif /* DCACHE_ALIASING_POSSIBLE */ |
diff --git a/arch/sparc64/prom/Makefile b/arch/sparc64/prom/Makefile index 8f2420d9e9e6..c7898a5ee456 100644 --- a/arch/sparc64/prom/Makefile +++ b/arch/sparc64/prom/Makefile | |||
@@ -7,4 +7,4 @@ EXTRA_AFLAGS := -ansi | |||
7 | EXTRA_CFLAGS := -Werror | 7 | EXTRA_CFLAGS := -Werror |
8 | 8 | ||
9 | lib-y := bootstr.o devops.o init.o memory.o misc.o \ | 9 | lib-y := bootstr.o devops.o init.o memory.o misc.o \ |
10 | tree.o console.o printf.o p1275.o map.o cif.o | 10 | tree.o console.o printf.o p1275.o cif.o |
diff --git a/arch/sparc64/prom/console.c b/arch/sparc64/prom/console.c index 028a53fcb1ec..eae5db8dda56 100644 --- a/arch/sparc64/prom/console.c +++ b/arch/sparc64/prom/console.c | |||
@@ -67,7 +67,7 @@ prom_putchar(char c) | |||
67 | } | 67 | } |
68 | 68 | ||
69 | void | 69 | void |
70 | prom_puts(char *s, int len) | 70 | prom_puts(const char *s, int len) |
71 | { | 71 | { |
72 | p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| | 72 | p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)| |
73 | P1275_INOUT(3,1), | 73 | P1275_INOUT(3,1), |
diff --git a/arch/sparc64/prom/devops.c b/arch/sparc64/prom/devops.c index 2c99b21b6981..4641839eb39a 100644 --- a/arch/sparc64/prom/devops.c +++ b/arch/sparc64/prom/devops.c | |||
@@ -16,7 +16,7 @@ | |||
16 | * Returns 0 on failure. | 16 | * Returns 0 on failure. |
17 | */ | 17 | */ |
18 | int | 18 | int |
19 | prom_devopen(char *dstr) | 19 | prom_devopen(const char *dstr) |
20 | { | 20 | { |
21 | return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)| | 21 | return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)| |
22 | P1275_INOUT(1,1), | 22 | P1275_INOUT(1,1), |
diff --git a/arch/sparc64/prom/init.c b/arch/sparc64/prom/init.c index 817faae058cd..8b4b622d0909 100644 --- a/arch/sparc64/prom/init.c +++ b/arch/sparc64/prom/init.c | |||
@@ -46,7 +46,7 @@ void __init prom_init(void *cif_handler, void *cif_stack) | |||
46 | if((prom_root_node == 0) || (prom_root_node == -1)) | 46 | if((prom_root_node == 0) || (prom_root_node == -1)) |
47 | prom_halt(); | 47 | prom_halt(); |
48 | 48 | ||
49 | prom_chosen_node = prom_finddevice("/chosen"); | 49 | prom_chosen_node = prom_finddevice(prom_chosen_path); |
50 | if (!prom_chosen_node || prom_chosen_node == -1) | 50 | if (!prom_chosen_node || prom_chosen_node == -1) |
51 | prom_halt(); | 51 | prom_halt(); |
52 | 52 | ||
diff --git a/arch/sparc64/prom/map.S b/arch/sparc64/prom/map.S deleted file mode 100644 index 21b3f9c99ea7..000000000000 --- a/arch/sparc64/prom/map.S +++ /dev/null | |||
@@ -1,72 +0,0 @@ | |||
1 | /* $Id: map.S,v 1.2 1999/11/19 05:53:02 davem Exp $ | ||
2 | * map.S: Tricky coding required to fixup the kernel OBP maps | ||
3 | * properly. | ||
4 | * | ||
5 | * Copyright (C) 1999 David S. Miller (davem@redhat.com) | ||
6 | */ | ||
7 | |||
8 | .text | ||
9 | .align 8192 | ||
10 | .globl prom_boot_page | ||
11 | prom_boot_page: | ||
12 | call_method: | ||
13 | .asciz "call-method" | ||
14 | .align 8 | ||
15 | map: | ||
16 | .asciz "map" | ||
17 | .align 8 | ||
18 | |||
19 | /* When we are invoked, our caller has remapped us to | ||
20 | * page zero, therefore we must use PC relative addressing | ||
21 | * for everything after we begin performing the unmap/map | ||
22 | * calls. | ||
23 | */ | ||
24 | .globl prom_remap | ||
25 | prom_remap: /* %o0 = physpage, %o1 = virtpage, %o2 = mmu_ihandle */ | ||
26 | rd %pc, %g1 | ||
27 | srl %o2, 0, %o2 ! kill sign extension | ||
28 | sethi %hi(p1275buf), %g2 | ||
29 | or %g2, %lo(p1275buf), %g2 | ||
30 | ldx [%g2 + 0x10], %g3 ! prom_cif_stack | ||
31 | save %g3, -(192 + 128), %sp | ||
32 | ldx [%g2 + 0x08], %l0 ! prom_cif_handler | ||
33 | mov %g6, %i3 | ||
34 | mov %g4, %i4 | ||
35 | mov %g5, %i5 | ||
36 | flushw | ||
37 | |||
38 | sethi %hi(prom_remap - call_method), %g7 | ||
39 | or %g7, %lo(prom_remap - call_method), %g7 | ||
40 | sub %g1, %g7, %l2 ! call-method string | ||
41 | sethi %hi(prom_remap - map), %g7 | ||
42 | or %g7, %lo(prom_remap - map), %g7 | ||
43 | sub %g1, %g7, %l4 ! map string | ||
44 | |||
45 | /* OK, map the 4MB region we really live at. */ | ||
46 | stx %l2, [%sp + 2047 + 128 + 0x00] ! call-method | ||
47 | mov 7, %l5 | ||
48 | stx %l5, [%sp + 2047 + 128 + 0x08] ! num_args | ||
49 | mov 1, %l5 | ||
50 | stx %l5, [%sp + 2047 + 128 + 0x10] ! num_rets | ||
51 | stx %l4, [%sp + 2047 + 128 + 0x18] ! map | ||
52 | stx %i2, [%sp + 2047 + 128 + 0x20] ! mmu_ihandle | ||
53 | mov -1, %l5 | ||
54 | stx %l5, [%sp + 2047 + 128 + 0x28] ! mode == default | ||
55 | sethi %hi(4 * 1024 * 1024), %l5 | ||
56 | stx %l5, [%sp + 2047 + 128 + 0x30] ! size | ||
57 | stx %i1, [%sp + 2047 + 128 + 0x38] ! vaddr | ||
58 | stx %g0, [%sp + 2047 + 128 + 0x40] ! filler | ||
59 | stx %i0, [%sp + 2047 + 128 + 0x48] ! paddr | ||
60 | call %l0 | ||
61 | add %sp, (2047 + 128), %o0 ! argument array | ||
62 | |||
63 | /* Restore hard-coded globals. */ | ||
64 | mov %i3, %g6 | ||
65 | mov %i4, %g4 | ||
66 | mov %i5, %g5 | ||
67 | |||
68 | /* Wheee.... we are done. */ | ||
69 | ret | ||
70 | restore | ||
71 | |||
72 | .align 8192 | ||
diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c index 19c44e97e9ee..9b895faf077b 100644 --- a/arch/sparc64/prom/misc.c +++ b/arch/sparc64/prom/misc.c | |||
@@ -17,14 +17,14 @@ | |||
17 | #include <asm/system.h> | 17 | #include <asm/system.h> |
18 | 18 | ||
19 | /* Reset and reboot the machine with the command 'bcommand'. */ | 19 | /* Reset and reboot the machine with the command 'bcommand'. */ |
20 | void prom_reboot(char *bcommand) | 20 | void prom_reboot(const char *bcommand) |
21 | { | 21 | { |
22 | p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) | | 22 | p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) | |
23 | P1275_INOUT(1, 0), bcommand); | 23 | P1275_INOUT(1, 0), bcommand); |
24 | } | 24 | } |
25 | 25 | ||
26 | /* Forth evaluate the expression contained in 'fstring'. */ | 26 | /* Forth evaluate the expression contained in 'fstring'. */ |
27 | void prom_feval(char *fstring) | 27 | void prom_feval(const char *fstring) |
28 | { | 28 | { |
29 | if (!fstring || fstring[0] == 0) | 29 | if (!fstring || fstring[0] == 0) |
30 | return; | 30 | return; |
@@ -148,21 +148,19 @@ void prom_set_trap_table(unsigned long tba) | |||
148 | p1275_cmd("SUNW,set-trap-table", P1275_INOUT(1, 0), tba); | 148 | p1275_cmd("SUNW,set-trap-table", P1275_INOUT(1, 0), tba); |
149 | } | 149 | } |
150 | 150 | ||
151 | int mmu_ihandle_cache = 0; | ||
152 | |||
153 | int prom_get_mmu_ihandle(void) | 151 | int prom_get_mmu_ihandle(void) |
154 | { | 152 | { |
155 | int node, ret; | 153 | int node, ret; |
156 | 154 | ||
157 | if (mmu_ihandle_cache != 0) | 155 | if (prom_mmu_ihandle_cache != 0) |
158 | return mmu_ihandle_cache; | 156 | return prom_mmu_ihandle_cache; |
159 | 157 | ||
160 | node = prom_finddevice("/chosen"); | 158 | node = prom_finddevice(prom_chosen_path); |
161 | ret = prom_getint(node, "mmu"); | 159 | ret = prom_getint(node, prom_mmu_name); |
162 | if (ret == -1 || ret == 0) | 160 | if (ret == -1 || ret == 0) |
163 | mmu_ihandle_cache = -1; | 161 | prom_mmu_ihandle_cache = -1; |
164 | else | 162 | else |
165 | mmu_ihandle_cache = ret; | 163 | prom_mmu_ihandle_cache = ret; |
166 | 164 | ||
167 | return ret; | 165 | return ret; |
168 | } | 166 | } |
@@ -190,7 +188,7 @@ long prom_itlb_load(unsigned long index, | |||
190 | unsigned long tte_data, | 188 | unsigned long tte_data, |
191 | unsigned long vaddr) | 189 | unsigned long vaddr) |
192 | { | 190 | { |
193 | return p1275_cmd("call-method", | 191 | return p1275_cmd(prom_callmethod_name, |
194 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 192 | (P1275_ARG(0, P1275_ARG_IN_STRING) | |
195 | P1275_ARG(2, P1275_ARG_IN_64B) | | 193 | P1275_ARG(2, P1275_ARG_IN_64B) | |
196 | P1275_ARG(3, P1275_ARG_IN_64B) | | 194 | P1275_ARG(3, P1275_ARG_IN_64B) | |
@@ -207,7 +205,7 @@ long prom_dtlb_load(unsigned long index, | |||
207 | unsigned long tte_data, | 205 | unsigned long tte_data, |
208 | unsigned long vaddr) | 206 | unsigned long vaddr) |
209 | { | 207 | { |
210 | return p1275_cmd("call-method", | 208 | return p1275_cmd(prom_callmethod_name, |
211 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 209 | (P1275_ARG(0, P1275_ARG_IN_STRING) | |
212 | P1275_ARG(2, P1275_ARG_IN_64B) | | 210 | P1275_ARG(2, P1275_ARG_IN_64B) | |
213 | P1275_ARG(3, P1275_ARG_IN_64B) | | 211 | P1275_ARG(3, P1275_ARG_IN_64B) | |
@@ -223,13 +221,13 @@ long prom_dtlb_load(unsigned long index, | |||
223 | int prom_map(int mode, unsigned long size, | 221 | int prom_map(int mode, unsigned long size, |
224 | unsigned long vaddr, unsigned long paddr) | 222 | unsigned long vaddr, unsigned long paddr) |
225 | { | 223 | { |
226 | int ret = p1275_cmd("call-method", | 224 | int ret = p1275_cmd(prom_callmethod_name, |
227 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 225 | (P1275_ARG(0, P1275_ARG_IN_STRING) | |
228 | P1275_ARG(3, P1275_ARG_IN_64B) | | 226 | P1275_ARG(3, P1275_ARG_IN_64B) | |
229 | P1275_ARG(4, P1275_ARG_IN_64B) | | 227 | P1275_ARG(4, P1275_ARG_IN_64B) | |
230 | P1275_ARG(6, P1275_ARG_IN_64B) | | 228 | P1275_ARG(6, P1275_ARG_IN_64B) | |
231 | P1275_INOUT(7, 1)), | 229 | P1275_INOUT(7, 1)), |
232 | "map", | 230 | prom_map_name, |
233 | prom_get_mmu_ihandle(), | 231 | prom_get_mmu_ihandle(), |
234 | mode, | 232 | mode, |
235 | size, | 233 | size, |
@@ -244,12 +242,12 @@ int prom_map(int mode, unsigned long size, | |||
244 | 242 | ||
245 | void prom_unmap(unsigned long size, unsigned long vaddr) | 243 | void prom_unmap(unsigned long size, unsigned long vaddr) |
246 | { | 244 | { |
247 | p1275_cmd("call-method", | 245 | p1275_cmd(prom_callmethod_name, |
248 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 246 | (P1275_ARG(0, P1275_ARG_IN_STRING) | |
249 | P1275_ARG(2, P1275_ARG_IN_64B) | | 247 | P1275_ARG(2, P1275_ARG_IN_64B) | |
250 | P1275_ARG(3, P1275_ARG_IN_64B) | | 248 | P1275_ARG(3, P1275_ARG_IN_64B) | |
251 | P1275_INOUT(4, 0)), | 249 | P1275_INOUT(4, 0)), |
252 | "unmap", | 250 | prom_unmap_name, |
253 | prom_get_mmu_ihandle(), | 251 | prom_get_mmu_ihandle(), |
254 | size, | 252 | size, |
255 | vaddr); | 253 | vaddr); |
@@ -258,7 +256,7 @@ void prom_unmap(unsigned long size, unsigned long vaddr) | |||
258 | /* Set aside physical memory which is not touched or modified | 256 | /* Set aside physical memory which is not touched or modified |
259 | * across soft resets. | 257 | * across soft resets. |
260 | */ | 258 | */ |
261 | unsigned long prom_retain(char *name, | 259 | unsigned long prom_retain(const char *name, |
262 | unsigned long pa_low, unsigned long pa_high, | 260 | unsigned long pa_low, unsigned long pa_high, |
263 | long size, long align) | 261 | long size, long align) |
264 | { | 262 | { |
@@ -290,7 +288,7 @@ int prom_getunumber(int syndrome_code, | |||
290 | unsigned long phys_addr, | 288 | unsigned long phys_addr, |
291 | char *buf, int buflen) | 289 | char *buf, int buflen) |
292 | { | 290 | { |
293 | return p1275_cmd("call-method", | 291 | return p1275_cmd(prom_callmethod_name, |
294 | (P1275_ARG(0, P1275_ARG_IN_STRING) | | 292 | (P1275_ARG(0, P1275_ARG_IN_STRING) | |
295 | P1275_ARG(3, P1275_ARG_OUT_BUF) | | 293 | P1275_ARG(3, P1275_ARG_OUT_BUF) | |
296 | P1275_ARG(6, P1275_ARG_IN_64B) | | 294 | P1275_ARG(6, P1275_ARG_IN_64B) | |
diff --git a/arch/sparc64/prom/p1275.c b/arch/sparc64/prom/p1275.c index 59fe38bba39e..a5a7c5712028 100644 --- a/arch/sparc64/prom/p1275.c +++ b/arch/sparc64/prom/p1275.c | |||
@@ -46,7 +46,7 @@ static inline unsigned long spitfire_get_primary_context(void) | |||
46 | */ | 46 | */ |
47 | DEFINE_SPINLOCK(prom_entry_lock); | 47 | DEFINE_SPINLOCK(prom_entry_lock); |
48 | 48 | ||
49 | long p1275_cmd (char *service, long fmt, ...) | 49 | long p1275_cmd(const char *service, long fmt, ...) |
50 | { | 50 | { |
51 | char *p, *q; | 51 | char *p, *q; |
52 | unsigned long flags; | 52 | unsigned long flags; |
diff --git a/arch/sparc64/prom/printf.c b/arch/sparc64/prom/printf.c index a6df82cafa0d..660943ee4c2a 100644 --- a/arch/sparc64/prom/printf.c +++ b/arch/sparc64/prom/printf.c | |||
@@ -34,7 +34,7 @@ prom_write(const char *buf, unsigned int n) | |||
34 | } | 34 | } |
35 | 35 | ||
36 | void | 36 | void |
37 | prom_printf(char *fmt, ...) | 37 | prom_printf(const char *fmt, ...) |
38 | { | 38 | { |
39 | va_list args; | 39 | va_list args; |
40 | int i; | 40 | int i; |
diff --git a/arch/sparc64/prom/tree.c b/arch/sparc64/prom/tree.c index ccf73258ebf7..b1ff9e87dcc6 100644 --- a/arch/sparc64/prom/tree.c +++ b/arch/sparc64/prom/tree.c | |||
@@ -69,7 +69,7 @@ prom_getsibling(int node) | |||
69 | * Return -1 on error. | 69 | * Return -1 on error. |
70 | */ | 70 | */ |
71 | __inline__ int | 71 | __inline__ int |
72 | prom_getproplen(int node, char *prop) | 72 | prom_getproplen(int node, const char *prop) |
73 | { | 73 | { |
74 | if((!node) || (!prop)) return -1; | 74 | if((!node) || (!prop)) return -1; |
75 | return p1275_cmd ("getproplen", | 75 | return p1275_cmd ("getproplen", |
@@ -83,20 +83,20 @@ prom_getproplen(int node, char *prop) | |||
83 | * was successful the length will be returned, else -1 is returned. | 83 | * was successful the length will be returned, else -1 is returned. |
84 | */ | 84 | */ |
85 | __inline__ int | 85 | __inline__ int |
86 | prom_getproperty(int node, char *prop, char *buffer, int bufsize) | 86 | prom_getproperty(int node, const char *prop, char *buffer, int bufsize) |
87 | { | 87 | { |
88 | int plen; | 88 | int plen; |
89 | 89 | ||
90 | plen = prom_getproplen(node, prop); | 90 | plen = prom_getproplen(node, prop); |
91 | if((plen > bufsize) || (plen == 0) || (plen == -1)) | 91 | if ((plen > bufsize) || (plen == 0) || (plen == -1)) { |
92 | return -1; | 92 | return -1; |
93 | else { | 93 | } else { |
94 | /* Ok, things seem all right. */ | 94 | /* Ok, things seem all right. */ |
95 | return p1275_cmd ("getprop", | 95 | return p1275_cmd(prom_getprop_name, |
96 | P1275_ARG(1,P1275_ARG_IN_STRING)| | 96 | P1275_ARG(1,P1275_ARG_IN_STRING)| |
97 | P1275_ARG(2,P1275_ARG_OUT_BUF)| | 97 | P1275_ARG(2,P1275_ARG_OUT_BUF)| |
98 | P1275_INOUT(4, 1), | 98 | P1275_INOUT(4, 1), |
99 | node, prop, buffer, P1275_SIZE(plen)); | 99 | node, prop, buffer, P1275_SIZE(plen)); |
100 | } | 100 | } |
101 | } | 101 | } |
102 | 102 | ||
@@ -104,7 +104,7 @@ prom_getproperty(int node, char *prop, char *buffer, int bufsize) | |||
104 | * on failure. | 104 | * on failure. |
105 | */ | 105 | */ |
106 | __inline__ int | 106 | __inline__ int |
107 | prom_getint(int node, char *prop) | 107 | prom_getint(int node, const char *prop) |
108 | { | 108 | { |
109 | int intprop; | 109 | int intprop; |
110 | 110 | ||
@@ -119,7 +119,7 @@ prom_getint(int node, char *prop) | |||
119 | */ | 119 | */ |
120 | 120 | ||
121 | int | 121 | int |
122 | prom_getintdefault(int node, char *property, int deflt) | 122 | prom_getintdefault(int node, const char *property, int deflt) |
123 | { | 123 | { |
124 | int retval; | 124 | int retval; |
125 | 125 | ||
@@ -131,7 +131,7 @@ prom_getintdefault(int node, char *property, int deflt) | |||
131 | 131 | ||
132 | /* Acquire a boolean property, 1=TRUE 0=FALSE. */ | 132 | /* Acquire a boolean property, 1=TRUE 0=FALSE. */ |
133 | int | 133 | int |
134 | prom_getbool(int node, char *prop) | 134 | prom_getbool(int node, const char *prop) |
135 | { | 135 | { |
136 | int retval; | 136 | int retval; |
137 | 137 | ||
@@ -145,7 +145,7 @@ prom_getbool(int node, char *prop) | |||
145 | * buffer. | 145 | * buffer. |
146 | */ | 146 | */ |
147 | void | 147 | void |
148 | prom_getstring(int node, char *prop, char *user_buf, int ubuf_size) | 148 | prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size) |
149 | { | 149 | { |
150 | int len; | 150 | int len; |
151 | 151 | ||
@@ -160,7 +160,7 @@ prom_getstring(int node, char *prop, char *user_buf, int ubuf_size) | |||
160 | * YES = 1 NO = 0 | 160 | * YES = 1 NO = 0 |
161 | */ | 161 | */ |
162 | int | 162 | int |
163 | prom_nodematch(int node, char *name) | 163 | prom_nodematch(int node, const char *name) |
164 | { | 164 | { |
165 | char namebuf[128]; | 165 | char namebuf[128]; |
166 | prom_getproperty(node, "name", namebuf, sizeof(namebuf)); | 166 | prom_getproperty(node, "name", namebuf, sizeof(namebuf)); |
@@ -172,7 +172,7 @@ prom_nodematch(int node, char *name) | |||
172 | * 'nodename'. Return node if successful, zero if not. | 172 | * 'nodename'. Return node if successful, zero if not. |
173 | */ | 173 | */ |
174 | int | 174 | int |
175 | prom_searchsiblings(int node_start, char *nodename) | 175 | prom_searchsiblings(int node_start, const char *nodename) |
176 | { | 176 | { |
177 | 177 | ||
178 | int thisnode, error; | 178 | int thisnode, error; |
@@ -294,7 +294,7 @@ prom_firstprop(int node, char *buffer) | |||
294 | * property types for this node. | 294 | * property types for this node. |
295 | */ | 295 | */ |
296 | __inline__ char * | 296 | __inline__ char * |
297 | prom_nextprop(int node, char *oprop, char *buffer) | 297 | prom_nextprop(int node, const char *oprop, char *buffer) |
298 | { | 298 | { |
299 | char buf[32]; | 299 | char buf[32]; |
300 | 300 | ||
@@ -314,15 +314,17 @@ prom_nextprop(int node, char *oprop, char *buffer) | |||
314 | } | 314 | } |
315 | 315 | ||
316 | int | 316 | int |
317 | prom_finddevice(char *name) | 317 | prom_finddevice(const char *name) |
318 | { | 318 | { |
319 | if(!name) return 0; | 319 | if (!name) |
320 | return p1275_cmd ("finddevice", P1275_ARG(0,P1275_ARG_IN_STRING)| | 320 | return 0; |
321 | P1275_INOUT(1, 1), | 321 | return p1275_cmd(prom_finddev_name, |
322 | name); | 322 | P1275_ARG(0,P1275_ARG_IN_STRING)| |
323 | P1275_INOUT(1, 1), | ||
324 | name); | ||
323 | } | 325 | } |
324 | 326 | ||
325 | int prom_node_has_property(int node, char *prop) | 327 | int prom_node_has_property(int node, const char *prop) |
326 | { | 328 | { |
327 | char buf [32]; | 329 | char buf [32]; |
328 | 330 | ||
@@ -339,7 +341,7 @@ int prom_node_has_property(int node, char *prop) | |||
339 | * of 'size' bytes. Return the number of bytes the prom accepted. | 341 | * of 'size' bytes. Return the number of bytes the prom accepted. |
340 | */ | 342 | */ |
341 | int | 343 | int |
342 | prom_setprop(int node, char *pname, char *value, int size) | 344 | prom_setprop(int node, const char *pname, char *value, int size) |
343 | { | 345 | { |
344 | if(size == 0) return 0; | 346 | if(size == 0) return 0; |
345 | if((pname == 0) || (value == 0)) return 0; | 347 | if((pname == 0) || (value == 0)) return 0; |
@@ -364,7 +366,7 @@ prom_inst2pkg(int inst) | |||
364 | * FIXME: Should work for v0 as well | 366 | * FIXME: Should work for v0 as well |
365 | */ | 367 | */ |
366 | int | 368 | int |
367 | prom_pathtoinode(char *path) | 369 | prom_pathtoinode(const char *path) |
368 | { | 370 | { |
369 | int node, inst; | 371 | int node, inst; |
370 | 372 | ||
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 2373cb8b8625..703acde2a1a5 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c | |||
@@ -959,9 +959,6 @@ static __init int unsynchronized_tsc(void) | |||
959 | are handled in the OEM check above. */ | 959 | are handled in the OEM check above. */ |
960 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) | 960 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) |
961 | return 0; | 961 | return 0; |
962 | /* All in a single socket - should be synchronized */ | ||
963 | if (cpus_weight(cpu_core_map[0]) == num_online_cpus()) | ||
964 | return 0; | ||
965 | #endif | 962 | #endif |
966 | /* Assume multi socket systems are not synchronized */ | 963 | /* Assume multi socket systems are not synchronized */ |
967 | return num_online_cpus() > 1; | 964 | return num_online_cpus() > 1; |
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c index e82a96ba396b..f66947722e12 100644 --- a/drivers/char/ipmi/ipmi_poweroff.c +++ b/drivers/char/ipmi/ipmi_poweroff.c | |||
@@ -55,7 +55,7 @@ extern void (*pm_power_off)(void); | |||
55 | static int poweroff_powercycle; | 55 | static int poweroff_powercycle; |
56 | 56 | ||
57 | /* parameter definition to allow user to flag power cycle */ | 57 | /* parameter definition to allow user to flag power cycle */ |
58 | module_param(poweroff_powercycle, int, 0); | 58 | module_param(poweroff_powercycle, int, 0644); |
59 | MODULE_PARM_DESC(poweroff_powercycles, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down."); | 59 | MODULE_PARM_DESC(poweroff_powercycles, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down."); |
60 | 60 | ||
61 | /* Stuff from the get device id command. */ | 61 | /* Stuff from the get device id command. */ |
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c index 966632182e2d..9f2f00d82917 100644 --- a/drivers/connector/cn_queue.c +++ b/drivers/connector/cn_queue.c | |||
@@ -31,16 +31,19 @@ | |||
31 | #include <linux/connector.h> | 31 | #include <linux/connector.h> |
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | 33 | ||
34 | static void cn_queue_wrapper(void *data) | 34 | void cn_queue_wrapper(void *data) |
35 | { | 35 | { |
36 | struct cn_callback_entry *cbq = data; | 36 | struct cn_callback_data *d = data; |
37 | 37 | ||
38 | cbq->cb->callback(cbq->cb->priv); | 38 | d->callback(d->callback_priv); |
39 | cbq->destruct_data(cbq->ddata); | 39 | |
40 | cbq->ddata = NULL; | 40 | d->destruct_data(d->ddata); |
41 | d->ddata = NULL; | ||
42 | |||
43 | kfree(d->free); | ||
41 | } | 44 | } |
42 | 45 | ||
43 | static struct cn_callback_entry *cn_queue_alloc_callback_entry(struct cn_callback *cb) | 46 | static struct cn_callback_entry *cn_queue_alloc_callback_entry(char *name, struct cb_id *id, void (*callback)(void *)) |
44 | { | 47 | { |
45 | struct cn_callback_entry *cbq; | 48 | struct cn_callback_entry *cbq; |
46 | 49 | ||
@@ -50,8 +53,11 @@ static struct cn_callback_entry *cn_queue_alloc_callback_entry(struct cn_callbac | |||
50 | return NULL; | 53 | return NULL; |
51 | } | 54 | } |
52 | 55 | ||
53 | cbq->cb = cb; | 56 | snprintf(cbq->id.name, sizeof(cbq->id.name), "%s", name); |
54 | INIT_WORK(&cbq->work, &cn_queue_wrapper, cbq); | 57 | memcpy(&cbq->id.id, id, sizeof(struct cb_id)); |
58 | cbq->data.callback = callback; | ||
59 | |||
60 | INIT_WORK(&cbq->work, &cn_queue_wrapper, &cbq->data); | ||
55 | return cbq; | 61 | return cbq; |
56 | } | 62 | } |
57 | 63 | ||
@@ -68,12 +74,12 @@ int cn_cb_equal(struct cb_id *i1, struct cb_id *i2) | |||
68 | return ((i1->idx == i2->idx) && (i1->val == i2->val)); | 74 | return ((i1->idx == i2->idx) && (i1->val == i2->val)); |
69 | } | 75 | } |
70 | 76 | ||
71 | int cn_queue_add_callback(struct cn_queue_dev *dev, struct cn_callback *cb) | 77 | int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(void *)) |
72 | { | 78 | { |
73 | struct cn_callback_entry *cbq, *__cbq; | 79 | struct cn_callback_entry *cbq, *__cbq; |
74 | int found = 0; | 80 | int found = 0; |
75 | 81 | ||
76 | cbq = cn_queue_alloc_callback_entry(cb); | 82 | cbq = cn_queue_alloc_callback_entry(name, id, callback); |
77 | if (!cbq) | 83 | if (!cbq) |
78 | return -ENOMEM; | 84 | return -ENOMEM; |
79 | 85 | ||
@@ -82,7 +88,7 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, struct cn_callback *cb) | |||
82 | 88 | ||
83 | spin_lock_bh(&dev->queue_lock); | 89 | spin_lock_bh(&dev->queue_lock); |
84 | list_for_each_entry(__cbq, &dev->queue_list, callback_entry) { | 90 | list_for_each_entry(__cbq, &dev->queue_list, callback_entry) { |
85 | if (cn_cb_equal(&__cbq->cb->id, &cb->id)) { | 91 | if (cn_cb_equal(&__cbq->id.id, id)) { |
86 | found = 1; | 92 | found = 1; |
87 | break; | 93 | break; |
88 | } | 94 | } |
@@ -99,7 +105,7 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, struct cn_callback *cb) | |||
99 | 105 | ||
100 | cbq->nls = dev->nls; | 106 | cbq->nls = dev->nls; |
101 | cbq->seq = 0; | 107 | cbq->seq = 0; |
102 | cbq->group = cbq->cb->id.idx; | 108 | cbq->group = cbq->id.id.idx; |
103 | 109 | ||
104 | return 0; | 110 | return 0; |
105 | } | 111 | } |
@@ -111,7 +117,7 @@ void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id) | |||
111 | 117 | ||
112 | spin_lock_bh(&dev->queue_lock); | 118 | spin_lock_bh(&dev->queue_lock); |
113 | list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry) { | 119 | list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry) { |
114 | if (cn_cb_equal(&cbq->cb->id, id)) { | 120 | if (cn_cb_equal(&cbq->id.id, id)) { |
115 | list_del(&cbq->callback_entry); | 121 | list_del(&cbq->callback_entry); |
116 | found = 1; | 122 | found = 1; |
117 | break; | 123 | break; |
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index aaf6d468a8b9..bb0b3a8de14b 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c | |||
@@ -84,7 +84,7 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, int gfp_mask) | |||
84 | spin_lock_bh(&dev->cbdev->queue_lock); | 84 | spin_lock_bh(&dev->cbdev->queue_lock); |
85 | list_for_each_entry(__cbq, &dev->cbdev->queue_list, | 85 | list_for_each_entry(__cbq, &dev->cbdev->queue_list, |
86 | callback_entry) { | 86 | callback_entry) { |
87 | if (cn_cb_equal(&__cbq->cb->id, &msg->id)) { | 87 | if (cn_cb_equal(&__cbq->id.id, &msg->id)) { |
88 | found = 1; | 88 | found = 1; |
89 | group = __cbq->group; | 89 | group = __cbq->group; |
90 | } | 90 | } |
@@ -127,42 +127,56 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v | |||
127 | { | 127 | { |
128 | struct cn_callback_entry *__cbq; | 128 | struct cn_callback_entry *__cbq; |
129 | struct cn_dev *dev = &cdev; | 129 | struct cn_dev *dev = &cdev; |
130 | int found = 0; | 130 | int err = -ENODEV; |
131 | 131 | ||
132 | spin_lock_bh(&dev->cbdev->queue_lock); | 132 | spin_lock_bh(&dev->cbdev->queue_lock); |
133 | list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) { | 133 | list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) { |
134 | if (cn_cb_equal(&__cbq->cb->id, &msg->id)) { | 134 | if (cn_cb_equal(&__cbq->id.id, &msg->id)) { |
135 | /* | ||
136 | * Let's scream if there is some magic and the | ||
137 | * data will arrive asynchronously here. | ||
138 | * [i.e. netlink messages will be queued]. | ||
139 | * After the first warning I will fix it | ||
140 | * quickly, but now I think it is | ||
141 | * impossible. --zbr (2004_04_27). | ||
142 | */ | ||
143 | if (likely(!test_bit(0, &__cbq->work.pending) && | 135 | if (likely(!test_bit(0, &__cbq->work.pending) && |
144 | __cbq->ddata == NULL)) { | 136 | __cbq->data.ddata == NULL)) { |
145 | __cbq->cb->priv = msg; | 137 | __cbq->data.callback_priv = msg; |
146 | 138 | ||
147 | __cbq->ddata = data; | 139 | __cbq->data.ddata = data; |
148 | __cbq->destruct_data = destruct_data; | 140 | __cbq->data.destruct_data = destruct_data; |
149 | 141 | ||
150 | if (queue_work(dev->cbdev->cn_queue, | 142 | if (queue_work(dev->cbdev->cn_queue, |
151 | &__cbq->work)) | 143 | &__cbq->work)) |
152 | found = 1; | 144 | err = 0; |
153 | } else { | 145 | } else { |
154 | printk("%s: cbq->data=%p, " | 146 | struct work_struct *w; |
155 | "work->pending=%08lx.\n", | 147 | struct cn_callback_data *d; |
156 | __func__, __cbq->ddata, | 148 | |
157 | __cbq->work.pending); | 149 | w = kzalloc(sizeof(*w) + sizeof(*d), GFP_ATOMIC); |
158 | WARN_ON(1); | 150 | if (w) { |
151 | d = (struct cn_callback_data *)(w+1); | ||
152 | |||
153 | d->callback_priv = msg; | ||
154 | d->callback = __cbq->data.callback; | ||
155 | d->ddata = data; | ||
156 | d->destruct_data = destruct_data; | ||
157 | d->free = w; | ||
158 | |||
159 | INIT_LIST_HEAD(&w->entry); | ||
160 | w->pending = 0; | ||
161 | w->func = &cn_queue_wrapper; | ||
162 | w->data = d; | ||
163 | init_timer(&w->timer); | ||
164 | |||
165 | if (queue_work(dev->cbdev->cn_queue, w)) | ||
166 | err = 0; | ||
167 | else { | ||
168 | kfree(w); | ||
169 | err = -EINVAL; | ||
170 | } | ||
171 | } else | ||
172 | err = -ENOMEM; | ||
159 | } | 173 | } |
160 | break; | 174 | break; |
161 | } | 175 | } |
162 | } | 176 | } |
163 | spin_unlock_bh(&dev->cbdev->queue_lock); | 177 | spin_unlock_bh(&dev->cbdev->queue_lock); |
164 | 178 | ||
165 | return found ? 0 : -ENODEV; | 179 | return err; |
166 | } | 180 | } |
167 | 181 | ||
168 | /* | 182 | /* |
@@ -291,22 +305,10 @@ int cn_add_callback(struct cb_id *id, char *name, void (*callback)(void *)) | |||
291 | { | 305 | { |
292 | int err; | 306 | int err; |
293 | struct cn_dev *dev = &cdev; | 307 | struct cn_dev *dev = &cdev; |
294 | struct cn_callback *cb; | ||
295 | |||
296 | cb = kzalloc(sizeof(*cb), GFP_KERNEL); | ||
297 | if (!cb) | ||
298 | return -ENOMEM; | ||
299 | |||
300 | scnprintf(cb->name, sizeof(cb->name), "%s", name); | ||
301 | 308 | ||
302 | memcpy(&cb->id, id, sizeof(cb->id)); | 309 | err = cn_queue_add_callback(dev->cbdev, name, id, callback); |
303 | cb->callback = callback; | 310 | if (err) |
304 | |||
305 | err = cn_queue_add_callback(dev->cbdev, cb); | ||
306 | if (err) { | ||
307 | kfree(cb); | ||
308 | return err; | 311 | return err; |
309 | } | ||
310 | 312 | ||
311 | cn_notify(id, 0); | 313 | cn_notify(id, 0); |
312 | 314 | ||
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 0ccf85fcee34..a35a58bef1a4 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c | |||
@@ -477,7 +477,7 @@ static struct pcmcia_device_id ide_ids[] = { | |||
477 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149), | 477 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149), |
478 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674), | 478 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674), |
479 | PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b), | 479 | PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b), |
480 | PCMCIA_DEVICE_PROD_ID12(" ", "NinjaATA-", 0x3b6e20c8, 0xebe0bd79), | 480 | PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79), |
481 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591), | 481 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591), |
482 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728), | 482 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728), |
483 | PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1), | 483 | PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1), |
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index b1897bed14ad..cc124344dd2c 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -69,6 +69,7 @@ struct ib_uverbs_event_file { | |||
69 | 69 | ||
70 | struct ib_uverbs_file { | 70 | struct ib_uverbs_file { |
71 | struct kref ref; | 71 | struct kref ref; |
72 | struct semaphore mutex; | ||
72 | struct ib_uverbs_device *device; | 73 | struct ib_uverbs_device *device; |
73 | struct ib_ucontext *ucontext; | 74 | struct ib_ucontext *ucontext; |
74 | struct ib_event_handler event_handler; | 75 | struct ib_event_handler event_handler; |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index e91ebde46481..562445165d2b 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -76,8 +76,9 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, | |||
76 | struct ib_uverbs_get_context_resp resp; | 76 | struct ib_uverbs_get_context_resp resp; |
77 | struct ib_udata udata; | 77 | struct ib_udata udata; |
78 | struct ib_device *ibdev = file->device->ib_dev; | 78 | struct ib_device *ibdev = file->device->ib_dev; |
79 | struct ib_ucontext *ucontext; | ||
79 | int i; | 80 | int i; |
80 | int ret = in_len; | 81 | int ret; |
81 | 82 | ||
82 | if (out_len < sizeof resp) | 83 | if (out_len < sizeof resp) |
83 | return -ENOSPC; | 84 | return -ENOSPC; |
@@ -85,45 +86,56 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, | |||
85 | if (copy_from_user(&cmd, buf, sizeof cmd)) | 86 | if (copy_from_user(&cmd, buf, sizeof cmd)) |
86 | return -EFAULT; | 87 | return -EFAULT; |
87 | 88 | ||
89 | down(&file->mutex); | ||
90 | |||
91 | if (file->ucontext) { | ||
92 | ret = -EINVAL; | ||
93 | goto err; | ||
94 | } | ||
95 | |||
88 | INIT_UDATA(&udata, buf + sizeof cmd, | 96 | INIT_UDATA(&udata, buf + sizeof cmd, |
89 | (unsigned long) cmd.response + sizeof resp, | 97 | (unsigned long) cmd.response + sizeof resp, |
90 | in_len - sizeof cmd, out_len - sizeof resp); | 98 | in_len - sizeof cmd, out_len - sizeof resp); |
91 | 99 | ||
92 | file->ucontext = ibdev->alloc_ucontext(ibdev, &udata); | 100 | ucontext = ibdev->alloc_ucontext(ibdev, &udata); |
93 | if (IS_ERR(file->ucontext)) { | 101 | if (IS_ERR(ucontext)) |
94 | ret = PTR_ERR(file->ucontext); | 102 | return PTR_ERR(file->ucontext); |
95 | file->ucontext = NULL; | ||
96 | return ret; | ||
97 | } | ||
98 | 103 | ||
99 | file->ucontext->device = ibdev; | 104 | ucontext->device = ibdev; |
100 | INIT_LIST_HEAD(&file->ucontext->pd_list); | 105 | INIT_LIST_HEAD(&ucontext->pd_list); |
101 | INIT_LIST_HEAD(&file->ucontext->mr_list); | 106 | INIT_LIST_HEAD(&ucontext->mr_list); |
102 | INIT_LIST_HEAD(&file->ucontext->mw_list); | 107 | INIT_LIST_HEAD(&ucontext->mw_list); |
103 | INIT_LIST_HEAD(&file->ucontext->cq_list); | 108 | INIT_LIST_HEAD(&ucontext->cq_list); |
104 | INIT_LIST_HEAD(&file->ucontext->qp_list); | 109 | INIT_LIST_HEAD(&ucontext->qp_list); |
105 | INIT_LIST_HEAD(&file->ucontext->srq_list); | 110 | INIT_LIST_HEAD(&ucontext->srq_list); |
106 | INIT_LIST_HEAD(&file->ucontext->ah_list); | 111 | INIT_LIST_HEAD(&ucontext->ah_list); |
107 | spin_lock_init(&file->ucontext->lock); | ||
108 | 112 | ||
109 | resp.async_fd = file->async_file.fd; | 113 | resp.async_fd = file->async_file.fd; |
110 | for (i = 0; i < file->device->num_comp; ++i) | 114 | for (i = 0; i < file->device->num_comp; ++i) |
111 | if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab + | 115 | if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab + |
112 | i * sizeof (__u32), | 116 | i * sizeof (__u32), |
113 | &file->comp_file[i].fd, sizeof (__u32))) | 117 | &file->comp_file[i].fd, sizeof (__u32))) { |
114 | goto err; | 118 | ret = -EFAULT; |
119 | goto err_free; | ||
120 | } | ||
115 | 121 | ||
116 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 122 | if (copy_to_user((void __user *) (unsigned long) cmd.response, |
117 | &resp, sizeof resp)) | 123 | &resp, sizeof resp)) { |
118 | goto err; | 124 | ret = -EFAULT; |
125 | goto err_free; | ||
126 | } | ||
127 | |||
128 | file->ucontext = ucontext; | ||
129 | up(&file->mutex); | ||
119 | 130 | ||
120 | return in_len; | 131 | return in_len; |
121 | 132 | ||
122 | err: | 133 | err_free: |
123 | ibdev->dealloc_ucontext(file->ucontext); | 134 | ibdev->dealloc_ucontext(ucontext); |
124 | file->ucontext = NULL; | ||
125 | 135 | ||
126 | return -EFAULT; | 136 | err: |
137 | up(&file->mutex); | ||
138 | return ret; | ||
127 | } | 139 | } |
128 | 140 | ||
129 | ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file, | 141 | ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file, |
@@ -352,9 +364,9 @@ retry: | |||
352 | if (ret) | 364 | if (ret) |
353 | goto err_pd; | 365 | goto err_pd; |
354 | 366 | ||
355 | spin_lock_irq(&file->ucontext->lock); | 367 | down(&file->mutex); |
356 | list_add_tail(&uobj->list, &file->ucontext->pd_list); | 368 | list_add_tail(&uobj->list, &file->ucontext->pd_list); |
357 | spin_unlock_irq(&file->ucontext->lock); | 369 | up(&file->mutex); |
358 | 370 | ||
359 | memset(&resp, 0, sizeof resp); | 371 | memset(&resp, 0, sizeof resp); |
360 | resp.pd_handle = uobj->id; | 372 | resp.pd_handle = uobj->id; |
@@ -368,9 +380,9 @@ retry: | |||
368 | return in_len; | 380 | return in_len; |
369 | 381 | ||
370 | err_list: | 382 | err_list: |
371 | spin_lock_irq(&file->ucontext->lock); | 383 | down(&file->mutex); |
372 | list_del(&uobj->list); | 384 | list_del(&uobj->list); |
373 | spin_unlock_irq(&file->ucontext->lock); | 385 | up(&file->mutex); |
374 | 386 | ||
375 | down(&ib_uverbs_idr_mutex); | 387 | down(&ib_uverbs_idr_mutex); |
376 | idr_remove(&ib_uverbs_pd_idr, uobj->id); | 388 | idr_remove(&ib_uverbs_pd_idr, uobj->id); |
@@ -410,9 +422,9 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file, | |||
410 | 422 | ||
411 | idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle); | 423 | idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle); |
412 | 424 | ||
413 | spin_lock_irq(&file->ucontext->lock); | 425 | down(&file->mutex); |
414 | list_del(&uobj->list); | 426 | list_del(&uobj->list); |
415 | spin_unlock_irq(&file->ucontext->lock); | 427 | up(&file->mutex); |
416 | 428 | ||
417 | kfree(uobj); | 429 | kfree(uobj); |
418 | 430 | ||
@@ -512,9 +524,9 @@ retry: | |||
512 | 524 | ||
513 | resp.mr_handle = obj->uobject.id; | 525 | resp.mr_handle = obj->uobject.id; |
514 | 526 | ||
515 | spin_lock_irq(&file->ucontext->lock); | 527 | down(&file->mutex); |
516 | list_add_tail(&obj->uobject.list, &file->ucontext->mr_list); | 528 | list_add_tail(&obj->uobject.list, &file->ucontext->mr_list); |
517 | spin_unlock_irq(&file->ucontext->lock); | 529 | up(&file->mutex); |
518 | 530 | ||
519 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 531 | if (copy_to_user((void __user *) (unsigned long) cmd.response, |
520 | &resp, sizeof resp)) { | 532 | &resp, sizeof resp)) { |
@@ -527,9 +539,9 @@ retry: | |||
527 | return in_len; | 539 | return in_len; |
528 | 540 | ||
529 | err_list: | 541 | err_list: |
530 | spin_lock_irq(&file->ucontext->lock); | 542 | down(&file->mutex); |
531 | list_del(&obj->uobject.list); | 543 | list_del(&obj->uobject.list); |
532 | spin_unlock_irq(&file->ucontext->lock); | 544 | up(&file->mutex); |
533 | 545 | ||
534 | err_unreg: | 546 | err_unreg: |
535 | ib_dereg_mr(mr); | 547 | ib_dereg_mr(mr); |
@@ -570,9 +582,9 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file, | |||
570 | 582 | ||
571 | idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle); | 583 | idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle); |
572 | 584 | ||
573 | spin_lock_irq(&file->ucontext->lock); | 585 | down(&file->mutex); |
574 | list_del(&memobj->uobject.list); | 586 | list_del(&memobj->uobject.list); |
575 | spin_unlock_irq(&file->ucontext->lock); | 587 | up(&file->mutex); |
576 | 588 | ||
577 | ib_umem_release(file->device->ib_dev, &memobj->umem); | 589 | ib_umem_release(file->device->ib_dev, &memobj->umem); |
578 | kfree(memobj); | 590 | kfree(memobj); |
@@ -647,9 +659,9 @@ retry: | |||
647 | if (ret) | 659 | if (ret) |
648 | goto err_cq; | 660 | goto err_cq; |
649 | 661 | ||
650 | spin_lock_irq(&file->ucontext->lock); | 662 | down(&file->mutex); |
651 | list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list); | 663 | list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list); |
652 | spin_unlock_irq(&file->ucontext->lock); | 664 | up(&file->mutex); |
653 | 665 | ||
654 | memset(&resp, 0, sizeof resp); | 666 | memset(&resp, 0, sizeof resp); |
655 | resp.cq_handle = uobj->uobject.id; | 667 | resp.cq_handle = uobj->uobject.id; |
@@ -664,9 +676,9 @@ retry: | |||
664 | return in_len; | 676 | return in_len; |
665 | 677 | ||
666 | err_list: | 678 | err_list: |
667 | spin_lock_irq(&file->ucontext->lock); | 679 | down(&file->mutex); |
668 | list_del(&uobj->uobject.list); | 680 | list_del(&uobj->uobject.list); |
669 | spin_unlock_irq(&file->ucontext->lock); | 681 | up(&file->mutex); |
670 | 682 | ||
671 | down(&ib_uverbs_idr_mutex); | 683 | down(&ib_uverbs_idr_mutex); |
672 | idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id); | 684 | idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id); |
@@ -712,9 +724,9 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, | |||
712 | 724 | ||
713 | idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle); | 725 | idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle); |
714 | 726 | ||
715 | spin_lock_irq(&file->ucontext->lock); | 727 | down(&file->mutex); |
716 | list_del(&uobj->uobject.list); | 728 | list_del(&uobj->uobject.list); |
717 | spin_unlock_irq(&file->ucontext->lock); | 729 | up(&file->mutex); |
718 | 730 | ||
719 | spin_lock_irq(&file->comp_file[0].lock); | 731 | spin_lock_irq(&file->comp_file[0].lock); |
720 | list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) { | 732 | list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) { |
@@ -847,9 +859,9 @@ retry: | |||
847 | 859 | ||
848 | resp.qp_handle = uobj->uobject.id; | 860 | resp.qp_handle = uobj->uobject.id; |
849 | 861 | ||
850 | spin_lock_irq(&file->ucontext->lock); | 862 | down(&file->mutex); |
851 | list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list); | 863 | list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list); |
852 | spin_unlock_irq(&file->ucontext->lock); | 864 | up(&file->mutex); |
853 | 865 | ||
854 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 866 | if (copy_to_user((void __user *) (unsigned long) cmd.response, |
855 | &resp, sizeof resp)) { | 867 | &resp, sizeof resp)) { |
@@ -862,9 +874,9 @@ retry: | |||
862 | return in_len; | 874 | return in_len; |
863 | 875 | ||
864 | err_list: | 876 | err_list: |
865 | spin_lock_irq(&file->ucontext->lock); | 877 | down(&file->mutex); |
866 | list_del(&uobj->uobject.list); | 878 | list_del(&uobj->uobject.list); |
867 | spin_unlock_irq(&file->ucontext->lock); | 879 | up(&file->mutex); |
868 | 880 | ||
869 | err_destroy: | 881 | err_destroy: |
870 | ib_destroy_qp(qp); | 882 | ib_destroy_qp(qp); |
@@ -989,9 +1001,9 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, | |||
989 | 1001 | ||
990 | idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle); | 1002 | idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle); |
991 | 1003 | ||
992 | spin_lock_irq(&file->ucontext->lock); | 1004 | down(&file->mutex); |
993 | list_del(&uobj->uobject.list); | 1005 | list_del(&uobj->uobject.list); |
994 | spin_unlock_irq(&file->ucontext->lock); | 1006 | up(&file->mutex); |
995 | 1007 | ||
996 | spin_lock_irq(&file->async_file.lock); | 1008 | spin_lock_irq(&file->async_file.lock); |
997 | list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { | 1009 | list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { |
@@ -1136,9 +1148,9 @@ retry: | |||
1136 | 1148 | ||
1137 | resp.srq_handle = uobj->uobject.id; | 1149 | resp.srq_handle = uobj->uobject.id; |
1138 | 1150 | ||
1139 | spin_lock_irq(&file->ucontext->lock); | 1151 | down(&file->mutex); |
1140 | list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list); | 1152 | list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list); |
1141 | spin_unlock_irq(&file->ucontext->lock); | 1153 | up(&file->mutex); |
1142 | 1154 | ||
1143 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 1155 | if (copy_to_user((void __user *) (unsigned long) cmd.response, |
1144 | &resp, sizeof resp)) { | 1156 | &resp, sizeof resp)) { |
@@ -1151,9 +1163,9 @@ retry: | |||
1151 | return in_len; | 1163 | return in_len; |
1152 | 1164 | ||
1153 | err_list: | 1165 | err_list: |
1154 | spin_lock_irq(&file->ucontext->lock); | 1166 | down(&file->mutex); |
1155 | list_del(&uobj->uobject.list); | 1167 | list_del(&uobj->uobject.list); |
1156 | spin_unlock_irq(&file->ucontext->lock); | 1168 | up(&file->mutex); |
1157 | 1169 | ||
1158 | err_destroy: | 1170 | err_destroy: |
1159 | ib_destroy_srq(srq); | 1171 | ib_destroy_srq(srq); |
@@ -1227,9 +1239,9 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, | |||
1227 | 1239 | ||
1228 | idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle); | 1240 | idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle); |
1229 | 1241 | ||
1230 | spin_lock_irq(&file->ucontext->lock); | 1242 | down(&file->mutex); |
1231 | list_del(&uobj->uobject.list); | 1243 | list_del(&uobj->uobject.list); |
1232 | spin_unlock_irq(&file->ucontext->lock); | 1244 | up(&file->mutex); |
1233 | 1245 | ||
1234 | spin_lock_irq(&file->async_file.lock); | 1246 | spin_lock_irq(&file->async_file.lock); |
1235 | list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { | 1247 | list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) { |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index ce5bdb7af306..12511808de21 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -448,7 +448,9 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, | |||
448 | if (hdr.in_words * 4 != count) | 448 | if (hdr.in_words * 4 != count) |
449 | return -EINVAL; | 449 | return -EINVAL; |
450 | 450 | ||
451 | if (hdr.command < 0 || hdr.command >= ARRAY_SIZE(uverbs_cmd_table)) | 451 | if (hdr.command < 0 || |
452 | hdr.command >= ARRAY_SIZE(uverbs_cmd_table) || | ||
453 | !uverbs_cmd_table[hdr.command]) | ||
452 | return -EINVAL; | 454 | return -EINVAL; |
453 | 455 | ||
454 | if (!file->ucontext && | 456 | if (!file->ucontext && |
@@ -484,27 +486,29 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) | |||
484 | file = kmalloc(sizeof *file + | 486 | file = kmalloc(sizeof *file + |
485 | (dev->num_comp - 1) * sizeof (struct ib_uverbs_event_file), | 487 | (dev->num_comp - 1) * sizeof (struct ib_uverbs_event_file), |
486 | GFP_KERNEL); | 488 | GFP_KERNEL); |
487 | if (!file) | 489 | if (!file) { |
488 | return -ENOMEM; | 490 | ret = -ENOMEM; |
491 | goto err; | ||
492 | } | ||
489 | 493 | ||
490 | file->device = dev; | 494 | file->device = dev; |
491 | kref_init(&file->ref); | 495 | kref_init(&file->ref); |
496 | init_MUTEX(&file->mutex); | ||
492 | 497 | ||
493 | file->ucontext = NULL; | 498 | file->ucontext = NULL; |
494 | 499 | ||
500 | kref_get(&file->ref); | ||
495 | ret = ib_uverbs_event_init(&file->async_file, file); | 501 | ret = ib_uverbs_event_init(&file->async_file, file); |
496 | if (ret) | 502 | if (ret) |
497 | goto err; | 503 | goto err_kref; |
498 | 504 | ||
499 | file->async_file.is_async = 1; | 505 | file->async_file.is_async = 1; |
500 | 506 | ||
501 | kref_get(&file->ref); | ||
502 | |||
503 | for (i = 0; i < dev->num_comp; ++i) { | 507 | for (i = 0; i < dev->num_comp; ++i) { |
508 | kref_get(&file->ref); | ||
504 | ret = ib_uverbs_event_init(&file->comp_file[i], file); | 509 | ret = ib_uverbs_event_init(&file->comp_file[i], file); |
505 | if (ret) | 510 | if (ret) |
506 | goto err_async; | 511 | goto err_async; |
507 | kref_get(&file->ref); | ||
508 | file->comp_file[i].is_async = 0; | 512 | file->comp_file[i].is_async = 0; |
509 | } | 513 | } |
510 | 514 | ||
@@ -524,9 +528,16 @@ err_async: | |||
524 | 528 | ||
525 | ib_uverbs_event_release(&file->async_file); | 529 | ib_uverbs_event_release(&file->async_file); |
526 | 530 | ||
527 | err: | 531 | err_kref: |
532 | /* | ||
533 | * One extra kref_put() because we took a reference before the | ||
534 | * event file creation that failed and got us here. | ||
535 | */ | ||
536 | kref_put(&file->ref, ib_uverbs_release_file); | ||
528 | kref_put(&file->ref, ib_uverbs_release_file); | 537 | kref_put(&file->ref, ib_uverbs_release_file); |
529 | 538 | ||
539 | err: | ||
540 | module_put(dev->ib_dev->owner); | ||
530 | return ret; | 541 | return ret; |
531 | } | 542 | } |
532 | 543 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index cc758a2d2bc6..f6a8ac026557 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c | |||
@@ -605,7 +605,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm, | |||
605 | err = -EINVAL; | 605 | err = -EINVAL; |
606 | goto out; | 606 | goto out; |
607 | } | 607 | } |
608 | for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i, ++nent) { | 608 | for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i) { |
609 | if (virt != -1) { | 609 | if (virt != -1) { |
610 | pages[nent * 2] = cpu_to_be64(virt); | 610 | pages[nent * 2] = cpu_to_be64(virt); |
611 | virt += 1 << lg; | 611 | virt += 1 << lg; |
@@ -616,7 +616,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm, | |||
616 | ts += 1 << (lg - 10); | 616 | ts += 1 << (lg - 10); |
617 | ++tc; | 617 | ++tc; |
618 | 618 | ||
619 | if (nent == MTHCA_MAILBOX_SIZE / 16) { | 619 | if (++nent == MTHCA_MAILBOX_SIZE / 16) { |
620 | err = mthca_cmd(dev, mailbox->dma, nent, 0, op, | 620 | err = mthca_cmd(dev, mailbox->dma, nent, 0, op, |
621 | CMD_TIME_CLASS_B, status); | 621 | CMD_TIME_CLASS_B, status); |
622 | if (err || *status) | 622 | if (err || *status) |
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index 78152a8ad17d..c81fa8e975ef 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c | |||
@@ -836,7 +836,7 @@ int __devinit mthca_init_eq_table(struct mthca_dev *dev) | |||
836 | dev->eq_table.clr_mask = | 836 | dev->eq_table.clr_mask = |
837 | swab32(1 << (dev->eq_table.inta_pin & 31)); | 837 | swab32(1 << (dev->eq_table.inta_pin & 31)); |
838 | dev->eq_table.clr_int = dev->clr_base + | 838 | dev->eq_table.clr_int = dev->clr_base + |
839 | (dev->eq_table.inta_pin < 31 ? 4 : 0); | 839 | (dev->eq_table.inta_pin < 32 ? 4 : 0); |
840 | } | 840 | } |
841 | 841 | ||
842 | dev->eq_table.arm_mask = 0; | 842 | dev->eq_table.arm_mask = 0; |
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index 1827400f189b..7bd7a4bec7b4 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c | |||
@@ -290,7 +290,7 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev, | |||
290 | int i; | 290 | int i; |
291 | u8 status; | 291 | u8 status; |
292 | 292 | ||
293 | num_icm = obj_size * nobj / MTHCA_TABLE_CHUNK_SIZE; | 293 | num_icm = (obj_size * nobj + MTHCA_TABLE_CHUNK_SIZE - 1) / MTHCA_TABLE_CHUNK_SIZE; |
294 | 294 | ||
295 | table = kmalloc(sizeof *table + num_icm * sizeof *table->icm, GFP_KERNEL); | 295 | table = kmalloc(sizeof *table + num_icm * sizeof *table->icm, GFP_KERNEL); |
296 | if (!table) | 296 | if (!table) |
@@ -529,12 +529,25 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db) | |||
529 | goto found; | 529 | goto found; |
530 | } | 530 | } |
531 | 531 | ||
532 | for (i = start; i != end; i += dir) | ||
533 | if (!dev->db_tab->page[i].db_rec) { | ||
534 | page = dev->db_tab->page + i; | ||
535 | goto alloc; | ||
536 | } | ||
537 | |||
532 | if (dev->db_tab->max_group1 >= dev->db_tab->min_group2 - 1) { | 538 | if (dev->db_tab->max_group1 >= dev->db_tab->min_group2 - 1) { |
533 | ret = -ENOMEM; | 539 | ret = -ENOMEM; |
534 | goto out; | 540 | goto out; |
535 | } | 541 | } |
536 | 542 | ||
543 | if (group == 0) | ||
544 | ++dev->db_tab->max_group1; | ||
545 | else | ||
546 | --dev->db_tab->min_group2; | ||
547 | |||
537 | page = dev->db_tab->page + end; | 548 | page = dev->db_tab->page + end; |
549 | |||
550 | alloc: | ||
538 | page->db_rec = dma_alloc_coherent(&dev->pdev->dev, 4096, | 551 | page->db_rec = dma_alloc_coherent(&dev->pdev->dev, 4096, |
539 | &page->mapping, GFP_KERNEL); | 552 | &page->mapping, GFP_KERNEL); |
540 | if (!page->db_rec) { | 553 | if (!page->db_rec) { |
@@ -554,10 +567,6 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db) | |||
554 | } | 567 | } |
555 | 568 | ||
556 | bitmap_zero(page->used, MTHCA_DB_REC_PER_PAGE); | 569 | bitmap_zero(page->used, MTHCA_DB_REC_PER_PAGE); |
557 | if (group == 0) | ||
558 | ++dev->db_tab->max_group1; | ||
559 | else | ||
560 | --dev->db_tab->min_group2; | ||
561 | 570 | ||
562 | found: | 571 | found: |
563 | j = find_first_zero_bit(page->used, MTHCA_DB_REC_PER_PAGE); | 572 | j = find_first_zero_bit(page->used, MTHCA_DB_REC_PER_PAGE); |
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 1c1c2e230871..3f5319a46577 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c | |||
@@ -84,7 +84,7 @@ static int mthca_query_device(struct ib_device *ibdev, | |||
84 | props->vendor_id = be32_to_cpup((__be32 *) (out_mad->data + 36)) & | 84 | props->vendor_id = be32_to_cpup((__be32 *) (out_mad->data + 36)) & |
85 | 0xffffff; | 85 | 0xffffff; |
86 | props->vendor_part_id = be16_to_cpup((__be16 *) (out_mad->data + 30)); | 86 | props->vendor_part_id = be16_to_cpup((__be16 *) (out_mad->data + 30)); |
87 | props->hw_ver = be16_to_cpup((__be16 *) (out_mad->data + 32)); | 87 | props->hw_ver = be32_to_cpup((__be32 *) (out_mad->data + 32)); |
88 | memcpy(&props->sys_image_guid, out_mad->data + 4, 8); | 88 | memcpy(&props->sys_image_guid, out_mad->data + 4, 8); |
89 | memcpy(&props->node_guid, out_mad->data + 12, 8); | 89 | memcpy(&props->node_guid, out_mad->data + 12, 8); |
90 | 90 | ||
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 200a0688f717..54ec737195e0 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c | |||
@@ -230,11 +230,20 @@ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_devi | |||
230 | 230 | ||
231 | static void __hash_remove(struct hash_cell *hc) | 231 | static void __hash_remove(struct hash_cell *hc) |
232 | { | 232 | { |
233 | struct dm_table *table; | ||
234 | |||
233 | /* remove from the dev hash */ | 235 | /* remove from the dev hash */ |
234 | list_del(&hc->uuid_list); | 236 | list_del(&hc->uuid_list); |
235 | list_del(&hc->name_list); | 237 | list_del(&hc->name_list); |
236 | unregister_with_devfs(hc); | 238 | unregister_with_devfs(hc); |
237 | dm_set_mdptr(hc->md, NULL); | 239 | dm_set_mdptr(hc->md, NULL); |
240 | |||
241 | table = dm_get_table(hc->md); | ||
242 | if (table) { | ||
243 | dm_table_event(table); | ||
244 | dm_table_put(table); | ||
245 | } | ||
246 | |||
238 | dm_put(hc->md); | 247 | dm_put(hc->md); |
239 | if (hc->new_map) | 248 | if (hc->new_map) |
240 | dm_table_put(hc->new_map); | 249 | dm_table_put(hc->new_map); |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 785806bdb248..f9b7b32d5d5c 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -329,13 +329,17 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio, | |||
329 | /* | 329 | /* |
330 | * If we run out of usable paths, should we queue I/O or error it? | 330 | * If we run out of usable paths, should we queue I/O or error it? |
331 | */ | 331 | */ |
332 | static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path) | 332 | static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path, |
333 | unsigned save_old_value) | ||
333 | { | 334 | { |
334 | unsigned long flags; | 335 | unsigned long flags; |
335 | 336 | ||
336 | spin_lock_irqsave(&m->lock, flags); | 337 | spin_lock_irqsave(&m->lock, flags); |
337 | 338 | ||
338 | m->saved_queue_if_no_path = m->queue_if_no_path; | 339 | if (save_old_value) |
340 | m->saved_queue_if_no_path = m->queue_if_no_path; | ||
341 | else | ||
342 | m->saved_queue_if_no_path = queue_if_no_path; | ||
339 | m->queue_if_no_path = queue_if_no_path; | 343 | m->queue_if_no_path = queue_if_no_path; |
340 | if (!m->queue_if_no_path && m->queue_size) | 344 | if (!m->queue_if_no_path && m->queue_size) |
341 | queue_work(kmultipathd, &m->process_queued_ios); | 345 | queue_work(kmultipathd, &m->process_queued_ios); |
@@ -677,7 +681,7 @@ static int parse_features(struct arg_set *as, struct multipath *m, | |||
677 | return 0; | 681 | return 0; |
678 | 682 | ||
679 | if (!strnicmp(shift(as), MESG_STR("queue_if_no_path"))) | 683 | if (!strnicmp(shift(as), MESG_STR("queue_if_no_path"))) |
680 | return queue_if_no_path(m, 1); | 684 | return queue_if_no_path(m, 1, 0); |
681 | else { | 685 | else { |
682 | ti->error = "Unrecognised multipath feature request"; | 686 | ti->error = "Unrecognised multipath feature request"; |
683 | return -EINVAL; | 687 | return -EINVAL; |
@@ -1077,7 +1081,7 @@ static void multipath_presuspend(struct dm_target *ti) | |||
1077 | { | 1081 | { |
1078 | struct multipath *m = (struct multipath *) ti->private; | 1082 | struct multipath *m = (struct multipath *) ti->private; |
1079 | 1083 | ||
1080 | queue_if_no_path(m, 0); | 1084 | queue_if_no_path(m, 0, 1); |
1081 | } | 1085 | } |
1082 | 1086 | ||
1083 | /* | 1087 | /* |
@@ -1222,9 +1226,9 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) | |||
1222 | 1226 | ||
1223 | if (argc == 1) { | 1227 | if (argc == 1) { |
1224 | if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) | 1228 | if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) |
1225 | return queue_if_no_path(m, 1); | 1229 | return queue_if_no_path(m, 1, 0); |
1226 | else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path"))) | 1230 | else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path"))) |
1227 | return queue_if_no_path(m, 0); | 1231 | return queue_if_no_path(m, 0, 0); |
1228 | } | 1232 | } |
1229 | 1233 | ||
1230 | if (argc != 2) | 1234 | if (argc != 2) |
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c index 87d5f4d8790f..eaf130e666d8 100644 --- a/drivers/media/dvb/frontends/tda10021.c +++ b/drivers/media/dvb/frontends/tda10021.c | |||
@@ -100,8 +100,8 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) | |||
100 | 100 | ||
101 | ret = i2c_transfer (state->i2c, msg, 2); | 101 | ret = i2c_transfer (state->i2c, msg, 2); |
102 | if (ret != 2) | 102 | if (ret != 2) |
103 | printk("DVB: TDA10021(%d): %s: readreg error (ret == %i)\n", | 103 | printk("DVB: TDA10021: %s: readreg error (ret == %i)\n", |
104 | state->frontend.dvb->num, __FUNCTION__, ret); | 104 | __FUNCTION__, ret); |
105 | return b1[0]; | 105 | return b1[0]; |
106 | } | 106 | } |
107 | 107 | ||
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index cdc07ccd7332..a6078ad9b654 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c | |||
@@ -140,6 +140,7 @@ | |||
140 | 140 | ||
141 | #include <asm/system.h> | 141 | #include <asm/system.h> |
142 | #include <asm/io.h> | 142 | #include <asm/io.h> |
143 | #include <asm/irq.h> | ||
143 | #if ALLOW_DMA | 144 | #if ALLOW_DMA |
144 | #include <asm/dma.h> | 145 | #include <asm/dma.h> |
145 | #endif | 146 | #endif |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 81f4aedf534c..25f85fb9df46 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -67,8 +67,8 @@ | |||
67 | 67 | ||
68 | #define DRV_MODULE_NAME "tg3" | 68 | #define DRV_MODULE_NAME "tg3" |
69 | #define PFX DRV_MODULE_NAME ": " | 69 | #define PFX DRV_MODULE_NAME ": " |
70 | #define DRV_MODULE_VERSION "3.40" | 70 | #define DRV_MODULE_VERSION "3.41" |
71 | #define DRV_MODULE_RELDATE "September 15, 2005" | 71 | #define DRV_MODULE_RELDATE "September 27, 2005" |
72 | 72 | ||
73 | #define TG3_DEF_MAC_MODE 0 | 73 | #define TG3_DEF_MAC_MODE 0 |
74 | #define TG3_DEF_RX_MODE 0 | 74 | #define TG3_DEF_RX_MODE 0 |
@@ -3389,7 +3389,8 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id, | |||
3389 | struct tg3 *tp = netdev_priv(dev); | 3389 | struct tg3 *tp = netdev_priv(dev); |
3390 | struct tg3_hw_status *sblk = tp->hw_status; | 3390 | struct tg3_hw_status *sblk = tp->hw_status; |
3391 | 3391 | ||
3392 | if (sblk->status & SD_STATUS_UPDATED) { | 3392 | if ((sblk->status & SD_STATUS_UPDATED) || |
3393 | !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { | ||
3393 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 3394 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
3394 | 0x00000001); | 3395 | 0x00000001); |
3395 | return IRQ_RETVAL(1); | 3396 | return IRQ_RETVAL(1); |
@@ -5395,6 +5396,9 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) | |||
5395 | struct tg3 *tp = netdev_priv(dev); | 5396 | struct tg3 *tp = netdev_priv(dev); |
5396 | struct sockaddr *addr = p; | 5397 | struct sockaddr *addr = p; |
5397 | 5398 | ||
5399 | if (!is_valid_ether_addr(addr->sa_data)) | ||
5400 | return -EINVAL; | ||
5401 | |||
5398 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | 5402 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); |
5399 | 5403 | ||
5400 | spin_lock_bh(&tp->lock); | 5404 | spin_lock_bh(&tp->lock); |
@@ -5806,6 +5810,13 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
5806 | } | 5810 | } |
5807 | memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); | 5811 | memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); |
5808 | 5812 | ||
5813 | if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) { | ||
5814 | tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT; | ||
5815 | /* reset to prevent losing 1st rx packet intermittently */ | ||
5816 | tw32_f(MAC_RX_MODE, RX_MODE_RESET); | ||
5817 | udelay(10); | ||
5818 | } | ||
5819 | |||
5809 | tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | | 5820 | tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | |
5810 | MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE; | 5821 | MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE; |
5811 | tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR); | 5822 | tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR); |
@@ -5937,7 +5948,7 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
5937 | tw32(MAC_LED_CTRL, tp->led_ctrl); | 5948 | tw32(MAC_LED_CTRL, tp->led_ctrl); |
5938 | 5949 | ||
5939 | tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB); | 5950 | tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB); |
5940 | if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) { | 5951 | if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { |
5941 | tw32_f(MAC_RX_MODE, RX_MODE_RESET); | 5952 | tw32_f(MAC_RX_MODE, RX_MODE_RESET); |
5942 | udelay(10); | 5953 | udelay(10); |
5943 | } | 5954 | } |
@@ -7360,12 +7371,17 @@ static int tg3_nway_reset(struct net_device *dev) | |||
7360 | if (!netif_running(dev)) | 7371 | if (!netif_running(dev)) |
7361 | return -EAGAIN; | 7372 | return -EAGAIN; |
7362 | 7373 | ||
7374 | if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) | ||
7375 | return -EINVAL; | ||
7376 | |||
7363 | spin_lock_bh(&tp->lock); | 7377 | spin_lock_bh(&tp->lock); |
7364 | r = -EINVAL; | 7378 | r = -EINVAL; |
7365 | tg3_readphy(tp, MII_BMCR, &bmcr); | 7379 | tg3_readphy(tp, MII_BMCR, &bmcr); |
7366 | if (!tg3_readphy(tp, MII_BMCR, &bmcr) && | 7380 | if (!tg3_readphy(tp, MII_BMCR, &bmcr) && |
7367 | (bmcr & BMCR_ANENABLE)) { | 7381 | ((bmcr & BMCR_ANENABLE) || |
7368 | tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART); | 7382 | (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) { |
7383 | tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART | | ||
7384 | BMCR_ANENABLE); | ||
7369 | r = 0; | 7385 | r = 0; |
7370 | } | 7386 | } |
7371 | spin_unlock_bh(&tp->lock); | 7387 | spin_unlock_bh(&tp->lock); |
@@ -7927,19 +7943,32 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) | |||
7927 | struct tg3_rx_buffer_desc *desc; | 7943 | struct tg3_rx_buffer_desc *desc; |
7928 | 7944 | ||
7929 | if (loopback_mode == TG3_MAC_LOOPBACK) { | 7945 | if (loopback_mode == TG3_MAC_LOOPBACK) { |
7946 | /* HW errata - mac loopback fails in some cases on 5780. | ||
7947 | * Normal traffic and PHY loopback are not affected by | ||
7948 | * errata. | ||
7949 | */ | ||
7950 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) | ||
7951 | return 0; | ||
7952 | |||
7930 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | 7953 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | |
7931 | MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY | | 7954 | MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY | |
7932 | MAC_MODE_PORT_MODE_GMII; | 7955 | MAC_MODE_PORT_MODE_GMII; |
7933 | tw32(MAC_MODE, mac_mode); | 7956 | tw32(MAC_MODE, mac_mode); |
7934 | } else if (loopback_mode == TG3_PHY_LOOPBACK) { | 7957 | } else if (loopback_mode == TG3_PHY_LOOPBACK) { |
7958 | tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX | | ||
7959 | BMCR_SPEED1000); | ||
7960 | udelay(40); | ||
7961 | /* reset to prevent losing 1st rx packet intermittently */ | ||
7962 | if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) { | ||
7963 | tw32_f(MAC_RX_MODE, RX_MODE_RESET); | ||
7964 | udelay(10); | ||
7965 | tw32_f(MAC_RX_MODE, tp->rx_mode); | ||
7966 | } | ||
7935 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | 7967 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | |
7936 | MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII; | 7968 | MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII; |
7937 | if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) | 7969 | if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) |
7938 | mac_mode &= ~MAC_MODE_LINK_POLARITY; | 7970 | mac_mode &= ~MAC_MODE_LINK_POLARITY; |
7939 | tw32(MAC_MODE, mac_mode); | 7971 | tw32(MAC_MODE, mac_mode); |
7940 | |||
7941 | tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX | | ||
7942 | BMCR_SPEED1000); | ||
7943 | } | 7972 | } |
7944 | else | 7973 | else |
7945 | return -EINVAL; | 7974 | return -EINVAL; |
@@ -10324,6 +10353,44 @@ static char * __devinit tg3_phy_string(struct tg3 *tp) | |||
10324 | }; | 10353 | }; |
10325 | } | 10354 | } |
10326 | 10355 | ||
10356 | static char * __devinit tg3_bus_string(struct tg3 *tp, char *str) | ||
10357 | { | ||
10358 | if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { | ||
10359 | strcpy(str, "PCI Express"); | ||
10360 | return str; | ||
10361 | } else if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) { | ||
10362 | u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL) & 0x1f; | ||
10363 | |||
10364 | strcpy(str, "PCIX:"); | ||
10365 | |||
10366 | if ((clock_ctrl == 7) || | ||
10367 | ((tr32(GRC_MISC_CFG) & GRC_MISC_CFG_BOARD_ID_MASK) == | ||
10368 | GRC_MISC_CFG_BOARD_ID_5704CIOBE)) | ||
10369 | strcat(str, "133MHz"); | ||
10370 | else if (clock_ctrl == 0) | ||
10371 | strcat(str, "33MHz"); | ||
10372 | else if (clock_ctrl == 2) | ||
10373 | strcat(str, "50MHz"); | ||
10374 | else if (clock_ctrl == 4) | ||
10375 | strcat(str, "66MHz"); | ||
10376 | else if (clock_ctrl == 6) | ||
10377 | strcat(str, "100MHz"); | ||
10378 | else if (clock_ctrl == 7) | ||
10379 | strcat(str, "133MHz"); | ||
10380 | } else { | ||
10381 | strcpy(str, "PCI:"); | ||
10382 | if (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED) | ||
10383 | strcat(str, "66MHz"); | ||
10384 | else | ||
10385 | strcat(str, "33MHz"); | ||
10386 | } | ||
10387 | if (tp->tg3_flags & TG3_FLAG_PCI_32BIT) | ||
10388 | strcat(str, ":32-bit"); | ||
10389 | else | ||
10390 | strcat(str, ":64-bit"); | ||
10391 | return str; | ||
10392 | } | ||
10393 | |||
10327 | static struct pci_dev * __devinit tg3_find_5704_peer(struct tg3 *tp) | 10394 | static struct pci_dev * __devinit tg3_find_5704_peer(struct tg3 *tp) |
10328 | { | 10395 | { |
10329 | struct pci_dev *peer; | 10396 | struct pci_dev *peer; |
@@ -10386,6 +10453,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10386 | struct net_device *dev; | 10453 | struct net_device *dev; |
10387 | struct tg3 *tp; | 10454 | struct tg3 *tp; |
10388 | int i, err, pci_using_dac, pm_cap; | 10455 | int i, err, pci_using_dac, pm_cap; |
10456 | char str[40]; | ||
10389 | 10457 | ||
10390 | if (tg3_version_printed++ == 0) | 10458 | if (tg3_version_printed++ == 0) |
10391 | printk(KERN_INFO "%s", version); | 10459 | printk(KERN_INFO "%s", version); |
@@ -10631,16 +10699,12 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10631 | 10699 | ||
10632 | pci_set_drvdata(pdev, dev); | 10700 | pci_set_drvdata(pdev, dev); |
10633 | 10701 | ||
10634 | printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (PCI%s:%s:%s) %sBaseT Ethernet ", | 10702 | printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %sBaseT Ethernet ", |
10635 | dev->name, | 10703 | dev->name, |
10636 | tp->board_part_number, | 10704 | tp->board_part_number, |
10637 | tp->pci_chip_rev_id, | 10705 | tp->pci_chip_rev_id, |
10638 | tg3_phy_string(tp), | 10706 | tg3_phy_string(tp), |
10639 | ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "X" : ""), | 10707 | tg3_bus_string(tp, str), |
10640 | ((tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED) ? | ||
10641 | ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "133MHz" : "66MHz") : | ||
10642 | ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "100MHz" : "33MHz")), | ||
10643 | ((tp->tg3_flags & TG3_FLAG_PCI_32BIT) ? "32-bit" : "64-bit"), | ||
10644 | (tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100" : "10/100/1000"); | 10708 | (tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100" : "10/100/1000"); |
10645 | 10709 | ||
10646 | for (i = 0; i < 6; i++) | 10710 | for (i = 0; i < 6; i++) |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index c184b773e585..2e733c60bfa4 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
@@ -2246,6 +2246,7 @@ struct tg3 { | |||
2246 | (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \ | 2246 | (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \ |
2247 | (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \ | 2247 | (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \ |
2248 | (X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \ | 2248 | (X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \ |
2249 | (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5780 || \ | ||
2249 | (X) == PHY_ID_BCM8002) | 2250 | (X) == PHY_ID_BCM8002) |
2250 | 2251 | ||
2251 | struct tg3_hw_stats *hw_stats; | 2252 | struct tg3_hw_stats *hw_stats; |
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index 8de49fe57233..6deb7cc810cc 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c | |||
@@ -2458,7 +2458,6 @@ struct net_device *alloc_orinocodev(int sizeof_card, | |||
2458 | dev->watchdog_timeo = HZ; /* 1 second timeout */ | 2458 | dev->watchdog_timeo = HZ; /* 1 second timeout */ |
2459 | dev->get_stats = orinoco_get_stats; | 2459 | dev->get_stats = orinoco_get_stats; |
2460 | dev->ethtool_ops = &orinoco_ethtool_ops; | 2460 | dev->ethtool_ops = &orinoco_ethtool_ops; |
2461 | dev->get_wireless_stats = orinoco_get_wireless_stats; | ||
2462 | dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def; | 2461 | dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def; |
2463 | dev->change_mtu = orinoco_change_mtu; | 2462 | dev->change_mtu = orinoco_change_mtu; |
2464 | dev->set_multicast_list = orinoco_set_multicast_list; | 2463 | dev->set_multicast_list = orinoco_set_multicast_list; |
@@ -4399,6 +4398,7 @@ static const struct iw_handler_def orinoco_handler_def = { | |||
4399 | .standard = orinoco_handler, | 4398 | .standard = orinoco_handler, |
4400 | .private = orinoco_private_handler, | 4399 | .private = orinoco_private_handler, |
4401 | .private_args = orinoco_privtab, | 4400 | .private_args = orinoco_privtab, |
4401 | .get_wireless_stats = orinoco_get_wireless_stats, | ||
4402 | }; | 4402 | }; |
4403 | 4403 | ||
4404 | static void orinoco_get_drvinfo(struct net_device *dev, | 4404 | static void orinoco_get_drvinfo(struct net_device *dev, |
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index ddc741e6ecbf..36cc9a96a338 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig | |||
@@ -146,7 +146,7 @@ config I82365 | |||
146 | 146 | ||
147 | config TCIC | 147 | config TCIC |
148 | tristate "Databook TCIC host bridge support" | 148 | tristate "Databook TCIC host bridge support" |
149 | depends on PCMCIA | 149 | depends on PCMCIA && ISA |
150 | select PCCARD_NONSTATIC | 150 | select PCCARD_NONSTATIC |
151 | help | 151 | help |
152 | Say Y here to include support for the Databook TCIC family of PCMCIA | 152 | Say Y here to include support for the Databook TCIC family of PCMCIA |
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index 1d755e20880c..3f6d51d11374 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c | |||
@@ -228,6 +228,11 @@ int cb_alloc(struct pcmcia_socket * s) | |||
228 | pci_bus_size_bridges(bus); | 228 | pci_bus_size_bridges(bus); |
229 | pci_bus_assign_resources(bus); | 229 | pci_bus_assign_resources(bus); |
230 | cardbus_assign_irqs(bus, s->pci_irq); | 230 | cardbus_assign_irqs(bus, s->pci_irq); |
231 | |||
232 | /* socket specific tune function */ | ||
233 | if (s->tune_bridge) | ||
234 | s->tune_bridge(s, bus); | ||
235 | |||
231 | pci_enable_bridges(bus); | 236 | pci_enable_bridges(bus); |
232 | pci_bus_add_devices(bus); | 237 | pci_bus_add_devices(bus); |
233 | 238 | ||
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index fbe233e19ceb..da0b404561c9 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h | |||
@@ -59,6 +59,7 @@ | |||
59 | 59 | ||
60 | #define TI122X_SCR_SER_STEP 0xc0000000 | 60 | #define TI122X_SCR_SER_STEP 0xc0000000 |
61 | #define TI122X_SCR_INTRTIE 0x20000000 | 61 | #define TI122X_SCR_INTRTIE 0x20000000 |
62 | #define TIXX21_SCR_TIEALL 0x10000000 | ||
62 | #define TI122X_SCR_CBRSVD 0x00400000 | 63 | #define TI122X_SCR_CBRSVD 0x00400000 |
63 | #define TI122X_SCR_MRBURSTDN 0x00008000 | 64 | #define TI122X_SCR_MRBURSTDN 0x00008000 |
64 | #define TI122X_SCR_MRBURSTUP 0x00004000 | 65 | #define TI122X_SCR_MRBURSTUP 0x00004000 |
@@ -153,6 +154,12 @@ | |||
153 | /* EnE test register */ | 154 | /* EnE test register */ |
154 | #define ENE_TEST_C9 0xc9 /* 8bit */ | 155 | #define ENE_TEST_C9 0xc9 /* 8bit */ |
155 | #define ENE_TEST_C9_TLTENABLE 0x02 | 156 | #define ENE_TEST_C9_TLTENABLE 0x02 |
157 | #define ENE_TEST_C9_PFENABLE_F0 0x04 | ||
158 | #define ENE_TEST_C9_PFENABLE_F1 0x08 | ||
159 | #define ENE_TEST_C9_PFENABLE (ENE_TEST_C9_PFENABLE_F0 | ENE_TEST_C9_PFENABLE_F0) | ||
160 | #define ENE_TEST_C9_WPDISALBLE_F0 0x40 | ||
161 | #define ENE_TEST_C9_WPDISALBLE_F1 0x80 | ||
162 | #define ENE_TEST_C9_WPDISALBLE (ENE_TEST_C9_WPDISALBLE_F0 | ENE_TEST_C9_WPDISALBLE_F1) | ||
156 | 163 | ||
157 | /* | 164 | /* |
158 | * Texas Instruments CardBus controller overrides. | 165 | * Texas Instruments CardBus controller overrides. |
@@ -618,6 +625,7 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket) | |||
618 | int devfn; | 625 | int devfn; |
619 | unsigned int state; | 626 | unsigned int state; |
620 | int ret = 1; | 627 | int ret = 1; |
628 | u32 sysctl; | ||
621 | 629 | ||
622 | /* catch the two-slot controllers */ | 630 | /* catch the two-slot controllers */ |
623 | switch (socket->dev->device) { | 631 | switch (socket->dev->device) { |
@@ -640,6 +648,24 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket) | |||
640 | */ | 648 | */ |
641 | break; | 649 | break; |
642 | 650 | ||
651 | case PCI_DEVICE_ID_TI_X515: | ||
652 | case PCI_DEVICE_ID_TI_X420: | ||
653 | case PCI_DEVICE_ID_TI_X620: | ||
654 | case PCI_DEVICE_ID_TI_XX21_XX11: | ||
655 | case PCI_DEVICE_ID_TI_7410: | ||
656 | case PCI_DEVICE_ID_TI_7610: | ||
657 | /* | ||
658 | * those are either single or dual slot CB with additional functions | ||
659 | * like 1394, smartcard reader, etc. check the TIEALL flag for them | ||
660 | * the TIEALL flag binds the IRQ of all functions toghether. | ||
661 | * we catch the single slot variants later. | ||
662 | */ | ||
663 | sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); | ||
664 | if (sysctl & TIXX21_SCR_TIEALL) | ||
665 | return 0; | ||
666 | |||
667 | break; | ||
668 | |||
643 | /* single-slot controllers have the 2nd slot empty always :) */ | 669 | /* single-slot controllers have the 2nd slot empty always :) */ |
644 | default: | 670 | default: |
645 | return 1; | 671 | return 1; |
@@ -652,6 +678,15 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket) | |||
652 | if (!func) | 678 | if (!func) |
653 | return 1; | 679 | return 1; |
654 | 680 | ||
681 | /* | ||
682 | * check that the device id of both slots match. this is needed for the | ||
683 | * XX21 and the XX11 controller that share the same device id for single | ||
684 | * and dual slot controllers. return '2nd slot empty'. we already checked | ||
685 | * if the interrupt is tied to another function. | ||
686 | */ | ||
687 | if (socket->dev->device != func->device) | ||
688 | goto out; | ||
689 | |||
655 | slot2 = pci_get_drvdata(func); | 690 | slot2 = pci_get_drvdata(func); |
656 | if (!slot2) | 691 | if (!slot2) |
657 | goto out; | 692 | goto out; |
@@ -791,16 +826,6 @@ static int ti12xx_override(struct yenta_socket *socket) | |||
791 | config_writel(socket, TI113X_SYSTEM_CONTROL, val); | 826 | config_writel(socket, TI113X_SYSTEM_CONTROL, val); |
792 | 827 | ||
793 | /* | 828 | /* |
794 | * for EnE bridges only: clear testbit TLTEnable. this makes the | ||
795 | * RME Hammerfall DSP sound card working. | ||
796 | */ | ||
797 | if (socket->dev->vendor == PCI_VENDOR_ID_ENE) { | ||
798 | u8 test_c9 = config_readb(socket, ENE_TEST_C9); | ||
799 | test_c9 &= ~ENE_TEST_C9_TLTENABLE; | ||
800 | config_writeb(socket, ENE_TEST_C9, test_c9); | ||
801 | } | ||
802 | |||
803 | /* | ||
804 | * Yenta expects controllers to use CSCINT to route | 829 | * Yenta expects controllers to use CSCINT to route |
805 | * CSC interrupts to PCI rather than INTVAL. | 830 | * CSC interrupts to PCI rather than INTVAL. |
806 | */ | 831 | */ |
@@ -841,5 +866,75 @@ static int ti1250_override(struct yenta_socket *socket) | |||
841 | return ti12xx_override(socket); | 866 | return ti12xx_override(socket); |
842 | } | 867 | } |
843 | 868 | ||
869 | |||
870 | /** | ||
871 | * EnE specific part. EnE bridges are register compatible with TI bridges but | ||
872 | * have their own test registers and more important their own little problems. | ||
873 | * Some fixup code to make everybody happy (TM). | ||
874 | */ | ||
875 | |||
876 | /** | ||
877 | * set/clear various test bits: | ||
878 | * Defaults to clear the bit. | ||
879 | * - mask (u8) defines what bits to change | ||
880 | * - bits (u8) is the values to change them to | ||
881 | * -> it's | ||
882 | * current = (current & ~mask) | bits | ||
883 | */ | ||
884 | /* pci ids of devices that wants to have the bit set */ | ||
885 | #define DEVID(_vend,_dev,_subvend,_subdev,mask,bits) { \ | ||
886 | .vendor = _vend, \ | ||
887 | .device = _dev, \ | ||
888 | .subvendor = _subvend, \ | ||
889 | .subdevice = _subdev, \ | ||
890 | .driver_data = ((mask) << 8 | (bits)), \ | ||
891 | } | ||
892 | static struct pci_device_id ene_tune_tbl[] = { | ||
893 | /* Echo Audio products based on motorola DSP56301 and DSP56361 */ | ||
894 | DEVID(PCI_VENDOR_ID_MOTOROLA, 0x1801, 0xECC0, PCI_ANY_ID, | ||
895 | ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE), | ||
896 | DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID, | ||
897 | ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE), | ||
898 | |||
899 | {} | ||
900 | }; | ||
901 | |||
902 | static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus) | ||
903 | { | ||
904 | struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); | ||
905 | struct pci_dev *dev; | ||
906 | struct pci_device_id *id = NULL; | ||
907 | u8 test_c9, old_c9, mask, bits; | ||
908 | |||
909 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
910 | id = (struct pci_device_id *) pci_match_id(ene_tune_tbl, dev); | ||
911 | if (id) | ||
912 | break; | ||
913 | } | ||
914 | |||
915 | test_c9 = old_c9 = config_readb(socket, ENE_TEST_C9); | ||
916 | if (id) { | ||
917 | mask = (id->driver_data >> 8) & 0xFF; | ||
918 | bits = id->driver_data & 0xFF; | ||
919 | |||
920 | test_c9 = (test_c9 & ~mask) | bits; | ||
921 | } | ||
922 | else | ||
923 | /* default to clear TLTEnable bit, old behaviour */ | ||
924 | test_c9 &= ~ENE_TEST_C9_TLTENABLE; | ||
925 | |||
926 | printk(KERN_INFO "yenta EnE: chaning testregister 0xC9, %02x -> %02x\n", old_c9, test_c9); | ||
927 | config_writeb(socket, ENE_TEST_C9, test_c9); | ||
928 | } | ||
929 | |||
930 | |||
931 | static int ene_override(struct yenta_socket *socket) | ||
932 | { | ||
933 | /* install tune_bridge() function */ | ||
934 | socket->socket.tune_bridge = ene_tune_bridge; | ||
935 | |||
936 | return ti1250_override(socket); | ||
937 | } | ||
938 | |||
844 | #endif /* _LINUX_TI113X_H */ | 939 | #endif /* _LINUX_TI113X_H */ |
845 | 940 | ||
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index ba4d78e5b121..db9f952f9e3c 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
@@ -559,12 +559,6 @@ static void yenta_interrogate(struct yenta_socket *socket) | |||
559 | static int yenta_sock_init(struct pcmcia_socket *sock) | 559 | static int yenta_sock_init(struct pcmcia_socket *sock) |
560 | { | 560 | { |
561 | struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); | 561 | struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); |
562 | u16 bridge; | ||
563 | |||
564 | bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~CB_BRIDGE_INTR; | ||
565 | if (!socket->cb_irq) | ||
566 | bridge |= CB_BRIDGE_INTR; | ||
567 | config_writew(socket, CB_BRIDGE_CONTROL, bridge); | ||
568 | 562 | ||
569 | exca_writeb(socket, I365_GBLCTL, 0x00); | 563 | exca_writeb(socket, I365_GBLCTL, 0x00); |
570 | exca_writeb(socket, I365_GENCTL, 0x00); | 564 | exca_writeb(socket, I365_GENCTL, 0x00); |
@@ -819,6 +813,7 @@ enum { | |||
819 | CARDBUS_TYPE_TOPIC95, | 813 | CARDBUS_TYPE_TOPIC95, |
820 | CARDBUS_TYPE_TOPIC97, | 814 | CARDBUS_TYPE_TOPIC97, |
821 | CARDBUS_TYPE_O2MICRO, | 815 | CARDBUS_TYPE_O2MICRO, |
816 | CARDBUS_TYPE_ENE, | ||
822 | }; | 817 | }; |
823 | 818 | ||
824 | /* | 819 | /* |
@@ -865,6 +860,12 @@ static struct cardbus_type cardbus_type[] = { | |||
865 | .override = o2micro_override, | 860 | .override = o2micro_override, |
866 | .restore_state = o2micro_restore_state, | 861 | .restore_state = o2micro_restore_state, |
867 | }, | 862 | }, |
863 | [CARDBUS_TYPE_ENE] = { | ||
864 | .override = ene_override, | ||
865 | .save_state = ti_save_state, | ||
866 | .restore_state = ti_restore_state, | ||
867 | .sock_init = ti_init, | ||
868 | }, | ||
868 | }; | 869 | }; |
869 | 870 | ||
870 | 871 | ||
@@ -883,16 +884,8 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas | |||
883 | { | 884 | { |
884 | int i; | 885 | int i; |
885 | unsigned long val; | 886 | unsigned long val; |
886 | u16 bridge_ctrl; | ||
887 | u32 mask; | 887 | u32 mask; |
888 | 888 | ||
889 | /* Set up ISA irq routing to probe the ISA irqs.. */ | ||
890 | bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL); | ||
891 | if (!(bridge_ctrl & CB_BRIDGE_INTR)) { | ||
892 | bridge_ctrl |= CB_BRIDGE_INTR; | ||
893 | config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl); | ||
894 | } | ||
895 | |||
896 | /* | 889 | /* |
897 | * Probe for usable interrupts using the force | 890 | * Probe for usable interrupts using the force |
898 | * register to generate bogus card status events. | 891 | * register to generate bogus card status events. |
@@ -914,9 +907,6 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas | |||
914 | 907 | ||
915 | mask = probe_irq_mask(val) & 0xffff; | 908 | mask = probe_irq_mask(val) & 0xffff; |
916 | 909 | ||
917 | bridge_ctrl &= ~CB_BRIDGE_INTR; | ||
918 | config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl); | ||
919 | |||
920 | return mask; | 910 | return mask; |
921 | } | 911 | } |
922 | 912 | ||
@@ -944,18 +934,11 @@ static irqreturn_t yenta_probe_handler(int irq, void *dev_id, struct pt_regs *re | |||
944 | /* probes the PCI interrupt, use only on override functions */ | 934 | /* probes the PCI interrupt, use only on override functions */ |
945 | static int yenta_probe_cb_irq(struct yenta_socket *socket) | 935 | static int yenta_probe_cb_irq(struct yenta_socket *socket) |
946 | { | 936 | { |
947 | u16 bridge_ctrl; | ||
948 | |||
949 | if (!socket->cb_irq) | 937 | if (!socket->cb_irq) |
950 | return -1; | 938 | return -1; |
951 | 939 | ||
952 | socket->probe_status = 0; | 940 | socket->probe_status = 0; |
953 | 941 | ||
954 | /* disable ISA interrupts */ | ||
955 | bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL); | ||
956 | bridge_ctrl &= ~CB_BRIDGE_INTR; | ||
957 | config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl); | ||
958 | |||
959 | if (request_irq(socket->cb_irq, yenta_probe_handler, SA_SHIRQ, "yenta", socket)) { | 942 | if (request_irq(socket->cb_irq, yenta_probe_handler, SA_SHIRQ, "yenta", socket)) { |
960 | printk(KERN_WARNING "Yenta: request_irq() in yenta_probe_cb_irq() failed!\n"); | 943 | printk(KERN_WARNING "Yenta: request_irq() in yenta_probe_cb_irq() failed!\n"); |
961 | return -1; | 944 | return -1; |
@@ -966,7 +949,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket) | |||
966 | cb_writel(socket, CB_SOCKET_EVENT, -1); | 949 | cb_writel(socket, CB_SOCKET_EVENT, -1); |
967 | cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); | 950 | cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); |
968 | cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS); | 951 | cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS); |
969 | 952 | ||
970 | msleep(100); | 953 | msleep(100); |
971 | 954 | ||
972 | /* disable interrupts */ | 955 | /* disable interrupts */ |
@@ -1004,11 +987,12 @@ static void yenta_config_init(struct yenta_socket *socket) | |||
1004 | { | 987 | { |
1005 | u16 bridge; | 988 | u16 bridge; |
1006 | struct pci_dev *dev = socket->dev; | 989 | struct pci_dev *dev = socket->dev; |
990 | struct pci_bus_region region; | ||
1007 | 991 | ||
1008 | pci_set_power_state(socket->dev, 0); | 992 | pcibios_resource_to_bus(socket->dev, ®ion, &dev->resource[0]); |
1009 | 993 | ||
1010 | config_writel(socket, CB_LEGACY_MODE_BASE, 0); | 994 | config_writel(socket, CB_LEGACY_MODE_BASE, 0); |
1011 | config_writel(socket, PCI_BASE_ADDRESS_0, dev->resource[0].start); | 995 | config_writel(socket, PCI_BASE_ADDRESS_0, region.start); |
1012 | config_writew(socket, PCI_COMMAND, | 996 | config_writew(socket, PCI_COMMAND, |
1013 | PCI_COMMAND_IO | | 997 | PCI_COMMAND_IO | |
1014 | PCI_COMMAND_MEMORY | | 998 | PCI_COMMAND_MEMORY | |
@@ -1031,8 +1015,8 @@ static void yenta_config_init(struct yenta_socket *socket) | |||
1031 | * - PCI interrupts enabled if a PCI interrupt exists.. | 1015 | * - PCI interrupts enabled if a PCI interrupt exists.. |
1032 | */ | 1016 | */ |
1033 | bridge = config_readw(socket, CB_BRIDGE_CONTROL); | 1017 | bridge = config_readw(socket, CB_BRIDGE_CONTROL); |
1034 | bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_INTR | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN); | 1018 | bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN); |
1035 | bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN | CB_BRIDGE_INTR; | 1019 | bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN; |
1036 | config_writew(socket, CB_BRIDGE_CONTROL, bridge); | 1020 | config_writew(socket, CB_BRIDGE_CONTROL, bridge); |
1037 | } | 1021 | } |
1038 | 1022 | ||
@@ -1265,10 +1249,22 @@ static struct pci_device_id yenta_table [] = { | |||
1265 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1250, TI1250), | 1249 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1250, TI1250), |
1266 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1410, TI1250), | 1250 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1410, TI1250), |
1267 | 1251 | ||
1268 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1211, TI12XX), | 1252 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX21_XX11, TI12XX), |
1269 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, TI12XX), | 1253 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X515, TI12XX), |
1270 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, TI1250), | 1254 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X420, TI12XX), |
1271 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, TI12XX), | 1255 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X620, TI12XX), |
1256 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7410, TI12XX), | ||
1257 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7510, TI12XX), | ||
1258 | CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7610, TI12XX), | ||
1259 | |||
1260 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_710, TI12XX), | ||
1261 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_712, TI12XX), | ||
1262 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_720, TI12XX), | ||
1263 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_722, TI12XX), | ||
1264 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1211, ENE), | ||
1265 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, ENE), | ||
1266 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, ENE), | ||
1267 | CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, ENE), | ||
1272 | 1268 | ||
1273 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH), | 1269 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH), |
1274 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH), | 1270 | CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH), |
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 1ae0b381c162..2c7d3ef76e8e 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -859,6 +859,7 @@ static struct pcmcia_device_id serial_ids[] = { | |||
859 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"), | 859 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"), |
860 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"), | 860 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"), |
861 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"), | 861 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"), |
862 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ | ||
862 | PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"), | 863 | PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"), |
863 | PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"), | 864 | PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"), |
864 | PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"), | 865 | PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"), |
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 821c9c4d76aa..d95f8626d170 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
@@ -71,21 +71,28 @@ static int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry) | |||
71 | * | 71 | * |
72 | */ | 72 | */ |
73 | 73 | ||
74 | struct v9fs_fid *v9fs_fid_create(struct dentry *dentry) | 74 | struct v9fs_fid *v9fs_fid_create(struct dentry *dentry, |
75 | struct v9fs_session_info *v9ses, int fid, int create) | ||
75 | { | 76 | { |
76 | struct v9fs_fid *new; | 77 | struct v9fs_fid *new; |
77 | 78 | ||
79 | dprintk(DEBUG_9P, "fid create dentry %p, fid %d, create %d\n", | ||
80 | dentry, fid, create); | ||
81 | |||
78 | new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); | 82 | new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); |
79 | if (new == NULL) { | 83 | if (new == NULL) { |
80 | dprintk(DEBUG_ERROR, "Out of Memory\n"); | 84 | dprintk(DEBUG_ERROR, "Out of Memory\n"); |
81 | return ERR_PTR(-ENOMEM); | 85 | return ERR_PTR(-ENOMEM); |
82 | } | 86 | } |
83 | 87 | ||
84 | new->fid = -1; | 88 | new->fid = fid; |
89 | new->v9ses = v9ses; | ||
85 | new->fidopen = 0; | 90 | new->fidopen = 0; |
86 | new->fidcreate = 0; | 91 | new->fidcreate = create; |
87 | new->fidclunked = 0; | 92 | new->fidclunked = 0; |
88 | new->iounit = 0; | 93 | new->iounit = 0; |
94 | new->rdir_pos = 0; | ||
95 | new->rdir_fcall = NULL; | ||
89 | 96 | ||
90 | if (v9fs_fid_insert(new, dentry) == 0) | 97 | if (v9fs_fid_insert(new, dentry) == 0) |
91 | return new; | 98 | return new; |
@@ -109,6 +116,59 @@ void v9fs_fid_destroy(struct v9fs_fid *fid) | |||
109 | } | 116 | } |
110 | 117 | ||
111 | /** | 118 | /** |
119 | * v9fs_fid_walk_up - walks from the process current directory | ||
120 | * up to the specified dentry. | ||
121 | */ | ||
122 | static struct v9fs_fid *v9fs_fid_walk_up(struct dentry *dentry) | ||
123 | { | ||
124 | int fidnum, cfidnum, err; | ||
125 | struct v9fs_fid *cfid; | ||
126 | struct dentry *cde; | ||
127 | struct v9fs_session_info *v9ses; | ||
128 | |||
129 | v9ses = v9fs_inode2v9ses(current->fs->pwd->d_inode); | ||
130 | cfid = v9fs_fid_lookup(current->fs->pwd); | ||
131 | if (cfid == NULL) { | ||
132 | dprintk(DEBUG_ERROR, "process cwd doesn't have a fid\n"); | ||
133 | return ERR_PTR(-ENOENT); | ||
134 | } | ||
135 | |||
136 | cfidnum = cfid->fid; | ||
137 | cde = current->fs->pwd; | ||
138 | /* TODO: take advantage of multiwalk */ | ||
139 | |||
140 | fidnum = v9fs_get_idpool(&v9ses->fidpool); | ||
141 | if (fidnum < 0) { | ||
142 | dprintk(DEBUG_ERROR, "could not get a new fid num\n"); | ||
143 | err = -ENOENT; | ||
144 | goto clunk_fid; | ||
145 | } | ||
146 | |||
147 | while (cde != dentry) { | ||
148 | if (cde == cde->d_parent) { | ||
149 | dprintk(DEBUG_ERROR, "can't find dentry\n"); | ||
150 | err = -ENOENT; | ||
151 | goto clunk_fid; | ||
152 | } | ||
153 | |||
154 | err = v9fs_t_walk(v9ses, cfidnum, fidnum, "..", NULL); | ||
155 | if (err < 0) { | ||
156 | dprintk(DEBUG_ERROR, "problem walking to parent\n"); | ||
157 | goto clunk_fid; | ||
158 | } | ||
159 | |||
160 | cfidnum = fidnum; | ||
161 | cde = cde->d_parent; | ||
162 | } | ||
163 | |||
164 | return v9fs_fid_create(dentry, v9ses, fidnum, 0); | ||
165 | |||
166 | clunk_fid: | ||
167 | v9fs_t_clunk(v9ses, fidnum, NULL); | ||
168 | return ERR_PTR(err); | ||
169 | } | ||
170 | |||
171 | /** | ||
112 | * v9fs_fid_lookup - retrieve the right fid from a particular dentry | 172 | * v9fs_fid_lookup - retrieve the right fid from a particular dentry |
113 | * @dentry: dentry to look for fid in | 173 | * @dentry: dentry to look for fid in |
114 | * @type: intent of lookup (operation or traversal) | 174 | * @type: intent of lookup (operation or traversal) |
@@ -119,49 +179,25 @@ void v9fs_fid_destroy(struct v9fs_fid *fid) | |||
119 | * | 179 | * |
120 | */ | 180 | */ |
121 | 181 | ||
122 | struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry, int type) | 182 | struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry) |
123 | { | 183 | { |
124 | struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; | 184 | struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; |
125 | struct v9fs_fid *current_fid = NULL; | 185 | struct v9fs_fid *current_fid = NULL; |
126 | struct v9fs_fid *temp = NULL; | 186 | struct v9fs_fid *temp = NULL; |
127 | struct v9fs_fid *return_fid = NULL; | 187 | struct v9fs_fid *return_fid = NULL; |
128 | int found_parent = 0; | ||
129 | int found_user = 0; | ||
130 | 188 | ||
131 | dprintk(DEBUG_9P, " dentry: %s (%p) type %d\n", dentry->d_iname, dentry, | 189 | dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry); |
132 | type); | ||
133 | 190 | ||
134 | if (fid_list && !list_empty(fid_list)) { | 191 | if (fid_list) { |
135 | list_for_each_entry_safe(current_fid, temp, fid_list, list) { | 192 | list_for_each_entry_safe(current_fid, temp, fid_list, list) { |
136 | if (current_fid->uid == current->uid) { | 193 | if (!current_fid->fidcreate) { |
137 | if (return_fid == NULL) { | 194 | return_fid = current_fid; |
138 | if ((type == FID_OP) | 195 | break; |
139 | || (!current_fid->fidopen)) { | ||
140 | return_fid = current_fid; | ||
141 | found_user = 1; | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | if (current_fid->pid == current->real_parent->pid) { | ||
146 | if ((return_fid == NULL) || (found_parent) | ||
147 | || (found_user)) { | ||
148 | if ((type == FID_OP) | ||
149 | || (!current_fid->fidopen)) { | ||
150 | return_fid = current_fid; | ||
151 | found_parent = 1; | ||
152 | found_user = 0; | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | if (current_fid->pid == current->pid) { | ||
157 | if ((type == FID_OP) || | ||
158 | (!current_fid->fidopen)) { | ||
159 | return_fid = current_fid; | ||
160 | found_parent = 0; | ||
161 | found_user = 0; | ||
162 | } | ||
163 | } | 196 | } |
164 | } | 197 | } |
198 | |||
199 | if (!return_fid) | ||
200 | return_fid = current_fid; | ||
165 | } | 201 | } |
166 | 202 | ||
167 | /* we are at the root but didn't match */ | 203 | /* we are at the root but didn't match */ |
@@ -187,55 +223,33 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry, int type) | |||
187 | 223 | ||
188 | /* XXX - there may be some duplication we can get rid of */ | 224 | /* XXX - there may be some duplication we can get rid of */ |
189 | if (par == dentry) { | 225 | if (par == dentry) { |
190 | /* we need to fid_lookup the starting point */ | 226 | return_fid = v9fs_fid_walk_up(dentry); |
191 | int fidnum = -1; | 227 | if (IS_ERR(return_fid)) |
192 | int oldfid = -1; | 228 | return_fid = NULL; |
193 | int result = -1; | 229 | } |
194 | struct v9fs_session_info *v9ses = | 230 | } |
195 | v9fs_inode2v9ses(current->fs->pwd->d_inode); | ||
196 | |||
197 | current_fid = | ||
198 | v9fs_fid_lookup(current->fs->pwd, FID_WALK); | ||
199 | if (current_fid == NULL) { | ||
200 | dprintk(DEBUG_ERROR, | ||
201 | "process cwd doesn't have a fid\n"); | ||
202 | return return_fid; | ||
203 | } | ||
204 | oldfid = current_fid->fid; | ||
205 | par = current->fs->pwd; | ||
206 | /* TODO: take advantage of multiwalk */ | ||
207 | 231 | ||
208 | fidnum = v9fs_get_idpool(&v9ses->fidpool); | 232 | return return_fid; |
209 | if (fidnum < 0) { | 233 | } |
210 | dprintk(DEBUG_ERROR, | ||
211 | "could not get a new fid num\n"); | ||
212 | return return_fid; | ||
213 | } | ||
214 | 234 | ||
215 | while (par != dentry) { | 235 | struct v9fs_fid *v9fs_fid_get_created(struct dentry *dentry) |
216 | result = | 236 | { |
217 | v9fs_t_walk(v9ses, oldfid, fidnum, "..", | 237 | struct list_head *fid_list; |
218 | NULL); | 238 | struct v9fs_fid *fid, *ftmp, *ret; |
219 | if (result < 0) { | 239 | |
220 | dprintk(DEBUG_ERROR, | 240 | dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry); |
221 | "problem walking to parent\n"); | 241 | fid_list = (struct list_head *)dentry->d_fsdata; |
222 | 242 | ret = NULL; | |
223 | break; | 243 | if (fid_list) { |
224 | } | 244 | list_for_each_entry_safe(fid, ftmp, fid_list, list) { |
225 | oldfid = fidnum; | 245 | if (fid->fidcreate && fid->pid == current->pid) { |
226 | if (par == par->d_parent) { | 246 | list_del(&fid->list); |
227 | dprintk(DEBUG_ERROR, | 247 | ret = fid; |
228 | "can't find dentry\n"); | 248 | break; |
229 | break; | ||
230 | } | ||
231 | par = par->d_parent; | ||
232 | } | ||
233 | if (par == dentry) { | ||
234 | return_fid = v9fs_fid_create(dentry); | ||
235 | return_fid->fid = fidnum; | ||
236 | } | 249 | } |
237 | } | 250 | } |
238 | } | 251 | } |
239 | 252 | ||
240 | return return_fid; | 253 | dprintk(DEBUG_9P, "return %p\n", ret); |
254 | return ret; | ||
241 | } | 255 | } |
diff --git a/fs/9p/fid.h b/fs/9p/fid.h index 7db478ccca36..84c673a44c83 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #define FID_OP 0 | 26 | #define FID_OP 0 |
27 | #define FID_WALK 1 | 27 | #define FID_WALK 1 |
28 | #define FID_CREATE 2 | ||
28 | 29 | ||
29 | struct v9fs_fid { | 30 | struct v9fs_fid { |
30 | struct list_head list; /* list of fids associated with a dentry */ | 31 | struct list_head list; /* list of fids associated with a dentry */ |
@@ -52,6 +53,8 @@ struct v9fs_fid { | |||
52 | struct v9fs_session_info *v9ses; /* session info for this FID */ | 53 | struct v9fs_session_info *v9ses; /* session info for this FID */ |
53 | }; | 54 | }; |
54 | 55 | ||
55 | struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry, int type); | 56 | struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry); |
57 | struct v9fs_fid *v9fs_fid_get_created(struct dentry *); | ||
56 | void v9fs_fid_destroy(struct v9fs_fid *fid); | 58 | void v9fs_fid_destroy(struct v9fs_fid *fid); |
57 | struct v9fs_fid *v9fs_fid_create(struct dentry *); | 59 | struct v9fs_fid *v9fs_fid_create(struct dentry *, |
60 | struct v9fs_session_info *v9ses, int fid, int create); | ||
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index 306c96741f81..a6aa947de0f9 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c | |||
@@ -67,7 +67,7 @@ static int v9fs_dentry_validate(struct dentry *dentry, struct nameidata *nd) | |||
67 | struct dentry *dc = current->fs->pwd; | 67 | struct dentry *dc = current->fs->pwd; |
68 | 68 | ||
69 | dprintk(DEBUG_VFS, "dentry: %s (%p)\n", dentry->d_iname, dentry); | 69 | dprintk(DEBUG_VFS, "dentry: %s (%p)\n", dentry->d_iname, dentry); |
70 | if (v9fs_fid_lookup(dentry, FID_OP)) { | 70 | if (v9fs_fid_lookup(dentry)) { |
71 | dprintk(DEBUG_VFS, "VALID\n"); | 71 | dprintk(DEBUG_VFS, "VALID\n"); |
72 | return 1; | 72 | return 1; |
73 | } | 73 | } |
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index c478a7384186..57a43b8feef5 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
@@ -197,21 +197,18 @@ int v9fs_dir_release(struct inode *inode, struct file *filp) | |||
197 | filemap_fdatawait(inode->i_mapping); | 197 | filemap_fdatawait(inode->i_mapping); |
198 | 198 | ||
199 | if (fidnum >= 0) { | 199 | if (fidnum >= 0) { |
200 | fid->fidopen--; | ||
201 | dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen, | 200 | dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen, |
202 | fid->fid); | 201 | fid->fid); |
203 | 202 | ||
204 | if (fid->fidopen == 0) { | 203 | if (v9fs_t_clunk(v9ses, fidnum, NULL)) |
205 | if (v9fs_t_clunk(v9ses, fidnum, NULL)) | 204 | dprintk(DEBUG_ERROR, "clunk failed\n"); |
206 | dprintk(DEBUG_ERROR, "clunk failed\n"); | ||
207 | 205 | ||
208 | v9fs_put_idpool(fid->fid, &v9ses->fidpool); | 206 | v9fs_put_idpool(fid->fid, &v9ses->fidpool); |
209 | } | ||
210 | 207 | ||
211 | kfree(fid->rdir_fcall); | 208 | kfree(fid->rdir_fcall); |
209 | kfree(fid); | ||
212 | 210 | ||
213 | filp->private_data = NULL; | 211 | filp->private_data = NULL; |
214 | v9fs_fid_destroy(fid); | ||
215 | } | 212 | } |
216 | 213 | ||
217 | d_drop(filp->f_dentry); | 214 | d_drop(filp->f_dentry); |
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 1f8ae7d580ab..a4799e971d1c 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -53,30 +53,36 @@ | |||
53 | int v9fs_file_open(struct inode *inode, struct file *file) | 53 | int v9fs_file_open(struct inode *inode, struct file *file) |
54 | { | 54 | { |
55 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 55 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); |
56 | struct v9fs_fid *v9fid = v9fs_fid_lookup(file->f_dentry, FID_WALK); | 56 | struct v9fs_fid *v9fid, *fid; |
57 | struct v9fs_fid *v9newfid = NULL; | ||
58 | struct v9fs_fcall *fcall = NULL; | 57 | struct v9fs_fcall *fcall = NULL; |
59 | int open_mode = 0; | 58 | int open_mode = 0; |
60 | unsigned int iounit = 0; | 59 | unsigned int iounit = 0; |
61 | int newfid = -1; | 60 | int newfid = -1; |
62 | long result = -1; | 61 | long result = -1; |
63 | 62 | ||
64 | dprintk(DEBUG_VFS, "inode: %p file: %p v9fid= %p\n", inode, file, | 63 | dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); |
65 | v9fid); | 64 | |
65 | v9fid = v9fs_fid_get_created(file->f_dentry); | ||
66 | if (!v9fid) | ||
67 | v9fid = v9fs_fid_lookup(file->f_dentry); | ||
66 | 68 | ||
67 | if (!v9fid) { | 69 | if (!v9fid) { |
68 | struct dentry *dentry = file->f_dentry; | ||
69 | dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); | 70 | dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); |
71 | return -EBADF; | ||
72 | } | ||
70 | 73 | ||
71 | /* XXX - some duplication from lookup, generalize later */ | 74 | if (!v9fid->fidcreate) { |
72 | /* basically vfs_lookup is too heavy weight */ | 75 | fid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); |
73 | v9fid = v9fs_fid_lookup(file->f_dentry, FID_OP); | 76 | if (fid == NULL) { |
74 | if (!v9fid) | 77 | dprintk(DEBUG_ERROR, "Out of Memory\n"); |
75 | return -EBADF; | 78 | return -ENOMEM; |
79 | } | ||
76 | 80 | ||
77 | v9fid = v9fs_fid_lookup(dentry->d_parent, FID_WALK); | 81 | fid->fidopen = 0; |
78 | if (!v9fid) | 82 | fid->fidcreate = 0; |
79 | return -EBADF; | 83 | fid->fidclunked = 0; |
84 | fid->iounit = 0; | ||
85 | fid->v9ses = v9ses; | ||
80 | 86 | ||
81 | newfid = v9fs_get_idpool(&v9ses->fidpool); | 87 | newfid = v9fs_get_idpool(&v9ses->fidpool); |
82 | if (newfid < 0) { | 88 | if (newfid < 0) { |
@@ -85,58 +91,16 @@ int v9fs_file_open(struct inode *inode, struct file *file) | |||
85 | } | 91 | } |
86 | 92 | ||
87 | result = | 93 | result = |
88 | v9fs_t_walk(v9ses, v9fid->fid, newfid, | 94 | v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL, NULL); |
89 | (char *)file->f_dentry->d_name.name, NULL); | 95 | |
90 | if (result < 0) { | 96 | if (result < 0) { |
91 | v9fs_put_idpool(newfid, &v9ses->fidpool); | 97 | v9fs_put_idpool(newfid, &v9ses->fidpool); |
92 | dprintk(DEBUG_ERROR, "rewalk didn't work\n"); | 98 | dprintk(DEBUG_ERROR, "rewalk didn't work\n"); |
93 | return -EBADF; | 99 | return -EBADF; |
94 | } | 100 | } |
95 | 101 | ||
96 | v9fid = v9fs_fid_create(dentry); | 102 | fid->fid = newfid; |
97 | if (v9fid == NULL) { | 103 | v9fid = fid; |
98 | dprintk(DEBUG_ERROR, "couldn't insert\n"); | ||
99 | return -ENOMEM; | ||
100 | } | ||
101 | v9fid->fid = newfid; | ||
102 | } | ||
103 | |||
104 | if (v9fid->fidcreate) { | ||
105 | /* create case */ | ||
106 | newfid = v9fid->fid; | ||
107 | iounit = v9fid->iounit; | ||
108 | v9fid->fidcreate = 0; | ||
109 | } else { | ||
110 | if (!S_ISDIR(inode->i_mode)) | ||
111 | newfid = v9fid->fid; | ||
112 | else { | ||
113 | newfid = v9fs_get_idpool(&v9ses->fidpool); | ||
114 | if (newfid < 0) { | ||
115 | eprintk(KERN_WARNING, "allocation failed\n"); | ||
116 | return -ENOSPC; | ||
117 | } | ||
118 | /* This would be a somewhat critical clone */ | ||
119 | result = | ||
120 | v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL, | ||
121 | &fcall); | ||
122 | if (result < 0) { | ||
123 | dprintk(DEBUG_ERROR, "clone error: %s\n", | ||
124 | FCALL_ERROR(fcall)); | ||
125 | kfree(fcall); | ||
126 | return result; | ||
127 | } | ||
128 | |||
129 | v9newfid = v9fs_fid_create(file->f_dentry); | ||
130 | v9newfid->fid = newfid; | ||
131 | v9newfid->qid = v9fid->qid; | ||
132 | v9newfid->iounit = v9fid->iounit; | ||
133 | v9newfid->fidopen = 0; | ||
134 | v9newfid->fidclunked = 0; | ||
135 | v9newfid->v9ses = v9ses; | ||
136 | v9fid = v9newfid; | ||
137 | kfree(fcall); | ||
138 | } | ||
139 | |||
140 | /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ | 104 | /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ |
141 | /* translate open mode appropriately */ | 105 | /* translate open mode appropriately */ |
142 | open_mode = file->f_flags & 0x3; | 106 | open_mode = file->f_flags & 0x3; |
@@ -163,9 +127,13 @@ int v9fs_file_open(struct inode *inode, struct file *file) | |||
163 | 127 | ||
164 | iounit = fcall->params.ropen.iounit; | 128 | iounit = fcall->params.ropen.iounit; |
165 | kfree(fcall); | 129 | kfree(fcall); |
130 | } else { | ||
131 | /* create case */ | ||
132 | newfid = v9fid->fid; | ||
133 | iounit = v9fid->iounit; | ||
134 | v9fid->fidcreate = 0; | ||
166 | } | 135 | } |
167 | 136 | ||
168 | |||
169 | file->private_data = v9fid; | 137 | file->private_data = v9fid; |
170 | 138 | ||
171 | v9fid->rdir_pos = 0; | 139 | v9fid->rdir_pos = 0; |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index b16322db5ce6..2b696ae6655a 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -307,7 +307,7 @@ v9fs_create(struct inode *dir, | |||
307 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); | 307 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); |
308 | struct super_block *sb = dir->i_sb; | 308 | struct super_block *sb = dir->i_sb; |
309 | struct v9fs_fid *dirfid = | 309 | struct v9fs_fid *dirfid = |
310 | v9fs_fid_lookup(file_dentry->d_parent, FID_WALK); | 310 | v9fs_fid_lookup(file_dentry->d_parent); |
311 | struct v9fs_fid *fid = NULL; | 311 | struct v9fs_fid *fid = NULL; |
312 | struct inode *file_inode = NULL; | 312 | struct inode *file_inode = NULL; |
313 | struct v9fs_fcall *fcall = NULL; | 313 | struct v9fs_fcall *fcall = NULL; |
@@ -317,6 +317,7 @@ v9fs_create(struct inode *dir, | |||
317 | long newfid = -1; | 317 | long newfid = -1; |
318 | int result = 0; | 318 | int result = 0; |
319 | unsigned int iounit = 0; | 319 | unsigned int iounit = 0; |
320 | int wfidno = -1; | ||
320 | 321 | ||
321 | perm = unixmode2p9mode(v9ses, perm); | 322 | perm = unixmode2p9mode(v9ses, perm); |
322 | 323 | ||
@@ -350,7 +351,7 @@ v9fs_create(struct inode *dir, | |||
350 | if (result < 0) { | 351 | if (result < 0) { |
351 | dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall)); | 352 | dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall)); |
352 | v9fs_put_idpool(newfid, &v9ses->fidpool); | 353 | v9fs_put_idpool(newfid, &v9ses->fidpool); |
353 | newfid = 0; | 354 | newfid = -1; |
354 | goto CleanUpFid; | 355 | goto CleanUpFid; |
355 | } | 356 | } |
356 | 357 | ||
@@ -369,20 +370,39 @@ v9fs_create(struct inode *dir, | |||
369 | qid = fcall->params.rcreate.qid; | 370 | qid = fcall->params.rcreate.qid; |
370 | kfree(fcall); | 371 | kfree(fcall); |
371 | 372 | ||
372 | fid = v9fs_fid_create(file_dentry); | 373 | fid = v9fs_fid_create(file_dentry, v9ses, newfid, 1); |
374 | dprintk(DEBUG_VFS, "fid %p %d\n", fid, fid->fidcreate); | ||
373 | if (!fid) { | 375 | if (!fid) { |
374 | result = -ENOMEM; | 376 | result = -ENOMEM; |
375 | goto CleanUpFid; | 377 | goto CleanUpFid; |
376 | } | 378 | } |
377 | 379 | ||
378 | fid->fid = newfid; | ||
379 | fid->fidopen = 0; | ||
380 | fid->fidcreate = 1; | ||
381 | fid->qid = qid; | 380 | fid->qid = qid; |
382 | fid->iounit = iounit; | 381 | fid->iounit = iounit; |
383 | fid->rdir_pos = 0; | 382 | |
384 | fid->rdir_fcall = NULL; | 383 | /* walk to the newly created file and put the fid in the dentry */ |
385 | fid->v9ses = v9ses; | 384 | wfidno = v9fs_get_idpool(&v9ses->fidpool); |
385 | if (newfid < 0) { | ||
386 | eprintk(KERN_WARNING, "no free fids available\n"); | ||
387 | return -ENOSPC; | ||
388 | } | ||
389 | |||
390 | result = v9fs_t_walk(v9ses, dirfidnum, wfidno, | ||
391 | (char *) file_dentry->d_name.name, NULL); | ||
392 | if (result < 0) { | ||
393 | dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall)); | ||
394 | v9fs_put_idpool(wfidno, &v9ses->fidpool); | ||
395 | wfidno = -1; | ||
396 | goto CleanUpFid; | ||
397 | } | ||
398 | |||
399 | if (!v9fs_fid_create(file_dentry, v9ses, wfidno, 0)) { | ||
400 | if (!v9fs_t_clunk(v9ses, newfid, &fcall)) { | ||
401 | v9fs_put_idpool(wfidno, &v9ses->fidpool); | ||
402 | } | ||
403 | |||
404 | goto CleanUpFid; | ||
405 | } | ||
386 | 406 | ||
387 | if ((perm & V9FS_DMSYMLINK) || (perm & V9FS_DMLINK) || | 407 | if ((perm & V9FS_DMSYMLINK) || (perm & V9FS_DMLINK) || |
388 | (perm & V9FS_DMNAMEDPIPE) || (perm & V9FS_DMSOCKET) || | 408 | (perm & V9FS_DMNAMEDPIPE) || (perm & V9FS_DMSOCKET) || |
@@ -410,11 +430,11 @@ v9fs_create(struct inode *dir, | |||
410 | d_instantiate(file_dentry, file_inode); | 430 | d_instantiate(file_dentry, file_inode); |
411 | 431 | ||
412 | if (perm & V9FS_DMDIR) { | 432 | if (perm & V9FS_DMDIR) { |
413 | if (v9fs_t_clunk(v9ses, newfid, &fcall)) | 433 | if (!v9fs_t_clunk(v9ses, newfid, &fcall)) |
434 | v9fs_put_idpool(newfid, &v9ses->fidpool); | ||
435 | else | ||
414 | dprintk(DEBUG_ERROR, "clunk for mkdir failed: %s\n", | 436 | dprintk(DEBUG_ERROR, "clunk for mkdir failed: %s\n", |
415 | FCALL_ERROR(fcall)); | 437 | FCALL_ERROR(fcall)); |
416 | |||
417 | v9fs_put_idpool(newfid, &v9ses->fidpool); | ||
418 | kfree(fcall); | 438 | kfree(fcall); |
419 | fid->fidopen = 0; | 439 | fid->fidopen = 0; |
420 | fid->fidcreate = 0; | 440 | fid->fidcreate = 0; |
@@ -426,12 +446,22 @@ v9fs_create(struct inode *dir, | |||
426 | CleanUpFid: | 446 | CleanUpFid: |
427 | kfree(fcall); | 447 | kfree(fcall); |
428 | 448 | ||
429 | if (newfid) { | 449 | if (newfid >= 0) { |
430 | if (v9fs_t_clunk(v9ses, newfid, &fcall)) | 450 | if (!v9fs_t_clunk(v9ses, newfid, &fcall)) |
451 | v9fs_put_idpool(newfid, &v9ses->fidpool); | ||
452 | else | ||
453 | dprintk(DEBUG_ERROR, "clunk failed: %s\n", | ||
454 | FCALL_ERROR(fcall)); | ||
455 | |||
456 | kfree(fcall); | ||
457 | } | ||
458 | if (wfidno >= 0) { | ||
459 | if (!v9fs_t_clunk(v9ses, wfidno, &fcall)) | ||
460 | v9fs_put_idpool(wfidno, &v9ses->fidpool); | ||
461 | else | ||
431 | dprintk(DEBUG_ERROR, "clunk failed: %s\n", | 462 | dprintk(DEBUG_ERROR, "clunk failed: %s\n", |
432 | FCALL_ERROR(fcall)); | 463 | FCALL_ERROR(fcall)); |
433 | 464 | ||
434 | v9fs_put_idpool(newfid, &v9ses->fidpool); | ||
435 | kfree(fcall); | 465 | kfree(fcall); |
436 | } | 466 | } |
437 | return result; | 467 | return result; |
@@ -461,7 +491,7 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) | |||
461 | file_inode = file->d_inode; | 491 | file_inode = file->d_inode; |
462 | sb = file_inode->i_sb; | 492 | sb = file_inode->i_sb; |
463 | v9ses = v9fs_inode2v9ses(file_inode); | 493 | v9ses = v9fs_inode2v9ses(file_inode); |
464 | v9fid = v9fs_fid_lookup(file, FID_OP); | 494 | v9fid = v9fs_fid_lookup(file); |
465 | 495 | ||
466 | if (!v9fid) { | 496 | if (!v9fid) { |
467 | dprintk(DEBUG_ERROR, | 497 | dprintk(DEBUG_ERROR, |
@@ -545,7 +575,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
545 | 575 | ||
546 | sb = dir->i_sb; | 576 | sb = dir->i_sb; |
547 | v9ses = v9fs_inode2v9ses(dir); | 577 | v9ses = v9fs_inode2v9ses(dir); |
548 | dirfid = v9fs_fid_lookup(dentry->d_parent, FID_WALK); | 578 | dirfid = v9fs_fid_lookup(dentry->d_parent); |
549 | 579 | ||
550 | if (!dirfid) { | 580 | if (!dirfid) { |
551 | dprintk(DEBUG_ERROR, "no dirfid\n"); | 581 | dprintk(DEBUG_ERROR, "no dirfid\n"); |
@@ -573,7 +603,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
573 | v9fs_put_idpool(newfid, &v9ses->fidpool); | 603 | v9fs_put_idpool(newfid, &v9ses->fidpool); |
574 | if (result == -ENOENT) { | 604 | if (result == -ENOENT) { |
575 | d_add(dentry, NULL); | 605 | d_add(dentry, NULL); |
576 | dprintk(DEBUG_ERROR, | 606 | dprintk(DEBUG_VFS, |
577 | "Return negative dentry %p count %d\n", | 607 | "Return negative dentry %p count %d\n", |
578 | dentry, atomic_read(&dentry->d_count)); | 608 | dentry, atomic_read(&dentry->d_count)); |
579 | return NULL; | 609 | return NULL; |
@@ -601,16 +631,13 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
601 | 631 | ||
602 | inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat->qid); | 632 | inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat->qid); |
603 | 633 | ||
604 | fid = v9fs_fid_create(dentry); | 634 | fid = v9fs_fid_create(dentry, v9ses, newfid, 0); |
605 | if (fid == NULL) { | 635 | if (fid == NULL) { |
606 | dprintk(DEBUG_ERROR, "couldn't insert\n"); | 636 | dprintk(DEBUG_ERROR, "couldn't insert\n"); |
607 | result = -ENOMEM; | 637 | result = -ENOMEM; |
608 | goto FreeFcall; | 638 | goto FreeFcall; |
609 | } | 639 | } |
610 | 640 | ||
611 | fid->fid = newfid; | ||
612 | fid->fidopen = 0; | ||
613 | fid->v9ses = v9ses; | ||
614 | fid->qid = fcall->params.rstat.stat->qid; | 641 | fid->qid = fcall->params.rstat.stat->qid; |
615 | 642 | ||
616 | dentry->d_op = &v9fs_dentry_operations; | 643 | dentry->d_op = &v9fs_dentry_operations; |
@@ -665,11 +692,11 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
665 | { | 692 | { |
666 | struct inode *old_inode = old_dentry->d_inode; | 693 | struct inode *old_inode = old_dentry->d_inode; |
667 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode); | 694 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode); |
668 | struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry, FID_WALK); | 695 | struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry); |
669 | struct v9fs_fid *olddirfid = | 696 | struct v9fs_fid *olddirfid = |
670 | v9fs_fid_lookup(old_dentry->d_parent, FID_WALK); | 697 | v9fs_fid_lookup(old_dentry->d_parent); |
671 | struct v9fs_fid *newdirfid = | 698 | struct v9fs_fid *newdirfid = |
672 | v9fs_fid_lookup(new_dentry->d_parent, FID_WALK); | 699 | v9fs_fid_lookup(new_dentry->d_parent); |
673 | struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); | 700 | struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); |
674 | struct v9fs_fcall *fcall = NULL; | 701 | struct v9fs_fcall *fcall = NULL; |
675 | int fid = -1; | 702 | int fid = -1; |
@@ -744,7 +771,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
744 | { | 771 | { |
745 | struct v9fs_fcall *fcall = NULL; | 772 | struct v9fs_fcall *fcall = NULL; |
746 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); | 773 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); |
747 | struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP); | 774 | struct v9fs_fid *fid = v9fs_fid_lookup(dentry); |
748 | int err = -EPERM; | 775 | int err = -EPERM; |
749 | 776 | ||
750 | dprintk(DEBUG_VFS, "dentry: %p\n", dentry); | 777 | dprintk(DEBUG_VFS, "dentry: %p\n", dentry); |
@@ -778,7 +805,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
778 | static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) | 805 | static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) |
779 | { | 806 | { |
780 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); | 807 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); |
781 | struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP); | 808 | struct v9fs_fid *fid = v9fs_fid_lookup(dentry); |
782 | struct v9fs_fcall *fcall = NULL; | 809 | struct v9fs_fcall *fcall = NULL; |
783 | struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); | 810 | struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); |
784 | int res = -EPERM; | 811 | int res = -EPERM; |
@@ -960,7 +987,7 @@ v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) | |||
960 | if (retval != 0) | 987 | if (retval != 0) |
961 | goto FreeFcall; | 988 | goto FreeFcall; |
962 | 989 | ||
963 | newfid = v9fs_fid_lookup(dentry, FID_OP); | 990 | newfid = v9fs_fid_lookup(dentry); |
964 | 991 | ||
965 | /* issue a twstat */ | 992 | /* issue a twstat */ |
966 | v9fs_blank_mistat(v9ses, mistat); | 993 | v9fs_blank_mistat(v9ses, mistat); |
@@ -1004,7 +1031,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
1004 | 1031 | ||
1005 | struct v9fs_fcall *fcall = NULL; | 1032 | struct v9fs_fcall *fcall = NULL; |
1006 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); | 1033 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); |
1007 | struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP); | 1034 | struct v9fs_fid *fid = v9fs_fid_lookup(dentry); |
1008 | 1035 | ||
1009 | if (!fid) { | 1036 | if (!fid) { |
1010 | dprintk(DEBUG_ERROR, "could not resolve fid from dentry\n"); | 1037 | dprintk(DEBUG_ERROR, "could not resolve fid from dentry\n"); |
@@ -1148,7 +1175,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1148 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); | 1175 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); |
1149 | struct v9fs_fcall *fcall = NULL; | 1176 | struct v9fs_fcall *fcall = NULL; |
1150 | struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); | 1177 | struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); |
1151 | struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry, FID_OP); | 1178 | struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry); |
1152 | struct v9fs_fid *newfid = NULL; | 1179 | struct v9fs_fid *newfid = NULL; |
1153 | char *symname = __getname(); | 1180 | char *symname = __getname(); |
1154 | 1181 | ||
@@ -1168,7 +1195,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1168 | if (retval != 0) | 1195 | if (retval != 0) |
1169 | goto FreeMem; | 1196 | goto FreeMem; |
1170 | 1197 | ||
1171 | newfid = v9fs_fid_lookup(dentry, FID_OP); | 1198 | newfid = v9fs_fid_lookup(dentry); |
1172 | if (!newfid) { | 1199 | if (!newfid) { |
1173 | dprintk(DEBUG_ERROR, "couldn't resolve fid from dentry\n"); | 1200 | dprintk(DEBUG_ERROR, "couldn't resolve fid from dentry\n"); |
1174 | goto FreeMem; | 1201 | goto FreeMem; |
@@ -1246,7 +1273,7 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) | |||
1246 | if (retval != 0) | 1273 | if (retval != 0) |
1247 | goto FreeMem; | 1274 | goto FreeMem; |
1248 | 1275 | ||
1249 | newfid = v9fs_fid_lookup(dentry, FID_OP); | 1276 | newfid = v9fs_fid_lookup(dentry); |
1250 | if (!newfid) { | 1277 | if (!newfid) { |
1251 | dprintk(DEBUG_ERROR, "coudn't resove fid from dentry\n"); | 1278 | dprintk(DEBUG_ERROR, "coudn't resove fid from dentry\n"); |
1252 | retval = -EINVAL; | 1279 | retval = -EINVAL; |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 1e2b2b54d300..0957f4da91d4 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -129,8 +129,7 @@ static struct super_block *v9fs_get_sb(struct file_system_type | |||
129 | 129 | ||
130 | if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { | 130 | if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { |
131 | dprintk(DEBUG_ERROR, "problem initiating session\n"); | 131 | dprintk(DEBUG_ERROR, "problem initiating session\n"); |
132 | kfree(v9ses); | 132 | return newfid; |
133 | return ERR_PTR(newfid); | ||
134 | } | 133 | } |
135 | 134 | ||
136 | sb = sget(fs_type, NULL, v9fs_set_super, v9ses); | 135 | sb = sget(fs_type, NULL, v9fs_set_super, v9ses); |
@@ -155,23 +154,19 @@ static struct super_block *v9fs_get_sb(struct file_system_type | |||
155 | 154 | ||
156 | sb->s_root = root; | 155 | sb->s_root = root; |
157 | 156 | ||
158 | /* Setup the Root Inode */ | ||
159 | root_fid = v9fs_fid_create(root); | ||
160 | if (root_fid == NULL) { | ||
161 | retval = -ENOMEM; | ||
162 | goto put_back_sb; | ||
163 | } | ||
164 | |||
165 | root_fid->fidopen = 0; | ||
166 | root_fid->v9ses = v9ses; | ||
167 | |||
168 | stat_result = v9fs_t_stat(v9ses, newfid, &fcall); | 157 | stat_result = v9fs_t_stat(v9ses, newfid, &fcall); |
169 | if (stat_result < 0) { | 158 | if (stat_result < 0) { |
170 | dprintk(DEBUG_ERROR, "stat error\n"); | 159 | dprintk(DEBUG_ERROR, "stat error\n"); |
171 | v9fs_t_clunk(v9ses, newfid, NULL); | 160 | v9fs_t_clunk(v9ses, newfid, NULL); |
172 | v9fs_put_idpool(newfid, &v9ses->fidpool); | 161 | v9fs_put_idpool(newfid, &v9ses->fidpool); |
173 | } else { | 162 | } else { |
174 | root_fid->fid = newfid; | 163 | /* Setup the Root Inode */ |
164 | root_fid = v9fs_fid_create(root, v9ses, newfid, 0); | ||
165 | if (root_fid == NULL) { | ||
166 | retval = -ENOMEM; | ||
167 | goto put_back_sb; | ||
168 | } | ||
169 | |||
175 | root_fid->qid = fcall->params.rstat.stat->qid; | 170 | root_fid->qid = fcall->params.rstat.stat->qid; |
176 | root->d_inode->i_ino = | 171 | root->d_inode->i_ino = |
177 | v9fs_qid2ino(&fcall->params.rstat.stat->qid); | 172 | v9fs_qid2ino(&fcall->params.rstat.stat->qid); |
diff --git a/fs/Kconfig b/fs/Kconfig index 068ccea2f184..48f5422cb19a 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -472,6 +472,9 @@ config FUSE_FS | |||
472 | utilities is available from the FUSE homepage: | 472 | utilities is available from the FUSE homepage: |
473 | <http://fuse.sourceforge.net/> | 473 | <http://fuse.sourceforge.net/> |
474 | 474 | ||
475 | See <file:Documentation/filesystems/fuse.txt> for more information. | ||
476 | See <file:Documentation/Changes> for needed library/utility version. | ||
477 | |||
475 | If you want to develop a userspace FS, or if you want to use | 478 | If you want to develop a userspace FS, or if you want to use |
476 | a filesystem based on FUSE, answer Y or M. | 479 | a filesystem based on FUSE, answer Y or M. |
477 | 480 | ||
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 403b90a1213d..4284cd31eba6 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -101,6 +101,10 @@ | |||
101 | /* Maximum number of poll wake up nests we are allowing */ | 101 | /* Maximum number of poll wake up nests we are allowing */ |
102 | #define EP_MAX_POLLWAKE_NESTS 4 | 102 | #define EP_MAX_POLLWAKE_NESTS 4 |
103 | 103 | ||
104 | /* Maximum msec timeout value storeable in a long int */ | ||
105 | #define EP_MAX_MSTIMEO min(1000ULL * MAX_SCHEDULE_TIMEOUT / HZ, (LONG_MAX - 999ULL) / HZ) | ||
106 | |||
107 | |||
104 | struct epoll_filefd { | 108 | struct epoll_filefd { |
105 | struct file *file; | 109 | struct file *file; |
106 | int fd; | 110 | int fd; |
@@ -1506,8 +1510,8 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, | |||
1506 | * and the overflow condition. The passed timeout is in milliseconds, | 1510 | * and the overflow condition. The passed timeout is in milliseconds, |
1507 | * that why (t * HZ) / 1000. | 1511 | * that why (t * HZ) / 1000. |
1508 | */ | 1512 | */ |
1509 | jtimeout = timeout == -1 || timeout > (MAX_SCHEDULE_TIMEOUT - 1000) / HZ ? | 1513 | jtimeout = (timeout < 0 || timeout >= EP_MAX_MSTIMEO) ? |
1510 | MAX_SCHEDULE_TIMEOUT: (timeout * HZ + 999) / 1000; | 1514 | MAX_SCHEDULE_TIMEOUT : (timeout * HZ + 999) / 1000; |
1511 | 1515 | ||
1512 | retry: | 1516 | retry: |
1513 | write_lock_irqsave(&ep->lock, flags); | 1517 | write_lock_irqsave(&ep->lock, flags); |
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index c8d07030c897..e2d6208633a7 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c | |||
@@ -605,27 +605,28 @@ got: | |||
605 | insert_inode_hash(inode); | 605 | insert_inode_hash(inode); |
606 | 606 | ||
607 | if (DQUOT_ALLOC_INODE(inode)) { | 607 | if (DQUOT_ALLOC_INODE(inode)) { |
608 | DQUOT_DROP(inode); | ||
609 | err = -ENOSPC; | 608 | err = -ENOSPC; |
610 | goto fail2; | 609 | goto fail_drop; |
611 | } | 610 | } |
611 | |||
612 | err = ext2_init_acl(inode, dir); | 612 | err = ext2_init_acl(inode, dir); |
613 | if (err) { | 613 | if (err) |
614 | DQUOT_FREE_INODE(inode); | 614 | goto fail_free_drop; |
615 | DQUOT_DROP(inode); | 615 | |
616 | goto fail2; | ||
617 | } | ||
618 | err = ext2_init_security(inode,dir); | 616 | err = ext2_init_security(inode,dir); |
619 | if (err) { | 617 | if (err) |
620 | DQUOT_FREE_INODE(inode); | 618 | goto fail_free_drop; |
621 | goto fail2; | 619 | |
622 | } | ||
623 | mark_inode_dirty(inode); | 620 | mark_inode_dirty(inode); |
624 | ext2_debug("allocating inode %lu\n", inode->i_ino); | 621 | ext2_debug("allocating inode %lu\n", inode->i_ino); |
625 | ext2_preread_inode(inode); | 622 | ext2_preread_inode(inode); |
626 | return inode; | 623 | return inode; |
627 | 624 | ||
628 | fail2: | 625 | fail_free_drop: |
626 | DQUOT_FREE_INODE(inode); | ||
627 | |||
628 | fail_drop: | ||
629 | DQUOT_DROP(inode); | ||
629 | inode->i_flags |= S_NOQUOTA; | 630 | inode->i_flags |= S_NOQUOTA; |
630 | inode->i_nlink = 0; | 631 | inode->i_nlink = 0; |
631 | iput(inode); | 632 | iput(inode); |
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 96552769d039..6549945f9ac1 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c | |||
@@ -597,27 +597,22 @@ got: | |||
597 | 597 | ||
598 | ret = inode; | 598 | ret = inode; |
599 | if(DQUOT_ALLOC_INODE(inode)) { | 599 | if(DQUOT_ALLOC_INODE(inode)) { |
600 | DQUOT_DROP(inode); | ||
601 | err = -EDQUOT; | 600 | err = -EDQUOT; |
602 | goto fail2; | 601 | goto fail_drop; |
603 | } | 602 | } |
603 | |||
604 | err = ext3_init_acl(handle, inode, dir); | 604 | err = ext3_init_acl(handle, inode, dir); |
605 | if (err) { | 605 | if (err) |
606 | DQUOT_FREE_INODE(inode); | 606 | goto fail_free_drop; |
607 | DQUOT_DROP(inode); | 607 | |
608 | goto fail2; | ||
609 | } | ||
610 | err = ext3_init_security(handle,inode, dir); | 608 | err = ext3_init_security(handle,inode, dir); |
611 | if (err) { | 609 | if (err) |
612 | DQUOT_FREE_INODE(inode); | 610 | goto fail_free_drop; |
613 | goto fail2; | 611 | |
614 | } | ||
615 | err = ext3_mark_inode_dirty(handle, inode); | 612 | err = ext3_mark_inode_dirty(handle, inode); |
616 | if (err) { | 613 | if (err) { |
617 | ext3_std_error(sb, err); | 614 | ext3_std_error(sb, err); |
618 | DQUOT_FREE_INODE(inode); | 615 | goto fail_free_drop; |
619 | DQUOT_DROP(inode); | ||
620 | goto fail2; | ||
621 | } | 616 | } |
622 | 617 | ||
623 | ext3_debug("allocating inode %lu\n", inode->i_ino); | 618 | ext3_debug("allocating inode %lu\n", inode->i_ino); |
@@ -631,7 +626,11 @@ really_out: | |||
631 | brelse(bitmap_bh); | 626 | brelse(bitmap_bh); |
632 | return ret; | 627 | return ret; |
633 | 628 | ||
634 | fail2: | 629 | fail_free_drop: |
630 | DQUOT_FREE_INODE(inode); | ||
631 | |||
632 | fail_drop: | ||
633 | DQUOT_DROP(inode); | ||
635 | inode->i_flags |= S_NOQUOTA; | 634 | inode->i_flags |= S_NOQUOTA; |
636 | inode->i_nlink = 0; | 635 | inode->i_nlink = 0; |
637 | iput(inode); | 636 | iput(inode); |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index e79e49b3eec7..29f1e9f6e85c 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -96,6 +96,8 @@ static int fuse_lookup_iget(struct inode *dir, struct dentry *entry, | |||
96 | fuse_lookup_init(req, dir, entry, &outarg); | 96 | fuse_lookup_init(req, dir, entry, &outarg); |
97 | request_send(fc, req); | 97 | request_send(fc, req); |
98 | err = req->out.h.error; | 98 | err = req->out.h.error; |
99 | if (!err && (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID)) | ||
100 | err = -EIO; | ||
99 | if (!err) { | 101 | if (!err) { |
100 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, | 102 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, |
101 | &outarg.attr); | 103 | &outarg.attr); |
@@ -152,6 +154,10 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, | |||
152 | fuse_put_request(fc, req); | 154 | fuse_put_request(fc, req); |
153 | return err; | 155 | return err; |
154 | } | 156 | } |
157 | if (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID) { | ||
158 | fuse_put_request(fc, req); | ||
159 | return -EIO; | ||
160 | } | ||
155 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, | 161 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, |
156 | &outarg.attr); | 162 | &outarg.attr); |
157 | if (!inode) { | 163 | if (!inode) { |
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index c7e9237379c2..83f3322765cd 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog | |||
@@ -29,7 +29,8 @@ ToDo/Notes: | |||
29 | The Windows boot will run chkdsk and then reboot. The user can then | 29 | The Windows boot will run chkdsk and then reboot. The user can then |
30 | immediately boot into Linux rather than having to do a full Windows | 30 | immediately boot into Linux rather than having to do a full Windows |
31 | boot first before rebooting into Linux and we will recognize such a | 31 | boot first before rebooting into Linux and we will recognize such a |
32 | journal and empty it as it is clean by definition. | 32 | journal and empty it as it is clean by definition. Note, this only |
33 | works if chkdsk left the journal in an obviously clean state. | ||
33 | - Support journals ($LogFile) with only one restart page as well as | 34 | - Support journals ($LogFile) with only one restart page as well as |
34 | journals with two different restart pages. We sanity check both and | 35 | journals with two different restart pages. We sanity check both and |
35 | either use the only sane one or the more recent one of the two in the | 36 | either use the only sane one or the more recent one of the two in the |
@@ -94,6 +95,13 @@ ToDo/Notes: | |||
94 | my ways. | 95 | my ways. |
95 | - Fix various bugs in the runlist merging code. (Based on libntfs | 96 | - Fix various bugs in the runlist merging code. (Based on libntfs |
96 | changes by Richard Russon.) | 97 | changes by Richard Russon.) |
98 | - Fix sparse warnings that have crept in over time. | ||
99 | - Change ntfs_cluster_free() to require a write locked runlist on entry | ||
100 | since we otherwise get into a lock reversal deadlock if a read locked | ||
101 | runlist is passed in. In the process also change it to take an ntfs | ||
102 | inode instead of a vfs inode as parameter. | ||
103 | - Fix the definition of the CHKD ntfs record magic. It had an off by | ||
104 | two error causing it to be CHKB instead of CHKD. | ||
97 | 105 | ||
98 | 2.1.23 - Implement extension of resident files and make writing safe as well as | 106 | 2.1.23 - Implement extension of resident files and make writing safe as well as |
99 | many bug fixes, cleanups, and enhancements... | 107 | many bug fixes, cleanups, and enhancements... |
diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h index 609ad1728ce4..01f2dfa39cec 100644 --- a/fs/ntfs/layout.h +++ b/fs/ntfs/layout.h | |||
@@ -123,7 +123,7 @@ enum { | |||
123 | magic_RCRD = const_cpu_to_le32(0x44524352), /* Log record page. */ | 123 | magic_RCRD = const_cpu_to_le32(0x44524352), /* Log record page. */ |
124 | 124 | ||
125 | /* Found in $LogFile/$DATA. (May be found in $MFT/$DATA, also?) */ | 125 | /* Found in $LogFile/$DATA. (May be found in $MFT/$DATA, also?) */ |
126 | magic_CHKD = const_cpu_to_le32(0x424b4843), /* Modified by chkdsk. */ | 126 | magic_CHKD = const_cpu_to_le32(0x444b4843), /* Modified by chkdsk. */ |
127 | 127 | ||
128 | /* Found in all ntfs record containing records. */ | 128 | /* Found in all ntfs record containing records. */ |
129 | magic_BAAD = const_cpu_to_le32(0x44414142), /* Failed multi sector | 129 | magic_BAAD = const_cpu_to_le32(0x44414142), /* Failed multi sector |
@@ -308,10 +308,8 @@ typedef le16 MFT_RECORD_FLAGS; | |||
308 | * The _LE versions are to be applied on little endian MFT_REFs. | 308 | * The _LE versions are to be applied on little endian MFT_REFs. |
309 | * Note: The _LE versions will return a CPU endian formatted value! | 309 | * Note: The _LE versions will return a CPU endian formatted value! |
310 | */ | 310 | */ |
311 | typedef enum { | 311 | #define MFT_REF_MASK_CPU 0x0000ffffffffffffULL |
312 | MFT_REF_MASK_CPU = 0x0000ffffffffffffULL, | 312 | #define MFT_REF_MASK_LE const_cpu_to_le64(0x0000ffffffffffffULL) |
313 | MFT_REF_MASK_LE = const_cpu_to_le64(0x0000ffffffffffffULL), | ||
314 | } MFT_REF_CONSTS; | ||
315 | 313 | ||
316 | typedef u64 MFT_REF; | 314 | typedef u64 MFT_REF; |
317 | typedef le64 leMFT_REF; | 315 | typedef le64 leMFT_REF; |
diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c index 7b5934290685..5af3bf0b7eee 100644 --- a/fs/ntfs/lcnalloc.c +++ b/fs/ntfs/lcnalloc.c | |||
@@ -779,14 +779,13 @@ out: | |||
779 | 779 | ||
780 | /** | 780 | /** |
781 | * __ntfs_cluster_free - free clusters on an ntfs volume | 781 | * __ntfs_cluster_free - free clusters on an ntfs volume |
782 | * @vi: vfs inode whose runlist describes the clusters to free | 782 | * @ni: ntfs inode whose runlist describes the clusters to free |
783 | * @start_vcn: vcn in the runlist of @vi at which to start freeing clusters | 783 | * @start_vcn: vcn in the runlist of @ni at which to start freeing clusters |
784 | * @count: number of clusters to free or -1 for all clusters | 784 | * @count: number of clusters to free or -1 for all clusters |
785 | * @write_locked: true if the runlist is locked for writing | ||
786 | * @is_rollback: true if this is a rollback operation | 785 | * @is_rollback: true if this is a rollback operation |
787 | * | 786 | * |
788 | * Free @count clusters starting at the cluster @start_vcn in the runlist | 787 | * Free @count clusters starting at the cluster @start_vcn in the runlist |
789 | * described by the vfs inode @vi. | 788 | * described by the vfs inode @ni. |
790 | * | 789 | * |
791 | * If @count is -1, all clusters from @start_vcn to the end of the runlist are | 790 | * If @count is -1, all clusters from @start_vcn to the end of the runlist are |
792 | * deallocated. Thus, to completely free all clusters in a runlist, use | 791 | * deallocated. Thus, to completely free all clusters in a runlist, use |
@@ -801,31 +800,28 @@ out: | |||
801 | * Return the number of deallocated clusters (not counting sparse ones) on | 800 | * Return the number of deallocated clusters (not counting sparse ones) on |
802 | * success and -errno on error. | 801 | * success and -errno on error. |
803 | * | 802 | * |
804 | * Locking: - The runlist described by @vi must be locked on entry and is | 803 | * Locking: - The runlist described by @ni must be locked for writing on entry |
805 | * locked on return. Note if the runlist is locked for reading the | 804 | * and is locked on return. Note the runlist may be modified when |
806 | * lock may be dropped and reacquired. Note the runlist may be | 805 | * needed runlist fragments need to be mapped. |
807 | * modified when needed runlist fragments need to be mapped. | ||
808 | * - The volume lcn bitmap must be unlocked on entry and is unlocked | 806 | * - The volume lcn bitmap must be unlocked on entry and is unlocked |
809 | * on return. | 807 | * on return. |
810 | * - This function takes the volume lcn bitmap lock for writing and | 808 | * - This function takes the volume lcn bitmap lock for writing and |
811 | * modifies the bitmap contents. | 809 | * modifies the bitmap contents. |
812 | */ | 810 | */ |
813 | s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count, | 811 | s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count, |
814 | const BOOL write_locked, const BOOL is_rollback) | 812 | const BOOL is_rollback) |
815 | { | 813 | { |
816 | s64 delta, to_free, total_freed, real_freed; | 814 | s64 delta, to_free, total_freed, real_freed; |
817 | ntfs_inode *ni; | ||
818 | ntfs_volume *vol; | 815 | ntfs_volume *vol; |
819 | struct inode *lcnbmp_vi; | 816 | struct inode *lcnbmp_vi; |
820 | runlist_element *rl; | 817 | runlist_element *rl; |
821 | int err; | 818 | int err; |
822 | 819 | ||
823 | BUG_ON(!vi); | 820 | BUG_ON(!ni); |
824 | ntfs_debug("Entering for i_ino 0x%lx, start_vcn 0x%llx, count " | 821 | ntfs_debug("Entering for i_ino 0x%lx, start_vcn 0x%llx, count " |
825 | "0x%llx.%s", vi->i_ino, (unsigned long long)start_vcn, | 822 | "0x%llx.%s", ni->mft_no, (unsigned long long)start_vcn, |
826 | (unsigned long long)count, | 823 | (unsigned long long)count, |
827 | is_rollback ? " (rollback)" : ""); | 824 | is_rollback ? " (rollback)" : ""); |
828 | ni = NTFS_I(vi); | ||
829 | vol = ni->vol; | 825 | vol = ni->vol; |
830 | lcnbmp_vi = vol->lcnbmp_ino; | 826 | lcnbmp_vi = vol->lcnbmp_ino; |
831 | BUG_ON(!lcnbmp_vi); | 827 | BUG_ON(!lcnbmp_vi); |
@@ -843,7 +839,7 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count, | |||
843 | 839 | ||
844 | total_freed = real_freed = 0; | 840 | total_freed = real_freed = 0; |
845 | 841 | ||
846 | rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, write_locked); | 842 | rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, TRUE); |
847 | if (IS_ERR(rl)) { | 843 | if (IS_ERR(rl)) { |
848 | if (!is_rollback) | 844 | if (!is_rollback) |
849 | ntfs_error(vol->sb, "Failed to find first runlist " | 845 | ntfs_error(vol->sb, "Failed to find first runlist " |
@@ -897,7 +893,7 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count, | |||
897 | 893 | ||
898 | /* Attempt to map runlist. */ | 894 | /* Attempt to map runlist. */ |
899 | vcn = rl->vcn; | 895 | vcn = rl->vcn; |
900 | rl = ntfs_attr_find_vcn_nolock(ni, vcn, write_locked); | 896 | rl = ntfs_attr_find_vcn_nolock(ni, vcn, TRUE); |
901 | if (IS_ERR(rl)) { | 897 | if (IS_ERR(rl)) { |
902 | err = PTR_ERR(rl); | 898 | err = PTR_ERR(rl); |
903 | if (!is_rollback) | 899 | if (!is_rollback) |
@@ -965,8 +961,7 @@ err_out: | |||
965 | * If rollback fails, set the volume errors flag, emit an error | 961 | * If rollback fails, set the volume errors flag, emit an error |
966 | * message, and return the error code. | 962 | * message, and return the error code. |
967 | */ | 963 | */ |
968 | delta = __ntfs_cluster_free(vi, start_vcn, total_freed, write_locked, | 964 | delta = __ntfs_cluster_free(ni, start_vcn, total_freed, TRUE); |
969 | TRUE); | ||
970 | if (delta < 0) { | 965 | if (delta < 0) { |
971 | ntfs_error(vol->sb, "Failed to rollback (error %i). Leaving " | 966 | ntfs_error(vol->sb, "Failed to rollback (error %i). Leaving " |
972 | "inconsistent metadata! Unmount and run " | 967 | "inconsistent metadata! Unmount and run " |
diff --git a/fs/ntfs/lcnalloc.h b/fs/ntfs/lcnalloc.h index e4d7fb98d685..a6a8827882e7 100644 --- a/fs/ntfs/lcnalloc.h +++ b/fs/ntfs/lcnalloc.h | |||
@@ -2,7 +2,7 @@ | |||
2 | * lcnalloc.h - Exports for NTFS kernel cluster (de)allocation. Part of the | 2 | * lcnalloc.h - Exports for NTFS kernel cluster (de)allocation. Part of the |
3 | * Linux-NTFS project. | 3 | * Linux-NTFS project. |
4 | * | 4 | * |
5 | * Copyright (c) 2004 Anton Altaparmakov | 5 | * Copyright (c) 2004-2005 Anton Altaparmakov |
6 | * | 6 | * |
7 | * This program/include file is free software; you can redistribute it and/or | 7 | * This program/include file is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License as published | 8 | * modify it under the terms of the GNU General Public License as published |
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | 29 | ||
30 | #include "types.h" | 30 | #include "types.h" |
31 | #include "inode.h" | ||
31 | #include "runlist.h" | 32 | #include "runlist.h" |
32 | #include "volume.h" | 33 | #include "volume.h" |
33 | 34 | ||
@@ -42,18 +43,17 @@ extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, | |||
42 | const VCN start_vcn, const s64 count, const LCN start_lcn, | 43 | const VCN start_vcn, const s64 count, const LCN start_lcn, |
43 | const NTFS_CLUSTER_ALLOCATION_ZONES zone); | 44 | const NTFS_CLUSTER_ALLOCATION_ZONES zone); |
44 | 45 | ||
45 | extern s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, | 46 | extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, |
46 | s64 count, const BOOL write_locked, const BOOL is_rollback); | 47 | s64 count, const BOOL is_rollback); |
47 | 48 | ||
48 | /** | 49 | /** |
49 | * ntfs_cluster_free - free clusters on an ntfs volume | 50 | * ntfs_cluster_free - free clusters on an ntfs volume |
50 | * @vi: vfs inode whose runlist describes the clusters to free | 51 | * @ni: ntfs inode whose runlist describes the clusters to free |
51 | * @start_vcn: vcn in the runlist of @vi at which to start freeing clusters | 52 | * @start_vcn: vcn in the runlist of @ni at which to start freeing clusters |
52 | * @count: number of clusters to free or -1 for all clusters | 53 | * @count: number of clusters to free or -1 for all clusters |
53 | * @write_locked: true if the runlist is locked for writing | ||
54 | * | 54 | * |
55 | * Free @count clusters starting at the cluster @start_vcn in the runlist | 55 | * Free @count clusters starting at the cluster @start_vcn in the runlist |
56 | * described by the vfs inode @vi. | 56 | * described by the ntfs inode @ni. |
57 | * | 57 | * |
58 | * If @count is -1, all clusters from @start_vcn to the end of the runlist are | 58 | * If @count is -1, all clusters from @start_vcn to the end of the runlist are |
59 | * deallocated. Thus, to completely free all clusters in a runlist, use | 59 | * deallocated. Thus, to completely free all clusters in a runlist, use |
@@ -65,19 +65,18 @@ extern s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, | |||
65 | * Return the number of deallocated clusters (not counting sparse ones) on | 65 | * Return the number of deallocated clusters (not counting sparse ones) on |
66 | * success and -errno on error. | 66 | * success and -errno on error. |
67 | * | 67 | * |
68 | * Locking: - The runlist described by @vi must be locked on entry and is | 68 | * Locking: - The runlist described by @ni must be locked for writing on entry |
69 | * locked on return. Note if the runlist is locked for reading the | 69 | * and is locked on return. Note the runlist may be modified when |
70 | * lock may be dropped and reacquired. Note the runlist may be | 70 | * needed runlist fragments need to be mapped. |
71 | * modified when needed runlist fragments need to be mapped. | ||
72 | * - The volume lcn bitmap must be unlocked on entry and is unlocked | 71 | * - The volume lcn bitmap must be unlocked on entry and is unlocked |
73 | * on return. | 72 | * on return. |
74 | * - This function takes the volume lcn bitmap lock for writing and | 73 | * - This function takes the volume lcn bitmap lock for writing and |
75 | * modifies the bitmap contents. | 74 | * modifies the bitmap contents. |
76 | */ | 75 | */ |
77 | static inline s64 ntfs_cluster_free(struct inode *vi, const VCN start_vcn, | 76 | static inline s64 ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, |
78 | s64 count, const BOOL write_locked) | 77 | s64 count) |
79 | { | 78 | { |
80 | return __ntfs_cluster_free(vi, start_vcn, count, write_locked, FALSE); | 79 | return __ntfs_cluster_free(ni, start_vcn, count, FALSE); |
81 | } | 80 | } |
82 | 81 | ||
83 | extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, | 82 | extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, |
diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c index 0173e95500d9..0fd70295cca6 100644 --- a/fs/ntfs/logfile.c +++ b/fs/ntfs/logfile.c | |||
@@ -51,7 +51,8 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, | |||
51 | RESTART_PAGE_HEADER *rp, s64 pos) | 51 | RESTART_PAGE_HEADER *rp, s64 pos) |
52 | { | 52 | { |
53 | u32 logfile_system_page_size, logfile_log_page_size; | 53 | u32 logfile_system_page_size, logfile_log_page_size; |
54 | u16 usa_count, usa_ofs, usa_end, ra_ofs; | 54 | u16 ra_ofs, usa_count, usa_ofs, usa_end = 0; |
55 | BOOL have_usa = TRUE; | ||
55 | 56 | ||
56 | ntfs_debug("Entering."); | 57 | ntfs_debug("Entering."); |
57 | /* | 58 | /* |
@@ -86,6 +87,14 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, | |||
86 | (int)sle16_to_cpu(rp->minor_ver)); | 87 | (int)sle16_to_cpu(rp->minor_ver)); |
87 | return FALSE; | 88 | return FALSE; |
88 | } | 89 | } |
90 | /* | ||
91 | * If chkdsk has been run the restart page may not be protected by an | ||
92 | * update sequence array. | ||
93 | */ | ||
94 | if (ntfs_is_chkd_record(rp->magic) && !le16_to_cpu(rp->usa_count)) { | ||
95 | have_usa = FALSE; | ||
96 | goto skip_usa_checks; | ||
97 | } | ||
89 | /* Verify the size of the update sequence array. */ | 98 | /* Verify the size of the update sequence array. */ |
90 | usa_count = 1 + (logfile_system_page_size >> NTFS_BLOCK_SIZE_BITS); | 99 | usa_count = 1 + (logfile_system_page_size >> NTFS_BLOCK_SIZE_BITS); |
91 | if (usa_count != le16_to_cpu(rp->usa_count)) { | 100 | if (usa_count != le16_to_cpu(rp->usa_count)) { |
@@ -102,6 +111,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, | |||
102 | "inconsistent update sequence array offset."); | 111 | "inconsistent update sequence array offset."); |
103 | return FALSE; | 112 | return FALSE; |
104 | } | 113 | } |
114 | skip_usa_checks: | ||
105 | /* | 115 | /* |
106 | * Verify the position of the restart area. It must be: | 116 | * Verify the position of the restart area. It must be: |
107 | * - aligned to 8-byte boundary, | 117 | * - aligned to 8-byte boundary, |
@@ -109,7 +119,8 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, | |||
109 | * - within the system page size. | 119 | * - within the system page size. |
110 | */ | 120 | */ |
111 | ra_ofs = le16_to_cpu(rp->restart_area_offset); | 121 | ra_ofs = le16_to_cpu(rp->restart_area_offset); |
112 | if (ra_ofs & 7 || ra_ofs < usa_end || | 122 | if (ra_ofs & 7 || (have_usa ? ra_ofs < usa_end : |
123 | ra_ofs < sizeof(RESTART_PAGE_HEADER)) || | ||
113 | ra_ofs > logfile_system_page_size) { | 124 | ra_ofs > logfile_system_page_size) { |
114 | ntfs_error(vi->i_sb, "$LogFile restart page specifies " | 125 | ntfs_error(vi->i_sb, "$LogFile restart page specifies " |
115 | "inconsistent restart area offset."); | 126 | "inconsistent restart area offset."); |
@@ -402,8 +413,12 @@ static int ntfs_check_and_load_restart_page(struct inode *vi, | |||
402 | idx++; | 413 | idx++; |
403 | } while (to_read > 0); | 414 | } while (to_read > 0); |
404 | } | 415 | } |
405 | /* Perform the multi sector transfer deprotection on the buffer. */ | 416 | /* |
406 | if (post_read_mst_fixup((NTFS_RECORD*)trp, | 417 | * Perform the multi sector transfer deprotection on the buffer if the |
418 | * restart page is protected. | ||
419 | */ | ||
420 | if ((!ntfs_is_chkd_record(trp->magic) || le16_to_cpu(trp->usa_count)) | ||
421 | && post_read_mst_fixup((NTFS_RECORD*)trp, | ||
407 | le32_to_cpu(rp->system_page_size))) { | 422 | le32_to_cpu(rp->system_page_size))) { |
408 | /* | 423 | /* |
409 | * A multi sector tranfer error was detected. We only need to | 424 | * A multi sector tranfer error was detected. We only need to |
@@ -615,11 +630,16 @@ is_empty: | |||
615 | * Otherwise just throw it away. | 630 | * Otherwise just throw it away. |
616 | */ | 631 | */ |
617 | if (rstr2_lsn > rstr1_lsn) { | 632 | if (rstr2_lsn > rstr1_lsn) { |
633 | ntfs_debug("Using second restart page as it is more " | ||
634 | "recent."); | ||
618 | ntfs_free(rstr1_ph); | 635 | ntfs_free(rstr1_ph); |
619 | rstr1_ph = rstr2_ph; | 636 | rstr1_ph = rstr2_ph; |
620 | /* rstr1_lsn = rstr2_lsn; */ | 637 | /* rstr1_lsn = rstr2_lsn; */ |
621 | } else | 638 | } else { |
639 | ntfs_debug("Using first restart page as it is more " | ||
640 | "recent."); | ||
622 | ntfs_free(rstr2_ph); | 641 | ntfs_free(rstr2_ph); |
642 | } | ||
623 | rstr2_ph = NULL; | 643 | rstr2_ph = NULL; |
624 | } | 644 | } |
625 | /* All consistency checks passed. */ | 645 | /* All consistency checks passed. */ |
diff --git a/fs/ntfs/logfile.h b/fs/ntfs/logfile.h index 42388f95ea6d..a51f3dd0e9eb 100644 --- a/fs/ntfs/logfile.h +++ b/fs/ntfs/logfile.h | |||
@@ -113,7 +113,7 @@ typedef struct { | |||
113 | */ | 113 | */ |
114 | enum { | 114 | enum { |
115 | RESTART_VOLUME_IS_CLEAN = const_cpu_to_le16(0x0002), | 115 | RESTART_VOLUME_IS_CLEAN = const_cpu_to_le16(0x0002), |
116 | RESTART_SPACE_FILLER = 0xffff, /* gcc: Force enum bit width to 16. */ | 116 | RESTART_SPACE_FILLER = const_cpu_to_le16(0xffff), /* gcc: Force enum bit width to 16. */ |
117 | } __attribute__ ((__packed__)); | 117 | } __attribute__ ((__packed__)); |
118 | 118 | ||
119 | typedef le16 RESTART_AREA_FLAGS; | 119 | typedef le16 RESTART_AREA_FLAGS; |
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c index 2c32b84385a8..247586d1d5dc 100644 --- a/fs/ntfs/mft.c +++ b/fs/ntfs/mft.c | |||
@@ -1953,7 +1953,7 @@ restore_undo_alloc: | |||
1953 | a = ctx->attr; | 1953 | a = ctx->attr; |
1954 | a->data.non_resident.highest_vcn = cpu_to_sle64(old_last_vcn - 1); | 1954 | a->data.non_resident.highest_vcn = cpu_to_sle64(old_last_vcn - 1); |
1955 | undo_alloc: | 1955 | undo_alloc: |
1956 | if (ntfs_cluster_free(vol->mft_ino, old_last_vcn, -1, TRUE) < 0) { | 1956 | if (ntfs_cluster_free(mft_ni, old_last_vcn, -1) < 0) { |
1957 | ntfs_error(vol->sb, "Failed to free clusters from mft data " | 1957 | ntfs_error(vol->sb, "Failed to free clusters from mft data " |
1958 | "attribute.%s", es); | 1958 | "attribute.%s", es); |
1959 | NVolSetErrors(vol); | 1959 | NVolSetErrors(vol); |
diff --git a/include/asm-arm/arch-s3c2410/anubis-map.h b/include/asm-arm/arch-s3c2410/anubis-map.h index 97741d6e506a..d529ffda8599 100644 --- a/include/asm-arm/arch-s3c2410/anubis-map.h +++ b/include/asm-arm/arch-s3c2410/anubis-map.h | |||
@@ -20,22 +20,22 @@ | |||
20 | 20 | ||
21 | /* start peripherals off after the S3C2410 */ | 21 | /* start peripherals off after the S3C2410 */ |
22 | 22 | ||
23 | #define ANUBIS_IOADDR(x) (S3C2410_ADDR((x) + 0x02000000)) | 23 | #define ANUBIS_IOADDR(x) (S3C2410_ADDR((x) + 0x01800000)) |
24 | 24 | ||
25 | #define ANUBIS_PA_CPLD (S3C2410_CS1 | (1<<26)) | 25 | #define ANUBIS_PA_CPLD (S3C2410_CS1 | (1<<26)) |
26 | 26 | ||
27 | /* we put the CPLD registers next, to get them out of the way */ | 27 | /* we put the CPLD registers next, to get them out of the way */ |
28 | 28 | ||
29 | #define ANUBIS_VA_CTRL1 ANUBIS_IOADDR(0x00000000) /* 0x01300000 */ | 29 | #define ANUBIS_VA_CTRL1 ANUBIS_IOADDR(0x00000000) /* 0x01800000 */ |
30 | #define ANUBIS_PA_CTRL1 (ANUBIS_PA_CPLD) | 30 | #define ANUBIS_PA_CTRL1 (ANUBIS_PA_CPLD) |
31 | 31 | ||
32 | #define ANUBIS_VA_CTRL2 ANUBIS_IOADDR(0x00100000) /* 0x01400000 */ | 32 | #define ANUBIS_VA_CTRL2 ANUBIS_IOADDR(0x00100000) /* 0x01900000 */ |
33 | #define ANUBIS_PA_CTRL2 (ANUBIS_PA_CPLD) | 33 | #define ANUBIS_PA_CTRL2 (ANUBIS_PA_CPLD) |
34 | 34 | ||
35 | #define ANUBIS_VA_CTRL3 ANUBIS_IOADDR(0x00200000) /* 0x01500000 */ | 35 | #define ANUBIS_VA_CTRL3 ANUBIS_IOADDR(0x00200000) /* 0x01A00000 */ |
36 | #define ANUBIS_PA_CTRL3 (ANUBIS_PA_CPLD) | 36 | #define ANUBIS_PA_CTRL3 (ANUBIS_PA_CPLD) |
37 | 37 | ||
38 | #define ANUBIS_VA_CTRL4 ANUBIS_IOADDR(0x00300000) /* 0x01600000 */ | 38 | #define ANUBIS_VA_CTRL4 ANUBIS_IOADDR(0x00300000) /* 0x01B00000 */ |
39 | #define ANUBIS_PA_CTRL4 (ANUBIS_PA_CPLD) | 39 | #define ANUBIS_PA_CTRL4 (ANUBIS_PA_CPLD) |
40 | 40 | ||
41 | #define ANUBIS_IDEPRI ANUBIS_IOADDR(0x01000000) | 41 | #define ANUBIS_IDEPRI ANUBIS_IOADDR(0x01000000) |
diff --git a/include/asm-arm/signal.h b/include/asm-arm/signal.h index 760f6e65af05..ced69161917b 100644 --- a/include/asm-arm/signal.h +++ b/include/asm-arm/signal.h | |||
@@ -115,7 +115,6 @@ typedef unsigned long sigset_t; | |||
115 | 115 | ||
116 | #ifdef __KERNEL__ | 116 | #ifdef __KERNEL__ |
117 | #define SA_TIMER 0x40000000 | 117 | #define SA_TIMER 0x40000000 |
118 | #define SA_IRQNOMASK 0x08000000 | ||
119 | #endif | 118 | #endif |
120 | 119 | ||
121 | #include <asm-generic/signal.h> | 120 | #include <asm-generic/signal.h> |
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index f86c1e549466..ff28c8b31f58 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h | |||
@@ -158,6 +158,19 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres | |||
158 | #define lazy_mmu_prot_update(pte) do { } while (0) | 158 | #define lazy_mmu_prot_update(pte) do { } while (0) |
159 | #endif | 159 | #endif |
160 | 160 | ||
161 | #ifndef __HAVE_ARCH_MULTIPLE_ZERO_PAGE | ||
162 | #define move_pte(pte, prot, old_addr, new_addr) (pte) | ||
163 | #else | ||
164 | #define move_pte(pte, prot, old_addr, new_addr) \ | ||
165 | ({ \ | ||
166 | pte_t newpte = (pte); \ | ||
167 | if (pte_present(pte) && pfn_valid(pte_pfn(pte)) && \ | ||
168 | pte_page(pte) == ZERO_PAGE(old_addr)) \ | ||
169 | newpte = mk_pte(ZERO_PAGE(new_addr), (prot)); \ | ||
170 | newpte; \ | ||
171 | }) | ||
172 | #endif | ||
173 | |||
161 | /* | 174 | /* |
162 | * When walking page tables, get the address of the next boundary, | 175 | * When walking page tables, get the address of the next boundary, |
163 | * or the end address of the range if that comes earlier. Although no | 176 | * or the end address of the range if that comes earlier. Although no |
diff --git a/include/asm-m32r/io.h b/include/asm-m32r/io.h index 8e9e481e6996..70ad1c949c2b 100644 --- a/include/asm-m32r/io.h +++ b/include/asm-m32r/io.h | |||
@@ -60,7 +60,7 @@ __ioremap(unsigned long offset, unsigned long size, unsigned long flags); | |||
60 | * address. | 60 | * address. |
61 | */ | 61 | */ |
62 | 62 | ||
63 | static inline void * ioremap(unsigned long offset, unsigned long size) | 63 | static inline void __iomem *ioremap(unsigned long offset, unsigned long size) |
64 | { | 64 | { |
65 | return __ioremap(offset, size, 0); | 65 | return __ioremap(offset, size, 0); |
66 | } | 66 | } |
diff --git a/include/asm-m32r/uaccess.h b/include/asm-m32r/uaccess.h index 93d863c455a1..0da7c47d2f01 100644 --- a/include/asm-m32r/uaccess.h +++ b/include/asm-m32r/uaccess.h | |||
@@ -208,7 +208,8 @@ extern void __get_user_4(void); | |||
208 | * On error, the variable @x is set to zero. | 208 | * On error, the variable @x is set to zero. |
209 | */ | 209 | */ |
210 | #define get_user(x,ptr) \ | 210 | #define get_user(x,ptr) \ |
211 | ({ int __ret_gu,__val_gu; \ | 211 | ({ int __ret_gu; \ |
212 | unsigned long __val_gu; \ | ||
212 | __chk_user_ptr(ptr); \ | 213 | __chk_user_ptr(ptr); \ |
213 | switch(sizeof (*(ptr))) { \ | 214 | switch(sizeof (*(ptr))) { \ |
214 | case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \ | 215 | case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \ |
@@ -403,7 +404,8 @@ struct __large_struct { unsigned long buf[100]; }; | |||
403 | 404 | ||
404 | #define __get_user_nocheck(x,ptr,size) \ | 405 | #define __get_user_nocheck(x,ptr,size) \ |
405 | ({ \ | 406 | ({ \ |
406 | long __gu_err, __gu_val; \ | 407 | long __gu_err; \ |
408 | unsigned long __gu_val; \ | ||
407 | __get_user_size(__gu_val,(ptr),(size),__gu_err); \ | 409 | __get_user_size(__gu_val,(ptr),(size),__gu_err); \ |
408 | (x) = (__typeof__(*(ptr)))__gu_val; \ | 410 | (x) = (__typeof__(*(ptr)))__gu_val; \ |
409 | __gu_err; \ | 411 | __gu_err; \ |
@@ -594,8 +596,8 @@ static inline unsigned long __generic_copy_to_user_nocheck(void __user *to, | |||
594 | return n; | 596 | return n; |
595 | } | 597 | } |
596 | 598 | ||
597 | unsigned long __generic_copy_to_user(void *, const void *, unsigned long); | 599 | unsigned long __generic_copy_to_user(void __user *, const void *, unsigned long); |
598 | unsigned long __generic_copy_from_user(void *, const void *, unsigned long); | 600 | unsigned long __generic_copy_from_user(void *, const void __user *, unsigned long); |
599 | 601 | ||
600 | /** | 602 | /** |
601 | * __copy_to_user: - Copy a block of data into user space, with less checking. | 603 | * __copy_to_user: - Copy a block of data into user space, with less checking. |
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h index cbd1672c94cb..eaf5d9b3a0e1 100644 --- a/include/asm-mips/pgtable.h +++ b/include/asm-mips/pgtable.h | |||
@@ -68,6 +68,8 @@ extern unsigned long zero_page_mask; | |||
68 | #define ZERO_PAGE(vaddr) \ | 68 | #define ZERO_PAGE(vaddr) \ |
69 | (virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask))) | 69 | (virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask))) |
70 | 70 | ||
71 | #define __HAVE_ARCH_MULTIPLE_ZERO_PAGE | ||
72 | |||
71 | extern void paging_init(void); | 73 | extern void paging_init(void); |
72 | 74 | ||
73 | /* | 75 | /* |
diff --git a/include/asm-ppc64/tlbflush.h b/include/asm-ppc64/tlbflush.h index 800bc0010cfb..626f505c6ee3 100644 --- a/include/asm-ppc64/tlbflush.h +++ b/include/asm-ppc64/tlbflush.h | |||
@@ -23,6 +23,7 @@ struct ppc64_tlb_batch { | |||
23 | struct mm_struct *mm; | 23 | struct mm_struct *mm; |
24 | pte_t pte[PPC64_TLB_BATCH_NR]; | 24 | pte_t pte[PPC64_TLB_BATCH_NR]; |
25 | unsigned long vaddr[PPC64_TLB_BATCH_NR]; | 25 | unsigned long vaddr[PPC64_TLB_BATCH_NR]; |
26 | unsigned int large; | ||
26 | }; | 27 | }; |
27 | DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); | 28 | DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); |
28 | 29 | ||
diff --git a/include/asm-sparc64/cacheflush.h b/include/asm-sparc64/cacheflush.h index ededd2659eab..b3f61659ba81 100644 --- a/include/asm-sparc64/cacheflush.h +++ b/include/asm-sparc64/cacheflush.h | |||
@@ -66,6 +66,11 @@ extern void flush_ptrace_access(struct vm_area_struct *, struct page *, | |||
66 | #define flush_cache_vmap(start, end) do { } while (0) | 66 | #define flush_cache_vmap(start, end) do { } while (0) |
67 | #define flush_cache_vunmap(start, end) do { } while (0) | 67 | #define flush_cache_vunmap(start, end) do { } while (0) |
68 | 68 | ||
69 | #ifdef CONFIG_DEBUG_PAGEALLOC | ||
70 | /* internal debugging function */ | ||
71 | void kernel_map_pages(struct page *page, int numpages, int enable); | ||
72 | #endif | ||
73 | |||
69 | #endif /* !__ASSEMBLY__ */ | 74 | #endif /* !__ASSEMBLY__ */ |
70 | 75 | ||
71 | #endif /* _SPARC64_CACHEFLUSH_H */ | 76 | #endif /* _SPARC64_CACHEFLUSH_H */ |
diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 9a3a81f1cc58..74de79dca915 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h | |||
@@ -22,6 +22,16 @@ typedef struct { | |||
22 | unsigned int __pad1; | 22 | unsigned int __pad1; |
23 | unsigned long *pte_cache[2]; | 23 | unsigned long *pte_cache[2]; |
24 | unsigned long *pgd_cache; | 24 | unsigned long *pgd_cache; |
25 | |||
26 | /* Dcache line 3, rarely used */ | ||
27 | unsigned int dcache_size; | ||
28 | unsigned int dcache_line_size; | ||
29 | unsigned int icache_size; | ||
30 | unsigned int icache_line_size; | ||
31 | unsigned int ecache_size; | ||
32 | unsigned int ecache_line_size; | ||
33 | unsigned int __pad2; | ||
34 | unsigned int __pad3; | ||
25 | } cpuinfo_sparc; | 35 | } cpuinfo_sparc; |
26 | 36 | ||
27 | DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data); | 37 | DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data); |
diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h index a432d9e7daaa..c628189b6c89 100644 --- a/include/asm-sparc64/oplib.h +++ b/include/asm-sparc64/oplib.h | |||
@@ -38,6 +38,20 @@ extern int prom_stdin, prom_stdout; | |||
38 | */ | 38 | */ |
39 | extern int prom_chosen_node; | 39 | extern int prom_chosen_node; |
40 | 40 | ||
41 | /* Helper values and strings in arch/sparc64/kernel/head.S */ | ||
42 | extern const char prom_finddev_name[]; | ||
43 | extern const char prom_chosen_path[]; | ||
44 | extern const char prom_getprop_name[]; | ||
45 | extern const char prom_mmu_name[]; | ||
46 | extern const char prom_callmethod_name[]; | ||
47 | extern const char prom_translate_name[]; | ||
48 | extern const char prom_map_name[]; | ||
49 | extern const char prom_unmap_name[]; | ||
50 | extern int prom_mmu_ihandle_cache; | ||
51 | extern unsigned int prom_boot_mapped_pc; | ||
52 | extern unsigned int prom_boot_mapping_mode; | ||
53 | extern unsigned long prom_boot_mapping_phys_high, prom_boot_mapping_phys_low; | ||
54 | |||
41 | struct linux_mlist_p1275 { | 55 | struct linux_mlist_p1275 { |
42 | struct linux_mlist_p1275 *theres_more; | 56 | struct linux_mlist_p1275 *theres_more; |
43 | unsigned long start_adr; | 57 | unsigned long start_adr; |
@@ -68,7 +82,7 @@ extern char *prom_getbootargs(void); | |||
68 | * of the string is different on V0 vs. V2->higher proms. The caller must | 82 | * of the string is different on V0 vs. V2->higher proms. The caller must |
69 | * know what he/she is doing! Returns the device descriptor, an int. | 83 | * know what he/she is doing! Returns the device descriptor, an int. |
70 | */ | 84 | */ |
71 | extern int prom_devopen(char *device_string); | 85 | extern int prom_devopen(const char *device_string); |
72 | 86 | ||
73 | /* Close a previously opened device described by the passed integer | 87 | /* Close a previously opened device described by the passed integer |
74 | * descriptor. | 88 | * descriptor. |
@@ -98,10 +112,10 @@ extern struct linux_mem_p1275 *prom_meminfo(void); | |||
98 | /* Miscellaneous routines, don't really fit in any category per se. */ | 112 | /* Miscellaneous routines, don't really fit in any category per se. */ |
99 | 113 | ||
100 | /* Reboot the machine with the command line passed. */ | 114 | /* Reboot the machine with the command line passed. */ |
101 | extern void prom_reboot(char *boot_command); | 115 | extern void prom_reboot(const char *boot_command); |
102 | 116 | ||
103 | /* Evaluate the forth string passed. */ | 117 | /* Evaluate the forth string passed. */ |
104 | extern void prom_feval(char *forth_string); | 118 | extern void prom_feval(const char *forth_string); |
105 | 119 | ||
106 | /* Enter the prom, with possibility of continuation with the 'go' | 120 | /* Enter the prom, with possibility of continuation with the 'go' |
107 | * command in newer proms. | 121 | * command in newer proms. |
@@ -154,7 +168,7 @@ extern char prom_getchar(void); | |||
154 | extern void prom_putchar(char character); | 168 | extern void prom_putchar(char character); |
155 | 169 | ||
156 | /* Prom's internal routines, don't use in kernel/boot code. */ | 170 | /* Prom's internal routines, don't use in kernel/boot code. */ |
157 | extern void prom_printf(char *fmt, ...); | 171 | extern void prom_printf(const char *fmt, ...); |
158 | extern void prom_write(const char *buf, unsigned int len); | 172 | extern void prom_write(const char *buf, unsigned int len); |
159 | 173 | ||
160 | /* Query for input device type */ | 174 | /* Query for input device type */ |
@@ -215,7 +229,7 @@ extern int prom_getunumber(int syndrome_code, | |||
215 | char *buf, int buflen); | 229 | char *buf, int buflen); |
216 | 230 | ||
217 | /* Retain physical memory to the caller across soft resets. */ | 231 | /* Retain physical memory to the caller across soft resets. */ |
218 | extern unsigned long prom_retain(char *name, | 232 | extern unsigned long prom_retain(const char *name, |
219 | unsigned long pa_low, unsigned long pa_high, | 233 | unsigned long pa_low, unsigned long pa_high, |
220 | long size, long align); | 234 | long size, long align); |
221 | 235 | ||
@@ -269,28 +283,28 @@ extern int prom_getsibling(int node); | |||
269 | /* Get the length, at the passed node, of the given property type. | 283 | /* Get the length, at the passed node, of the given property type. |
270 | * Returns -1 on error (ie. no such property at this node). | 284 | * Returns -1 on error (ie. no such property at this node). |
271 | */ | 285 | */ |
272 | extern int prom_getproplen(int thisnode, char *property); | 286 | extern int prom_getproplen(int thisnode, const char *property); |
273 | 287 | ||
274 | /* Fetch the requested property using the given buffer. Returns | 288 | /* Fetch the requested property using the given buffer. Returns |
275 | * the number of bytes the prom put into your buffer or -1 on error. | 289 | * the number of bytes the prom put into your buffer or -1 on error. |
276 | */ | 290 | */ |
277 | extern int prom_getproperty(int thisnode, char *property, | 291 | extern int prom_getproperty(int thisnode, const char *property, |
278 | char *prop_buffer, int propbuf_size); | 292 | char *prop_buffer, int propbuf_size); |
279 | 293 | ||
280 | /* Acquire an integer property. */ | 294 | /* Acquire an integer property. */ |
281 | extern int prom_getint(int node, char *property); | 295 | extern int prom_getint(int node, const char *property); |
282 | 296 | ||
283 | /* Acquire an integer property, with a default value. */ | 297 | /* Acquire an integer property, with a default value. */ |
284 | extern int prom_getintdefault(int node, char *property, int defval); | 298 | extern int prom_getintdefault(int node, const char *property, int defval); |
285 | 299 | ||
286 | /* Acquire a boolean property, 0=FALSE 1=TRUE. */ | 300 | /* Acquire a boolean property, 0=FALSE 1=TRUE. */ |
287 | extern int prom_getbool(int node, char *prop); | 301 | extern int prom_getbool(int node, const char *prop); |
288 | 302 | ||
289 | /* Acquire a string property, null string on error. */ | 303 | /* Acquire a string property, null string on error. */ |
290 | extern void prom_getstring(int node, char *prop, char *buf, int bufsize); | 304 | extern void prom_getstring(int node, const char *prop, char *buf, int bufsize); |
291 | 305 | ||
292 | /* Does the passed node have the given "name"? YES=1 NO=0 */ | 306 | /* Does the passed node have the given "name"? YES=1 NO=0 */ |
293 | extern int prom_nodematch(int thisnode, char *name); | 307 | extern int prom_nodematch(int thisnode, const char *name); |
294 | 308 | ||
295 | /* Puts in buffer a prom name in the form name@x,y or name (x for which_io | 309 | /* Puts in buffer a prom name in the form name@x,y or name (x for which_io |
296 | * and y for first regs phys address | 310 | * and y for first regs phys address |
@@ -300,7 +314,7 @@ extern int prom_getname(int node, char *buf, int buflen); | |||
300 | /* Search all siblings starting at the passed node for "name" matching | 314 | /* Search all siblings starting at the passed node for "name" matching |
301 | * the given string. Returns the node on success, zero on failure. | 315 | * the given string. Returns the node on success, zero on failure. |
302 | */ | 316 | */ |
303 | extern int prom_searchsiblings(int node_start, char *name); | 317 | extern int prom_searchsiblings(int node_start, const char *name); |
304 | 318 | ||
305 | /* Return the first property type, as a string, for the given node. | 319 | /* Return the first property type, as a string, for the given node. |
306 | * Returns a null string on error. Buffer should be at least 32B long. | 320 | * Returns a null string on error. Buffer should be at least 32B long. |
@@ -310,21 +324,21 @@ extern char *prom_firstprop(int node, char *buffer); | |||
310 | /* Returns the next property after the passed property for the given | 324 | /* Returns the next property after the passed property for the given |
311 | * node. Returns null string on failure. Buffer should be at least 32B long. | 325 | * node. Returns null string on failure. Buffer should be at least 32B long. |
312 | */ | 326 | */ |
313 | extern char *prom_nextprop(int node, char *prev_property, char *buffer); | 327 | extern char *prom_nextprop(int node, const char *prev_property, char *buffer); |
314 | 328 | ||
315 | /* Returns 1 if the specified node has given property. */ | 329 | /* Returns 1 if the specified node has given property. */ |
316 | extern int prom_node_has_property(int node, char *property); | 330 | extern int prom_node_has_property(int node, const char *property); |
317 | 331 | ||
318 | /* Returns phandle of the path specified */ | 332 | /* Returns phandle of the path specified */ |
319 | extern int prom_finddevice(char *name); | 333 | extern int prom_finddevice(const char *name); |
320 | 334 | ||
321 | /* Set the indicated property at the given node with the passed value. | 335 | /* Set the indicated property at the given node with the passed value. |
322 | * Returns the number of bytes of your value that the prom took. | 336 | * Returns the number of bytes of your value that the prom took. |
323 | */ | 337 | */ |
324 | extern int prom_setprop(int node, char *prop_name, char *prop_value, | 338 | extern int prom_setprop(int node, const char *prop_name, char *prop_value, |
325 | int value_size); | 339 | int value_size); |
326 | 340 | ||
327 | extern int prom_pathtoinode(char *path); | 341 | extern int prom_pathtoinode(const char *path); |
328 | extern int prom_inst2pkg(int); | 342 | extern int prom_inst2pkg(int); |
329 | 343 | ||
330 | /* CPU probing helpers. */ | 344 | /* CPU probing helpers. */ |
@@ -334,7 +348,7 @@ int cpu_find_by_mid(int mid, int *prom_node); | |||
334 | /* Client interface level routines. */ | 348 | /* Client interface level routines. */ |
335 | extern void prom_set_trap_table(unsigned long tba); | 349 | extern void prom_set_trap_table(unsigned long tba); |
336 | 350 | ||
337 | extern long p1275_cmd (char *, long, ...); | 351 | extern long p1275_cmd(const char *, long, ...); |
338 | 352 | ||
339 | 353 | ||
340 | #if 0 | 354 | #if 0 |
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index a297f6144f0f..43cbb089cde2 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h | |||
@@ -60,13 +60,13 @@ | |||
60 | * table can map | 60 | * table can map |
61 | */ | 61 | */ |
62 | #define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3)) | 62 | #define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3)) |
63 | #define PMD_SIZE (1UL << PMD_SHIFT) | 63 | #define PMD_SIZE (_AC(1,UL) << PMD_SHIFT) |
64 | #define PMD_MASK (~(PMD_SIZE-1)) | 64 | #define PMD_MASK (~(PMD_SIZE-1)) |
65 | #define PMD_BITS (PAGE_SHIFT - 2) | 65 | #define PMD_BITS (PAGE_SHIFT - 2) |
66 | 66 | ||
67 | /* PGDIR_SHIFT determines what a third-level page table entry can map */ | 67 | /* PGDIR_SHIFT determines what a third-level page table entry can map */ |
68 | #define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS) | 68 | #define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS) |
69 | #define PGDIR_SIZE (1UL << PGDIR_SHIFT) | 69 | #define PGDIR_SIZE (_AC(1,UL) << PGDIR_SHIFT) |
70 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) | 70 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) |
71 | #define PGDIR_BITS (PAGE_SHIFT - 2) | 71 | #define PGDIR_BITS (PAGE_SHIFT - 2) |
72 | 72 | ||
@@ -336,7 +336,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *p | |||
336 | #define pte_clear(mm,addr,ptep) \ | 336 | #define pte_clear(mm,addr,ptep) \ |
337 | set_pte_at((mm), (addr), (ptep), __pte(0UL)) | 337 | set_pte_at((mm), (addr), (ptep), __pte(0UL)) |
338 | 338 | ||
339 | extern pgd_t swapper_pg_dir[1]; | 339 | extern pgd_t swapper_pg_dir[2048]; |
340 | extern pmd_t swapper_low_pmd_dir[2048]; | ||
340 | 341 | ||
341 | /* These do nothing with the way I have things setup. */ | 342 | /* These do nothing with the way I have things setup. */ |
342 | #define mmu_lockarea(vaddr, len) (vaddr) | 343 | #define mmu_lockarea(vaddr, len) (vaddr) |
diff --git a/include/linux/connector.h b/include/linux/connector.h index 96de26301f84..86d4b0a81713 100644 --- a/include/linux/connector.h +++ b/include/linux/connector.h | |||
@@ -104,12 +104,19 @@ struct cn_queue_dev { | |||
104 | struct sock *nls; | 104 | struct sock *nls; |
105 | }; | 105 | }; |
106 | 106 | ||
107 | struct cn_callback { | 107 | struct cn_callback_id { |
108 | unsigned char name[CN_CBQ_NAMELEN]; | 108 | unsigned char name[CN_CBQ_NAMELEN]; |
109 | |||
110 | struct cb_id id; | 109 | struct cb_id id; |
110 | }; | ||
111 | |||
112 | struct cn_callback_data { | ||
113 | void (*destruct_data) (void *); | ||
114 | void *ddata; | ||
115 | |||
116 | void *callback_priv; | ||
111 | void (*callback) (void *); | 117 | void (*callback) (void *); |
112 | void *priv; | 118 | |
119 | void *free; | ||
113 | }; | 120 | }; |
114 | 121 | ||
115 | struct cn_callback_entry { | 122 | struct cn_callback_entry { |
@@ -118,8 +125,8 @@ struct cn_callback_entry { | |||
118 | struct work_struct work; | 125 | struct work_struct work; |
119 | struct cn_queue_dev *pdev; | 126 | struct cn_queue_dev *pdev; |
120 | 127 | ||
121 | void (*destruct_data) (void *); | 128 | struct cn_callback_id id; |
122 | void *ddata; | 129 | struct cn_callback_data data; |
123 | 130 | ||
124 | int seq, group; | 131 | int seq, group; |
125 | struct sock *nls; | 132 | struct sock *nls; |
@@ -144,7 +151,7 @@ int cn_add_callback(struct cb_id *, char *, void (*callback) (void *)); | |||
144 | void cn_del_callback(struct cb_id *); | 151 | void cn_del_callback(struct cb_id *); |
145 | int cn_netlink_send(struct cn_msg *, u32, int); | 152 | int cn_netlink_send(struct cn_msg *, u32, int); |
146 | 153 | ||
147 | int cn_queue_add_callback(struct cn_queue_dev *dev, struct cn_callback *cb); | 154 | int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(void *)); |
148 | void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id); | 155 | void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id); |
149 | 156 | ||
150 | struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *); | 157 | struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *); |
@@ -152,6 +159,8 @@ void cn_queue_free_dev(struct cn_queue_dev *dev); | |||
152 | 159 | ||
153 | int cn_cb_equal(struct cb_id *, struct cb_id *); | 160 | int cn_cb_equal(struct cb_id *, struct cb_id *); |
154 | 161 | ||
162 | void cn_queue_wrapper(void *data); | ||
163 | |||
155 | extern int cn_already_initialized; | 164 | extern int cn_already_initialized; |
156 | 165 | ||
157 | #endif /* __KERNEL__ */ | 166 | #endif /* __KERNEL__ */ |
diff --git a/include/linux/key-ui.h b/include/linux/key-ui.h index cc326174a808..918c34a8347e 100644 --- a/include/linux/key-ui.h +++ b/include/linux/key-ui.h | |||
@@ -42,11 +42,14 @@ struct keyring_list { | |||
42 | /* | 42 | /* |
43 | * check to see whether permission is granted to use a key in the desired way | 43 | * check to see whether permission is granted to use a key in the desired way |
44 | */ | 44 | */ |
45 | static inline int key_permission(const struct key *key, key_perm_t perm) | 45 | static inline int key_permission(const key_ref_t key_ref, key_perm_t perm) |
46 | { | 46 | { |
47 | struct key *key = key_ref_to_ptr(key_ref); | ||
47 | key_perm_t kperm; | 48 | key_perm_t kperm; |
48 | 49 | ||
49 | if (key->uid == current->fsuid) | 50 | if (is_key_possessed(key_ref)) |
51 | kperm = key->perm >> 24; | ||
52 | else if (key->uid == current->fsuid) | ||
50 | kperm = key->perm >> 16; | 53 | kperm = key->perm >> 16; |
51 | else if (key->gid != -1 && | 54 | else if (key->gid != -1 && |
52 | key->perm & KEY_GRP_ALL && | 55 | key->perm & KEY_GRP_ALL && |
@@ -65,11 +68,14 @@ static inline int key_permission(const struct key *key, key_perm_t perm) | |||
65 | * check to see whether permission is granted to use a key in at least one of | 68 | * check to see whether permission is granted to use a key in at least one of |
66 | * the desired ways | 69 | * the desired ways |
67 | */ | 70 | */ |
68 | static inline int key_any_permission(const struct key *key, key_perm_t perm) | 71 | static inline int key_any_permission(const key_ref_t key_ref, key_perm_t perm) |
69 | { | 72 | { |
73 | struct key *key = key_ref_to_ptr(key_ref); | ||
70 | key_perm_t kperm; | 74 | key_perm_t kperm; |
71 | 75 | ||
72 | if (key->uid == current->fsuid) | 76 | if (is_key_possessed(key_ref)) |
77 | kperm = key->perm >> 24; | ||
78 | else if (key->uid == current->fsuid) | ||
73 | kperm = key->perm >> 16; | 79 | kperm = key->perm >> 16; |
74 | else if (key->gid != -1 && | 80 | else if (key->gid != -1 && |
75 | key->perm & KEY_GRP_ALL && | 81 | key->perm & KEY_GRP_ALL && |
@@ -94,13 +100,17 @@ static inline int key_task_groups_search(struct task_struct *tsk, gid_t gid) | |||
94 | return ret; | 100 | return ret; |
95 | } | 101 | } |
96 | 102 | ||
97 | static inline int key_task_permission(const struct key *key, | 103 | static inline int key_task_permission(const key_ref_t key_ref, |
98 | struct task_struct *context, | 104 | struct task_struct *context, |
99 | key_perm_t perm) | 105 | key_perm_t perm) |
100 | { | 106 | { |
107 | struct key *key = key_ref_to_ptr(key_ref); | ||
101 | key_perm_t kperm; | 108 | key_perm_t kperm; |
102 | 109 | ||
103 | if (key->uid == context->fsuid) { | 110 | if (is_key_possessed(key_ref)) { |
111 | kperm = key->perm >> 24; | ||
112 | } | ||
113 | else if (key->uid == context->fsuid) { | ||
104 | kperm = key->perm >> 16; | 114 | kperm = key->perm >> 16; |
105 | } | 115 | } |
106 | else if (key->gid != -1 && | 116 | else if (key->gid != -1 && |
@@ -121,9 +131,9 @@ static inline int key_task_permission(const struct key *key, | |||
121 | 131 | ||
122 | } | 132 | } |
123 | 133 | ||
124 | extern struct key *lookup_user_key(struct task_struct *context, | 134 | extern key_ref_t lookup_user_key(struct task_struct *context, |
125 | key_serial_t id, int create, int partial, | 135 | key_serial_t id, int create, int partial, |
126 | key_perm_t perm); | 136 | key_perm_t perm); |
127 | 137 | ||
128 | extern long join_session_keyring(const char *name); | 138 | extern long join_session_keyring(const char *name); |
129 | 139 | ||
diff --git a/include/linux/key.h b/include/linux/key.h index 970bbd916cf4..f1efa016dbf3 100644 --- a/include/linux/key.h +++ b/include/linux/key.h | |||
@@ -35,11 +35,18 @@ struct key; | |||
35 | 35 | ||
36 | #undef KEY_DEBUGGING | 36 | #undef KEY_DEBUGGING |
37 | 37 | ||
38 | #define KEY_USR_VIEW 0x00010000 /* user can view a key's attributes */ | 38 | #define KEY_POS_VIEW 0x01000000 /* possessor can view a key's attributes */ |
39 | #define KEY_USR_READ 0x00020000 /* user can read key payload / view keyring */ | 39 | #define KEY_POS_READ 0x02000000 /* possessor can read key payload / view keyring */ |
40 | #define KEY_USR_WRITE 0x00040000 /* user can update key payload / add link to keyring */ | 40 | #define KEY_POS_WRITE 0x04000000 /* possessor can update key payload / add link to keyring */ |
41 | #define KEY_USR_SEARCH 0x00080000 /* user can find a key in search / search a keyring */ | 41 | #define KEY_POS_SEARCH 0x08000000 /* possessor can find a key in search / search a keyring */ |
42 | #define KEY_USR_LINK 0x00100000 /* user can create a link to a key/keyring */ | 42 | #define KEY_POS_LINK 0x10000000 /* possessor can create a link to a key/keyring */ |
43 | #define KEY_POS_ALL 0x1f000000 | ||
44 | |||
45 | #define KEY_USR_VIEW 0x00010000 /* user permissions... */ | ||
46 | #define KEY_USR_READ 0x00020000 | ||
47 | #define KEY_USR_WRITE 0x00040000 | ||
48 | #define KEY_USR_SEARCH 0x00080000 | ||
49 | #define KEY_USR_LINK 0x00100000 | ||
43 | #define KEY_USR_ALL 0x001f0000 | 50 | #define KEY_USR_ALL 0x001f0000 |
44 | 51 | ||
45 | #define KEY_GRP_VIEW 0x00000100 /* group permissions... */ | 52 | #define KEY_GRP_VIEW 0x00000100 /* group permissions... */ |
@@ -67,6 +74,38 @@ struct keyring_name; | |||
67 | 74 | ||
68 | /*****************************************************************************/ | 75 | /*****************************************************************************/ |
69 | /* | 76 | /* |
77 | * key reference with possession attribute handling | ||
78 | * | ||
79 | * NOTE! key_ref_t is a typedef'd pointer to a type that is not actually | ||
80 | * defined. This is because we abuse the bottom bit of the reference to carry a | ||
81 | * flag to indicate whether the calling process possesses that key in one of | ||
82 | * its keyrings. | ||
83 | * | ||
84 | * the key_ref_t has been made a separate type so that the compiler can reject | ||
85 | * attempts to dereference it without proper conversion. | ||
86 | * | ||
87 | * the three functions are used to assemble and disassemble references | ||
88 | */ | ||
89 | typedef struct __key_reference_with_attributes *key_ref_t; | ||
90 | |||
91 | static inline key_ref_t make_key_ref(const struct key *key, | ||
92 | unsigned long possession) | ||
93 | { | ||
94 | return (key_ref_t) ((unsigned long) key | possession); | ||
95 | } | ||
96 | |||
97 | static inline struct key *key_ref_to_ptr(const key_ref_t key_ref) | ||
98 | { | ||
99 | return (struct key *) ((unsigned long) key_ref & ~1UL); | ||
100 | } | ||
101 | |||
102 | static inline unsigned long is_key_possessed(const key_ref_t key_ref) | ||
103 | { | ||
104 | return (unsigned long) key_ref & 1UL; | ||
105 | } | ||
106 | |||
107 | /*****************************************************************************/ | ||
108 | /* | ||
70 | * authentication token / access credential / keyring | 109 | * authentication token / access credential / keyring |
71 | * - types of key include: | 110 | * - types of key include: |
72 | * - keyrings | 111 | * - keyrings |
@@ -215,20 +254,25 @@ static inline struct key *key_get(struct key *key) | |||
215 | return key; | 254 | return key; |
216 | } | 255 | } |
217 | 256 | ||
257 | static inline void key_ref_put(key_ref_t key_ref) | ||
258 | { | ||
259 | key_put(key_ref_to_ptr(key_ref)); | ||
260 | } | ||
261 | |||
218 | extern struct key *request_key(struct key_type *type, | 262 | extern struct key *request_key(struct key_type *type, |
219 | const char *description, | 263 | const char *description, |
220 | const char *callout_info); | 264 | const char *callout_info); |
221 | 265 | ||
222 | extern int key_validate(struct key *key); | 266 | extern int key_validate(struct key *key); |
223 | 267 | ||
224 | extern struct key *key_create_or_update(struct key *keyring, | 268 | extern key_ref_t key_create_or_update(key_ref_t keyring, |
225 | const char *type, | 269 | const char *type, |
226 | const char *description, | 270 | const char *description, |
227 | const void *payload, | 271 | const void *payload, |
228 | size_t plen, | 272 | size_t plen, |
229 | int not_in_quota); | 273 | int not_in_quota); |
230 | 274 | ||
231 | extern int key_update(struct key *key, | 275 | extern int key_update(key_ref_t key, |
232 | const void *payload, | 276 | const void *payload, |
233 | size_t plen); | 277 | size_t plen); |
234 | 278 | ||
@@ -243,9 +287,9 @@ extern struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, | |||
243 | 287 | ||
244 | extern int keyring_clear(struct key *keyring); | 288 | extern int keyring_clear(struct key *keyring); |
245 | 289 | ||
246 | extern struct key *keyring_search(struct key *keyring, | 290 | extern key_ref_t keyring_search(key_ref_t keyring, |
247 | struct key_type *type, | 291 | struct key_type *type, |
248 | const char *description); | 292 | const char *description); |
249 | 293 | ||
250 | extern int keyring_add_key(struct key *keyring, | 294 | extern int keyring_add_key(struct key *keyring, |
251 | struct key *key); | 295 | struct key *key); |
@@ -285,6 +329,10 @@ extern void key_init(void); | |||
285 | #define key_serial(k) 0 | 329 | #define key_serial(k) 0 |
286 | #define key_get(k) ({ NULL; }) | 330 | #define key_get(k) ({ NULL; }) |
287 | #define key_put(k) do { } while(0) | 331 | #define key_put(k) do { } while(0) |
332 | #define key_ref_put(k) do { } while(0) | ||
333 | #define make_key_ref(k) ({ NULL; }) | ||
334 | #define key_ref_to_ptr(k) ({ NULL; }) | ||
335 | #define is_key_possessed(k) 0 | ||
288 | #define alloc_uid_keyring(u) 0 | 336 | #define alloc_uid_keyring(u) 0 |
289 | #define switch_uid_keyring(u) do { } while(0) | 337 | #define switch_uid_keyring(u) do { } while(0) |
290 | #define __install_session_keyring(t, k) ({ NULL; }) | 338 | #define __install_session_keyring(t, k) ({ NULL; }) |
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 47da39ba3f03..4ed2107bc020 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h | |||
@@ -209,10 +209,11 @@ struct pcmcia_device_id { | |||
209 | /* for real multi-function devices */ | 209 | /* for real multi-function devices */ |
210 | __u8 function; | 210 | __u8 function; |
211 | 211 | ||
212 | /* for pseude multi-function devices */ | 212 | /* for pseudo multi-function devices */ |
213 | __u8 device_no; | 213 | __u8 device_no; |
214 | 214 | ||
215 | __u32 prod_id_hash[4]; | 215 | __u32 prod_id_hash[4] |
216 | __attribute__((aligned(sizeof(__u32)))); | ||
216 | 217 | ||
217 | /* not matched against in kernelspace*/ | 218 | /* not matched against in kernelspace*/ |
218 | #ifdef __KERNEL__ | 219 | #ifdef __KERNEL__ |
diff --git a/include/linux/netfilter_ipv4/ip_nat_core.h b/include/linux/netfilter_ipv4/ip_nat_core.h index 3b50eb91f007..30db23f06b03 100644 --- a/include/linux/netfilter_ipv4/ip_nat_core.h +++ b/include/linux/netfilter_ipv4/ip_nat_core.h | |||
@@ -5,16 +5,14 @@ | |||
5 | 5 | ||
6 | /* This header used to share core functionality between the standalone | 6 | /* This header used to share core functionality between the standalone |
7 | NAT module, and the compatibility layer's use of NAT for masquerading. */ | 7 | NAT module, and the compatibility layer's use of NAT for masquerading. */ |
8 | extern int ip_nat_init(void); | ||
9 | extern void ip_nat_cleanup(void); | ||
10 | 8 | ||
11 | extern unsigned int nat_packet(struct ip_conntrack *ct, | 9 | extern unsigned int ip_nat_packet(struct ip_conntrack *ct, |
12 | enum ip_conntrack_info conntrackinfo, | 10 | enum ip_conntrack_info conntrackinfo, |
13 | unsigned int hooknum, | 11 | unsigned int hooknum, |
14 | struct sk_buff **pskb); | 12 | struct sk_buff **pskb); |
15 | 13 | ||
16 | extern int icmp_reply_translation(struct sk_buff **pskb, | 14 | extern int ip_nat_icmp_reply_translation(struct sk_buff **pskb, |
17 | struct ip_conntrack *ct, | 15 | struct ip_conntrack *ct, |
18 | enum ip_nat_manip_type manip, | 16 | enum ip_nat_manip_type manip, |
19 | enum ip_conntrack_dir dir); | 17 | enum ip_conntrack_dir dir); |
20 | #endif /* _IP_NAT_CORE_H */ | 18 | #endif /* _IP_NAT_CORE_H */ |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index b86a4b77007e..68f11ac1a314 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -769,6 +769,8 @@ | |||
769 | #define PCI_DEVICE_ID_TI_TVP4010 0x3d04 | 769 | #define PCI_DEVICE_ID_TI_TVP4010 0x3d04 |
770 | #define PCI_DEVICE_ID_TI_TVP4020 0x3d07 | 770 | #define PCI_DEVICE_ID_TI_TVP4020 0x3d07 |
771 | #define PCI_DEVICE_ID_TI_4450 0x8011 | 771 | #define PCI_DEVICE_ID_TI_4450 0x8011 |
772 | #define PCI_DEVICE_ID_TI_XX21_XX11 0x8031 | ||
773 | #define PCI_DEVICE_ID_TI_X515 0x8036 | ||
772 | #define PCI_DEVICE_ID_TI_1130 0xac12 | 774 | #define PCI_DEVICE_ID_TI_1130 0xac12 |
773 | #define PCI_DEVICE_ID_TI_1031 0xac13 | 775 | #define PCI_DEVICE_ID_TI_1031 0xac13 |
774 | #define PCI_DEVICE_ID_TI_1131 0xac15 | 776 | #define PCI_DEVICE_ID_TI_1131 0xac15 |
@@ -785,12 +787,17 @@ | |||
785 | #define PCI_DEVICE_ID_TI_4451 0xac42 | 787 | #define PCI_DEVICE_ID_TI_4451 0xac42 |
786 | #define PCI_DEVICE_ID_TI_4510 0xac44 | 788 | #define PCI_DEVICE_ID_TI_4510 0xac44 |
787 | #define PCI_DEVICE_ID_TI_4520 0xac46 | 789 | #define PCI_DEVICE_ID_TI_4520 0xac46 |
790 | #define PCI_DEVICE_ID_TI_7510 0xac47 | ||
791 | #define PCI_DEVICE_ID_TI_7610 0xac48 | ||
792 | #define PCI_DEVICE_ID_TI_7410 0xac49 | ||
788 | #define PCI_DEVICE_ID_TI_1410 0xac50 | 793 | #define PCI_DEVICE_ID_TI_1410 0xac50 |
789 | #define PCI_DEVICE_ID_TI_1420 0xac51 | 794 | #define PCI_DEVICE_ID_TI_1420 0xac51 |
790 | #define PCI_DEVICE_ID_TI_1451A 0xac52 | 795 | #define PCI_DEVICE_ID_TI_1451A 0xac52 |
791 | #define PCI_DEVICE_ID_TI_1620 0xac54 | 796 | #define PCI_DEVICE_ID_TI_1620 0xac54 |
792 | #define PCI_DEVICE_ID_TI_1520 0xac55 | 797 | #define PCI_DEVICE_ID_TI_1520 0xac55 |
793 | #define PCI_DEVICE_ID_TI_1510 0xac56 | 798 | #define PCI_DEVICE_ID_TI_1510 0xac56 |
799 | #define PCI_DEVICE_ID_TI_X620 0xac8d | ||
800 | #define PCI_DEVICE_ID_TI_X420 0xac8e | ||
794 | 801 | ||
795 | #define PCI_VENDOR_ID_SONY 0x104d | 802 | #define PCI_VENDOR_ID_SONY 0x104d |
796 | #define PCI_DEVICE_ID_SONY_CXD3222 0x8039 | 803 | #define PCI_DEVICE_ID_SONY_CXD3222 0x8039 |
@@ -2187,7 +2194,12 @@ | |||
2187 | #define PCI_DEVICE_ID_ENE_1211 0x1211 | 2194 | #define PCI_DEVICE_ID_ENE_1211 0x1211 |
2188 | #define PCI_DEVICE_ID_ENE_1225 0x1225 | 2195 | #define PCI_DEVICE_ID_ENE_1225 0x1225 |
2189 | #define PCI_DEVICE_ID_ENE_1410 0x1410 | 2196 | #define PCI_DEVICE_ID_ENE_1410 0x1410 |
2197 | #define PCI_DEVICE_ID_ENE_710 0x1411 | ||
2198 | #define PCI_DEVICE_ID_ENE_712 0x1412 | ||
2190 | #define PCI_DEVICE_ID_ENE_1420 0x1420 | 2199 | #define PCI_DEVICE_ID_ENE_1420 0x1420 |
2200 | #define PCI_DEVICE_ID_ENE_720 0x1421 | ||
2201 | #define PCI_DEVICE_ID_ENE_722 0x1422 | ||
2202 | |||
2191 | #define PCI_VENDOR_ID_CHELSIO 0x1425 | 2203 | #define PCI_VENDOR_ID_CHELSIO 0x1425 |
2192 | 2204 | ||
2193 | #define PCI_VENDOR_ID_MIPS 0x153f | 2205 | #define PCI_VENDOR_ID_MIPS 0x153f |
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 3a29a9f9b451..fc8e367f671e 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h | |||
@@ -202,7 +202,8 @@ enum | |||
202 | NET_TR=14, | 202 | NET_TR=14, |
203 | NET_DECNET=15, | 203 | NET_DECNET=15, |
204 | NET_ECONET=16, | 204 | NET_ECONET=16, |
205 | NET_SCTP=17, | 205 | NET_SCTP=17, |
206 | NET_LLC=18, | ||
206 | }; | 207 | }; |
207 | 208 | ||
208 | /* /proc/sys/kernel/random */ | 209 | /* /proc/sys/kernel/random */ |
@@ -522,6 +523,29 @@ enum { | |||
522 | NET_IPX_FORWARDING=2 | 523 | NET_IPX_FORWARDING=2 |
523 | }; | 524 | }; |
524 | 525 | ||
526 | /* /proc/sys/net/llc */ | ||
527 | enum { | ||
528 | NET_LLC2=1, | ||
529 | NET_LLC_STATION=2, | ||
530 | }; | ||
531 | |||
532 | /* /proc/sys/net/llc/llc2 */ | ||
533 | enum { | ||
534 | NET_LLC2_TIMEOUT=1, | ||
535 | }; | ||
536 | |||
537 | /* /proc/sys/net/llc/station */ | ||
538 | enum { | ||
539 | NET_LLC_STATION_ACK_TIMEOUT=1, | ||
540 | }; | ||
541 | |||
542 | /* /proc/sys/net/llc/llc2/timeout */ | ||
543 | enum { | ||
544 | NET_LLC2_ACK_TIMEOUT=1, | ||
545 | NET_LLC2_P_TIMEOUT=2, | ||
546 | NET_LLC2_REJ_TIMEOUT=3, | ||
547 | NET_LLC2_BUSY_TIMEOUT=4, | ||
548 | }; | ||
525 | 549 | ||
526 | /* /proc/sys/net/appletalk */ | 550 | /* /proc/sys/net/appletalk */ |
527 | enum { | 551 | enum { |
diff --git a/include/net/llc.h b/include/net/llc.h index 71769a5aeef3..1adb2ef3f6f7 100644 --- a/include/net/llc.h +++ b/include/net/llc.h | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/list.h> | 17 | #include <linux/list.h> |
18 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
19 | 19 | ||
20 | #include <asm/atomic.h> | ||
21 | |||
20 | struct net_device; | 22 | struct net_device; |
21 | struct packet_type; | 23 | struct packet_type; |
22 | struct sk_buff; | 24 | struct sk_buff; |
@@ -44,6 +46,7 @@ struct llc_sap { | |||
44 | unsigned char state; | 46 | unsigned char state; |
45 | unsigned char p_bit; | 47 | unsigned char p_bit; |
46 | unsigned char f_bit; | 48 | unsigned char f_bit; |
49 | atomic_t refcnt; | ||
47 | int (*rcv_func)(struct sk_buff *skb, | 50 | int (*rcv_func)(struct sk_buff *skb, |
48 | struct net_device *dev, | 51 | struct net_device *dev, |
49 | struct packet_type *pt, | 52 | struct packet_type *pt, |
@@ -81,13 +84,27 @@ extern struct llc_sap *llc_sap_open(unsigned char lsap, | |||
81 | struct net_device *dev, | 84 | struct net_device *dev, |
82 | struct packet_type *pt, | 85 | struct packet_type *pt, |
83 | struct net_device *orig_dev)); | 86 | struct net_device *orig_dev)); |
87 | static inline void llc_sap_hold(struct llc_sap *sap) | ||
88 | { | ||
89 | atomic_inc(&sap->refcnt); | ||
90 | } | ||
91 | |||
84 | extern void llc_sap_close(struct llc_sap *sap); | 92 | extern void llc_sap_close(struct llc_sap *sap); |
85 | 93 | ||
94 | static inline void llc_sap_put(struct llc_sap *sap) | ||
95 | { | ||
96 | if (atomic_dec_and_test(&sap->refcnt)) | ||
97 | llc_sap_close(sap); | ||
98 | } | ||
99 | |||
86 | extern struct llc_sap *llc_sap_find(unsigned char sap_value); | 100 | extern struct llc_sap *llc_sap_find(unsigned char sap_value); |
87 | 101 | ||
88 | extern int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb, | 102 | extern int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb, |
89 | unsigned char *dmac, unsigned char dsap); | 103 | unsigned char *dmac, unsigned char dsap); |
90 | 104 | ||
105 | extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb); | ||
106 | extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb); | ||
107 | |||
91 | extern int llc_station_init(void); | 108 | extern int llc_station_init(void); |
92 | extern void llc_station_exit(void); | 109 | extern void llc_station_exit(void); |
93 | 110 | ||
@@ -98,4 +115,17 @@ extern void llc_proc_exit(void); | |||
98 | #define llc_proc_init() (0) | 115 | #define llc_proc_init() (0) |
99 | #define llc_proc_exit() do { } while(0) | 116 | #define llc_proc_exit() do { } while(0) |
100 | #endif /* CONFIG_PROC_FS */ | 117 | #endif /* CONFIG_PROC_FS */ |
118 | #ifdef CONFIG_SYSCTL | ||
119 | extern int llc_sysctl_init(void); | ||
120 | extern void llc_sysctl_exit(void); | ||
121 | |||
122 | extern int sysctl_llc2_ack_timeout; | ||
123 | extern int sysctl_llc2_busy_timeout; | ||
124 | extern int sysctl_llc2_p_timeout; | ||
125 | extern int sysctl_llc2_rej_timeout; | ||
126 | extern int sysctl_llc_station_ack_timeout; | ||
127 | #else | ||
128 | #define llc_sysctl_init() (0) | ||
129 | #define llc_sysctl_exit() do { } while(0) | ||
130 | #endif /* CONFIG_SYSCTL */ | ||
101 | #endif /* LLC_H */ | 131 | #endif /* LLC_H */ |
diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h index 8ad3bc2c23d7..54852ff6033b 100644 --- a/include/net/llc_conn.h +++ b/include/net/llc_conn.h | |||
@@ -19,14 +19,14 @@ | |||
19 | #define LLC_EVENT 1 | 19 | #define LLC_EVENT 1 |
20 | #define LLC_PACKET 2 | 20 | #define LLC_PACKET 2 |
21 | 21 | ||
22 | #define LLC_P_TIME 2 | 22 | #define LLC2_P_TIME 2 |
23 | #define LLC_ACK_TIME 1 | 23 | #define LLC2_ACK_TIME 1 |
24 | #define LLC_REJ_TIME 3 | 24 | #define LLC2_REJ_TIME 3 |
25 | #define LLC_BUSY_TIME 3 | 25 | #define LLC2_BUSY_TIME 3 |
26 | 26 | ||
27 | struct llc_timer { | 27 | struct llc_timer { |
28 | struct timer_list timer; | 28 | struct timer_list timer; |
29 | u16 expire; /* timer expire time */ | 29 | unsigned long expire; /* timer expire time */ |
30 | }; | 30 | }; |
31 | 31 | ||
32 | struct llc_sock { | 32 | struct llc_sock { |
@@ -38,6 +38,7 @@ struct llc_sock { | |||
38 | struct llc_addr laddr; /* lsap/mac pair */ | 38 | struct llc_addr laddr; /* lsap/mac pair */ |
39 | struct llc_addr daddr; /* dsap/mac pair */ | 39 | struct llc_addr daddr; /* dsap/mac pair */ |
40 | struct net_device *dev; /* device to send to remote */ | 40 | struct net_device *dev; /* device to send to remote */ |
41 | u32 copied_seq; /* head of yet unread data */ | ||
41 | u8 retry_count; /* number of retries */ | 42 | u8 retry_count; /* number of retries */ |
42 | u8 ack_must_be_send; | 43 | u8 ack_must_be_send; |
43 | u8 first_pdu_Ns; | 44 | u8 first_pdu_Ns; |
@@ -92,7 +93,8 @@ static __inline__ char llc_backlog_type(struct sk_buff *skb) | |||
92 | return skb->cb[sizeof(skb->cb) - 1]; | 93 | return skb->cb[sizeof(skb->cb) - 1]; |
93 | } | 94 | } |
94 | 95 | ||
95 | extern struct sock *llc_sk_alloc(int family, int priority, struct proto *prot); | 96 | extern struct sock *llc_sk_alloc(int family, unsigned int __nocast priority, |
97 | struct proto *prot); | ||
96 | extern void llc_sk_free(struct sock *sk); | 98 | extern void llc_sk_free(struct sock *sk); |
97 | 99 | ||
98 | extern void llc_sk_reset(struct sock *sk); | 100 | extern void llc_sk_reset(struct sock *sk); |
@@ -115,5 +117,4 @@ extern void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk); | |||
115 | 117 | ||
116 | extern u8 llc_data_accept_state(u8 state); | 118 | extern u8 llc_data_accept_state(u8 state); |
117 | extern void llc_build_offset_table(void); | 119 | extern void llc_build_offset_table(void); |
118 | extern int llc_release_sockets(struct llc_sap *sap); | ||
119 | #endif /* LLC_CONN_H */ | 120 | #endif /* LLC_CONN_H */ |
diff --git a/include/net/llc_sap.h b/include/net/llc_sap.h index 353baaa627f3..2c56dbece729 100644 --- a/include/net/llc_sap.h +++ b/include/net/llc_sap.h | |||
@@ -12,11 +12,15 @@ | |||
12 | * See the GNU General Public License for more details. | 12 | * See the GNU General Public License for more details. |
13 | */ | 13 | */ |
14 | struct llc_sap; | 14 | struct llc_sap; |
15 | struct net_device; | ||
15 | struct sk_buff; | 16 | struct sk_buff; |
17 | struct sock; | ||
16 | 18 | ||
17 | extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb); | 19 | extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb); |
18 | extern void llc_save_primitive(struct sk_buff* skb, unsigned char prim); | 20 | extern void llc_save_primitive(struct sock *sk, struct sk_buff* skb, |
19 | extern struct sk_buff *llc_alloc_frame(void); | 21 | unsigned char prim); |
22 | extern struct sk_buff *llc_alloc_frame(struct sock *sk, | ||
23 | struct net_device *dev); | ||
20 | 24 | ||
21 | extern void llc_build_and_send_test_pkt(struct llc_sap *sap, | 25 | extern void llc_build_and_send_test_pkt(struct llc_sap *sap, |
22 | struct sk_buff *skb, | 26 | struct sk_buff *skb, |
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index 0f7aacc33fe9..c8592c7e8eaa 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h | |||
@@ -21,6 +21,9 @@ | |||
21 | #include <pcmcia/cs_types.h> | 21 | #include <pcmcia/cs_types.h> |
22 | #include <pcmcia/cs.h> | 22 | #include <pcmcia/cs.h> |
23 | #include <pcmcia/bulkmem.h> | 23 | #include <pcmcia/bulkmem.h> |
24 | #ifdef CONFIG_CARDBUS | ||
25 | #include <linux/pci.h> | ||
26 | #endif | ||
24 | 27 | ||
25 | /* Definitions for card status flags for GetStatus */ | 28 | /* Definitions for card status flags for GetStatus */ |
26 | #define SS_WRPROT 0x0001 | 29 | #define SS_WRPROT 0x0001 |
@@ -233,7 +236,11 @@ struct pcmcia_socket { | |||
233 | 236 | ||
234 | /* so is power hook */ | 237 | /* so is power hook */ |
235 | int (*power_hook)(struct pcmcia_socket *sock, int operation); | 238 | int (*power_hook)(struct pcmcia_socket *sock, int operation); |
236 | 239 | #ifdef CONFIG_CARDBUS | |
240 | /* allows tuning the CB bridge before loading driver for the CB card */ | ||
241 | void (*tune_bridge)(struct pcmcia_socket *sock, struct pci_bus *bus); | ||
242 | #endif | ||
243 | |||
237 | /* state thread */ | 244 | /* state thread */ |
238 | struct semaphore skt_sem; /* protects socket h/w state */ | 245 | struct semaphore skt_sem; /* protects socket h/w state */ |
239 | 246 | ||
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index e16cf94870f2..e6f4c9e55df7 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h | |||
@@ -665,7 +665,6 @@ struct ib_ucontext { | |||
665 | struct list_head qp_list; | 665 | struct list_head qp_list; |
666 | struct list_head srq_list; | 666 | struct list_head srq_list; |
667 | struct list_head ah_list; | 667 | struct list_head ah_list; |
668 | spinlock_t lock; | ||
669 | }; | 668 | }; |
670 | 669 | ||
671 | struct ib_uobject { | 670 | struct ib_uobject { |
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 3a926011507b..a0f18c9cc89d 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -611,6 +611,7 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry, | |||
611 | dentry->d_fsdata = &attr; | 611 | dentry->d_fsdata = &attr; |
612 | } | 612 | } |
613 | 613 | ||
614 | mode &= ~current->fs->umask; | ||
614 | ret = vfs_create(dir->d_inode, dentry, mode, NULL); | 615 | ret = vfs_create(dir->d_inode, dentry, mode, NULL); |
615 | dentry->d_fsdata = NULL; | 616 | dentry->d_fsdata = NULL; |
616 | if (ret) | 617 | if (ret) |
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 79866bc6b3a1..6a6e87b2f2fd 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -969,7 +969,7 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf, | |||
969 | ssize_t retval = 0; | 969 | ssize_t retval = 0; |
970 | char *s; | 970 | char *s; |
971 | char *start; | 971 | char *start; |
972 | size_t n; | 972 | ssize_t n; |
973 | 973 | ||
974 | if (!(page = (char *)__get_free_page(GFP_KERNEL))) | 974 | if (!(page = (char *)__get_free_page(GFP_KERNEL))) |
975 | return -ENOMEM; | 975 | return -ENOMEM; |
@@ -999,12 +999,13 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf, | |||
999 | *s++ = '\n'; | 999 | *s++ = '\n'; |
1000 | *s = '\0'; | 1000 | *s = '\0'; |
1001 | 1001 | ||
1002 | /* Do nothing if *ppos is at the eof or beyond the eof. */ | ||
1003 | if (s - page <= *ppos) | ||
1004 | return 0; | ||
1005 | |||
1006 | start = page + *ppos; | 1002 | start = page + *ppos; |
1007 | n = s - start; | 1003 | n = s - start; |
1004 | |||
1005 | /* Do nothing if *ppos is at the eof or beyond the eof. */ | ||
1006 | if (n <= 0) | ||
1007 | goto out; | ||
1008 | |||
1008 | retval = n - copy_to_user(buf, start, min(n, nbytes)); | 1009 | retval = n - copy_to_user(buf, start, min(n, nbytes)); |
1009 | *ppos += retval; | 1010 | *ppos += retval; |
1010 | out: | 1011 | out: |
diff --git a/kernel/params.c b/kernel/params.c index fbf173215fd2..1a8614bac5d5 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
@@ -80,8 +80,6 @@ static char *next_arg(char *args, char **param, char **val) | |||
80 | int in_quote = 0, quoted = 0; | 80 | int in_quote = 0, quoted = 0; |
81 | char *next; | 81 | char *next; |
82 | 82 | ||
83 | /* Chew any extra spaces */ | ||
84 | while (*args == ' ') args++; | ||
85 | if (*args == '"') { | 83 | if (*args == '"') { |
86 | args++; | 84 | args++; |
87 | in_quote = 1; | 85 | in_quote = 1; |
@@ -121,6 +119,10 @@ static char *next_arg(char *args, char **param, char **val) | |||
121 | next = args + i + 1; | 119 | next = args + i + 1; |
122 | } else | 120 | } else |
123 | next = args + i; | 121 | next = args + i; |
122 | |||
123 | /* Chew up trailing spaces. */ | ||
124 | while (*next == ' ') | ||
125 | next++; | ||
124 | return next; | 126 | return next; |
125 | } | 127 | } |
126 | 128 | ||
@@ -135,6 +137,10 @@ int parse_args(const char *name, | |||
135 | 137 | ||
136 | DEBUGP("Parsing ARGS: %s\n", args); | 138 | DEBUGP("Parsing ARGS: %s\n", args); |
137 | 139 | ||
140 | /* Chew leading spaces */ | ||
141 | while (*args == ' ') | ||
142 | args++; | ||
143 | |||
138 | while (*args) { | 144 | while (*args) { |
139 | int ret; | 145 | int ret; |
140 | 146 | ||
diff --git a/kernel/power/power.h b/kernel/power/power.h index 9c9167d910dd..6748de23e83c 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h | |||
@@ -9,6 +9,9 @@ | |||
9 | #define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) | 9 | #define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) |
10 | #endif | 10 | #endif |
11 | 11 | ||
12 | #define MAX_PBES ((PAGE_SIZE - sizeof(struct new_utsname) \ | ||
13 | - 4 - 3*sizeof(unsigned long) - sizeof(int) \ | ||
14 | - sizeof(void *)) / sizeof(swp_entry_t)) | ||
12 | 15 | ||
13 | struct swsusp_info { | 16 | struct swsusp_info { |
14 | struct new_utsname uts; | 17 | struct new_utsname uts; |
@@ -18,7 +21,7 @@ struct swsusp_info { | |||
18 | unsigned long image_pages; | 21 | unsigned long image_pages; |
19 | unsigned long pagedir_pages; | 22 | unsigned long pagedir_pages; |
20 | suspend_pagedir_t * suspend_pagedir; | 23 | suspend_pagedir_t * suspend_pagedir; |
21 | swp_entry_t pagedir[768]; | 24 | swp_entry_t pagedir[MAX_PBES]; |
22 | } __attribute__((aligned(PAGE_SIZE))); | 25 | } __attribute__((aligned(PAGE_SIZE))); |
23 | 26 | ||
24 | 27 | ||
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index 1cc9ff25e479..acf79ac1cb6d 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c | |||
@@ -402,15 +402,14 @@ static int write_page(unsigned long addr, swp_entry_t * loc) | |||
402 | static void data_free(void) | 402 | static void data_free(void) |
403 | { | 403 | { |
404 | swp_entry_t entry; | 404 | swp_entry_t entry; |
405 | int i; | 405 | struct pbe * p; |
406 | 406 | ||
407 | for (i = 0; i < nr_copy_pages; i++) { | 407 | for_each_pbe(p, pagedir_nosave) { |
408 | entry = (pagedir_nosave + i)->swap_address; | 408 | entry = p->swap_address; |
409 | if (entry.val) | 409 | if (entry.val) |
410 | swap_free(entry); | 410 | swap_free(entry); |
411 | else | 411 | else |
412 | break; | 412 | break; |
413 | (pagedir_nosave + i)->swap_address = (swp_entry_t){0}; | ||
414 | } | 413 | } |
415 | } | 414 | } |
416 | 415 | ||
@@ -932,6 +931,10 @@ static int swsusp_alloc(void) | |||
932 | if (!enough_swap()) | 931 | if (!enough_swap()) |
933 | return -ENOSPC; | 932 | return -ENOSPC; |
934 | 933 | ||
934 | if (MAX_PBES < nr_copy_pages / PBES_PER_PAGE + | ||
935 | !!(nr_copy_pages % PBES_PER_PAGE)) | ||
936 | return -ENOSPC; | ||
937 | |||
935 | if (!(pagedir_save = alloc_pagedir(nr_copy_pages))) { | 938 | if (!(pagedir_save = alloc_pagedir(nr_copy_pages))) { |
936 | printk(KERN_ERR "suspend: Allocating pagedir failed.\n"); | 939 | printk(KERN_ERR "suspend: Allocating pagedir failed.\n"); |
937 | return -ENOMEM; | 940 | return -ENOMEM; |
@@ -1438,9 +1441,9 @@ static int read_pagedir(struct pbe *pblist) | |||
1438 | } | 1441 | } |
1439 | 1442 | ||
1440 | if (error) | 1443 | if (error) |
1441 | free_page((unsigned long)pblist); | 1444 | free_pagedir(pblist); |
1442 | 1445 | else | |
1443 | BUG_ON(i != swsusp_info.pagedir_pages); | 1446 | BUG_ON(i != swsusp_info.pagedir_pages); |
1444 | 1447 | ||
1445 | return error; | 1448 | return error; |
1446 | } | 1449 | } |
diff --git a/mm/mremap.c b/mm/mremap.c index a32fed454bd7..f343fc73a8bd 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
@@ -141,10 +141,10 @@ move_one_page(struct vm_area_struct *vma, unsigned long old_addr, | |||
141 | if (dst) { | 141 | if (dst) { |
142 | pte_t pte; | 142 | pte_t pte; |
143 | pte = ptep_clear_flush(vma, old_addr, src); | 143 | pte = ptep_clear_flush(vma, old_addr, src); |
144 | |||
144 | /* ZERO_PAGE can be dependant on virtual addr */ | 145 | /* ZERO_PAGE can be dependant on virtual addr */ |
145 | if (pfn_valid(pte_pfn(pte)) && | 146 | pte = move_pte(pte, new_vma->vm_page_prot, |
146 | pte_page(pte) == ZERO_PAGE(old_addr)) | 147 | old_addr, new_addr); |
147 | pte = pte_wrprotect(mk_pte(ZERO_PAGE(new_addr), new_vma->vm_page_prot)); | ||
148 | set_pte_at(mm, new_addr, dst, pte); | 148 | set_pte_at(mm, new_addr, dst, pte); |
149 | } else | 149 | } else |
150 | error = -ENOMEM; | 150 | error = -ENOMEM; |
@@ -2510,16 +2510,12 @@ cache_alloc_debugcheck_after(kmem_cache_t *cachep, | |||
2510 | #define cache_alloc_debugcheck_after(a,b,objp,d) (objp) | 2510 | #define cache_alloc_debugcheck_after(a,b,objp,d) (objp) |
2511 | #endif | 2511 | #endif |
2512 | 2512 | ||
2513 | 2513 | static inline void *____cache_alloc(kmem_cache_t *cachep, unsigned int __nocast flags) | |
2514 | static inline void *__cache_alloc(kmem_cache_t *cachep, unsigned int __nocast flags) | ||
2515 | { | 2514 | { |
2516 | unsigned long save_flags; | ||
2517 | void* objp; | 2515 | void* objp; |
2518 | struct array_cache *ac; | 2516 | struct array_cache *ac; |
2519 | 2517 | ||
2520 | cache_alloc_debugcheck_before(cachep, flags); | 2518 | check_irq_off(); |
2521 | |||
2522 | local_irq_save(save_flags); | ||
2523 | ac = ac_data(cachep); | 2519 | ac = ac_data(cachep); |
2524 | if (likely(ac->avail)) { | 2520 | if (likely(ac->avail)) { |
2525 | STATS_INC_ALLOCHIT(cachep); | 2521 | STATS_INC_ALLOCHIT(cachep); |
@@ -2529,6 +2525,18 @@ static inline void *__cache_alloc(kmem_cache_t *cachep, unsigned int __nocast fl | |||
2529 | STATS_INC_ALLOCMISS(cachep); | 2525 | STATS_INC_ALLOCMISS(cachep); |
2530 | objp = cache_alloc_refill(cachep, flags); | 2526 | objp = cache_alloc_refill(cachep, flags); |
2531 | } | 2527 | } |
2528 | return objp; | ||
2529 | } | ||
2530 | |||
2531 | static inline void *__cache_alloc(kmem_cache_t *cachep, unsigned int __nocast flags) | ||
2532 | { | ||
2533 | unsigned long save_flags; | ||
2534 | void* objp; | ||
2535 | |||
2536 | cache_alloc_debugcheck_before(cachep, flags); | ||
2537 | |||
2538 | local_irq_save(save_flags); | ||
2539 | objp = ____cache_alloc(cachep, flags); | ||
2532 | local_irq_restore(save_flags); | 2540 | local_irq_restore(save_flags); |
2533 | objp = cache_alloc_debugcheck_after(cachep, flags, objp, | 2541 | objp = cache_alloc_debugcheck_after(cachep, flags, objp, |
2534 | __builtin_return_address(0)); | 2542 | __builtin_return_address(0)); |
@@ -2856,7 +2864,10 @@ void *kmem_cache_alloc_node(kmem_cache_t *cachep, unsigned int __nocast flags, i | |||
2856 | 2864 | ||
2857 | cache_alloc_debugcheck_before(cachep, flags); | 2865 | cache_alloc_debugcheck_before(cachep, flags); |
2858 | local_irq_save(save_flags); | 2866 | local_irq_save(save_flags); |
2859 | ptr = __cache_alloc_node(cachep, flags, nodeid); | 2867 | if (nodeid == numa_node_id()) |
2868 | ptr = ____cache_alloc(cachep, flags); | ||
2869 | else | ||
2870 | ptr = __cache_alloc_node(cachep, flags, nodeid); | ||
2860 | local_irq_restore(save_flags); | 2871 | local_irq_restore(save_flags); |
2861 | ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, __builtin_return_address(0)); | 2872 | ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, __builtin_return_address(0)); |
2862 | 2873 | ||
diff --git a/net/802/p8022.c b/net/802/p8022.c index b24817c63ca8..2530f35241cd 100644 --- a/net/802/p8022.c +++ b/net/802/p8022.c | |||
@@ -56,7 +56,7 @@ struct datalink_proto *register_8022_client(unsigned char type, | |||
56 | 56 | ||
57 | void unregister_8022_client(struct datalink_proto *proto) | 57 | void unregister_8022_client(struct datalink_proto *proto) |
58 | { | 58 | { |
59 | llc_sap_close(proto->sap); | 59 | llc_sap_put(proto->sap); |
60 | kfree(proto); | 60 | kfree(proto); |
61 | } | 61 | } |
62 | 62 | ||
diff --git a/net/802/psnap.c b/net/802/psnap.c index ab80b1fab53c..4d638944d933 100644 --- a/net/802/psnap.c +++ b/net/802/psnap.c | |||
@@ -106,7 +106,7 @@ module_init(snap_init); | |||
106 | 106 | ||
107 | static void __exit snap_exit(void) | 107 | static void __exit snap_exit(void) |
108 | { | 108 | { |
109 | llc_sap_close(snap_sap); | 109 | llc_sap_put(snap_sap); |
110 | } | 110 | } |
111 | 111 | ||
112 | module_exit(snap_exit); | 112 | module_exit(snap_exit); |
diff --git a/net/802/tr.c b/net/802/tr.c index 1bb7dc1b85cd..1eaa3d19d8bf 100644 --- a/net/802/tr.c +++ b/net/802/tr.c | |||
@@ -238,7 +238,7 @@ unsigned short tr_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
238 | return trllc->ethertype; | 238 | return trllc->ethertype; |
239 | } | 239 | } |
240 | 240 | ||
241 | return ntohs(ETH_P_802_2); | 241 | return ntohs(ETH_P_TR_802_2); |
242 | } | 242 | } |
243 | 243 | ||
244 | /* | 244 | /* |
diff --git a/net/core/dev.c b/net/core/dev.c index c01511e3d0c1..37c881070963 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -574,6 +574,8 @@ struct net_device *dev_getbyhwaddr(unsigned short type, char *ha) | |||
574 | return dev; | 574 | return dev; |
575 | } | 575 | } |
576 | 576 | ||
577 | EXPORT_SYMBOL(dev_getbyhwaddr); | ||
578 | |||
577 | struct net_device *dev_getfirstbyhwtype(unsigned short type) | 579 | struct net_device *dev_getfirstbyhwtype(unsigned short type) |
578 | { | 580 | { |
579 | struct net_device *dev; | 581 | struct net_device *dev; |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 39fc55edf691..4128fc76ac3a 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -61,7 +61,9 @@ static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev); | |||
61 | void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev); | 61 | void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev); |
62 | 62 | ||
63 | static struct neigh_table *neigh_tables; | 63 | static struct neigh_table *neigh_tables; |
64 | #ifdef CONFIG_PROC_FS | ||
64 | static struct file_operations neigh_stat_seq_fops; | 65 | static struct file_operations neigh_stat_seq_fops; |
66 | #endif | ||
65 | 67 | ||
66 | /* | 68 | /* |
67 | Neighbour hash table buckets are protected with rwlock tbl->lock. | 69 | Neighbour hash table buckets are protected with rwlock tbl->lock. |
@@ -725,6 +727,13 @@ static __inline__ int neigh_max_probes(struct neighbour *n) | |||
725 | p->ucast_probes + p->app_probes + p->mcast_probes); | 727 | p->ucast_probes + p->app_probes + p->mcast_probes); |
726 | } | 728 | } |
727 | 729 | ||
730 | static inline void neigh_add_timer(struct neighbour *n, unsigned long when) | ||
731 | { | ||
732 | if (unlikely(mod_timer(&n->timer, when))) { | ||
733 | printk("NEIGH: BUG, double timer add, state is %x\n", | ||
734 | n->nud_state); | ||
735 | } | ||
736 | } | ||
728 | 737 | ||
729 | /* Called when a timer expires for a neighbour entry. */ | 738 | /* Called when a timer expires for a neighbour entry. */ |
730 | 739 | ||
@@ -809,8 +818,7 @@ static void neigh_timer_handler(unsigned long arg) | |||
809 | neigh_hold(neigh); | 818 | neigh_hold(neigh); |
810 | if (time_before(next, jiffies + HZ/2)) | 819 | if (time_before(next, jiffies + HZ/2)) |
811 | next = jiffies + HZ/2; | 820 | next = jiffies + HZ/2; |
812 | neigh->timer.expires = next; | 821 | neigh_add_timer(neigh, next); |
813 | add_timer(&neigh->timer); | ||
814 | } | 822 | } |
815 | if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) { | 823 | if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) { |
816 | struct sk_buff *skb = skb_peek(&neigh->arp_queue); | 824 | struct sk_buff *skb = skb_peek(&neigh->arp_queue); |
@@ -852,8 +860,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) | |||
852 | atomic_set(&neigh->probes, neigh->parms->ucast_probes); | 860 | atomic_set(&neigh->probes, neigh->parms->ucast_probes); |
853 | neigh->nud_state = NUD_INCOMPLETE; | 861 | neigh->nud_state = NUD_INCOMPLETE; |
854 | neigh_hold(neigh); | 862 | neigh_hold(neigh); |
855 | neigh->timer.expires = now + 1; | 863 | neigh_add_timer(neigh, now + 1); |
856 | add_timer(&neigh->timer); | ||
857 | } else { | 864 | } else { |
858 | neigh->nud_state = NUD_FAILED; | 865 | neigh->nud_state = NUD_FAILED; |
859 | write_unlock_bh(&neigh->lock); | 866 | write_unlock_bh(&neigh->lock); |
@@ -866,8 +873,8 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) | |||
866 | NEIGH_PRINTK2("neigh %p is delayed.\n", neigh); | 873 | NEIGH_PRINTK2("neigh %p is delayed.\n", neigh); |
867 | neigh_hold(neigh); | 874 | neigh_hold(neigh); |
868 | neigh->nud_state = NUD_DELAY; | 875 | neigh->nud_state = NUD_DELAY; |
869 | neigh->timer.expires = jiffies + neigh->parms->delay_probe_time; | 876 | neigh_add_timer(neigh, |
870 | add_timer(&neigh->timer); | 877 | jiffies + neigh->parms->delay_probe_time); |
871 | } | 878 | } |
872 | 879 | ||
873 | if (neigh->nud_state == NUD_INCOMPLETE) { | 880 | if (neigh->nud_state == NUD_INCOMPLETE) { |
@@ -1013,10 +1020,10 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, | |||
1013 | neigh_del_timer(neigh); | 1020 | neigh_del_timer(neigh); |
1014 | if (new & NUD_IN_TIMER) { | 1021 | if (new & NUD_IN_TIMER) { |
1015 | neigh_hold(neigh); | 1022 | neigh_hold(neigh); |
1016 | neigh->timer.expires = jiffies + | 1023 | neigh_add_timer(neigh, (jiffies + |
1017 | ((new & NUD_REACHABLE) ? | 1024 | ((new & NUD_REACHABLE) ? |
1018 | neigh->parms->reachable_time : 0); | 1025 | neigh->parms->reachable_time : |
1019 | add_timer(&neigh->timer); | 1026 | 0))); |
1020 | } | 1027 | } |
1021 | neigh->nud_state = new; | 1028 | neigh->nud_state = new; |
1022 | } | 1029 | } |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 3cf9b451675c..2cd7e7d1ac90 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -537,6 +537,17 @@ config IP_NF_TARGET_TCPMSS | |||
537 | 537 | ||
538 | To compile it as a module, choose M here. If unsure, say N. | 538 | To compile it as a module, choose M here. If unsure, say N. |
539 | 539 | ||
540 | config IP_NF_TARGET_NFQUEUE | ||
541 | tristate "NFQUEUE Target Support" | ||
542 | depends on IP_NF_IPTABLES | ||
543 | help | ||
544 | This Target replaced the old obsolete QUEUE target. | ||
545 | |||
546 | As opposed to QUEUE, it supports 65535 different queues, | ||
547 | not just one. | ||
548 | |||
549 | To compile it as a module, choose M here. If unsure, say N. | ||
550 | |||
540 | # NAT + specific targets | 551 | # NAT + specific targets |
541 | config IP_NF_NAT | 552 | config IP_NF_NAT |
542 | tristate "Full NAT" | 553 | tristate "Full NAT" |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 3d45d3c0283c..dab4b58dd31e 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -4,7 +4,8 @@ | |||
4 | 4 | ||
5 | # objects for the standalone - connection tracking / NAT | 5 | # objects for the standalone - connection tracking / NAT |
6 | ip_conntrack-objs := ip_conntrack_standalone.o ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o | 6 | ip_conntrack-objs := ip_conntrack_standalone.o ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o |
7 | iptable_nat-objs := ip_nat_standalone.o ip_nat_rule.o ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o | 7 | ip_nat-objs := ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o |
8 | iptable_nat-objs := ip_nat_rule.o ip_nat_standalone.o | ||
8 | 9 | ||
9 | ip_conntrack_pptp-objs := ip_conntrack_helper_pptp.o ip_conntrack_proto_gre.o | 10 | ip_conntrack_pptp-objs := ip_conntrack_helper_pptp.o ip_conntrack_proto_gre.o |
10 | ip_nat_pptp-objs := ip_nat_helper_pptp.o ip_nat_proto_gre.o | 11 | ip_nat_pptp-objs := ip_nat_helper_pptp.o ip_nat_proto_gre.o |
@@ -40,7 +41,7 @@ obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o | |||
40 | # the three instances of ip_tables | 41 | # the three instances of ip_tables |
41 | obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o | 42 | obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o |
42 | obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o | 43 | obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o |
43 | obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o | 44 | obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o ip_nat.o |
44 | obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o | 45 | obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o |
45 | 46 | ||
46 | # matches | 47 | # matches |
@@ -92,6 +93,7 @@ obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o | |||
92 | obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o | 93 | obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o |
93 | obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o | 94 | obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o |
94 | obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o | 95 | obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o |
96 | obj-$(CONFIG_IP_NF_TARGET_NFQUEUE) += ipt_NFQUEUE.o | ||
95 | 97 | ||
96 | # generic ARP tables | 98 | # generic ARP tables |
97 | obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o | 99 | obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o |
@@ -101,4 +103,3 @@ obj-$(CONFIG_IP_NF_ARP_MANGLE) += arpt_mangle.o | |||
101 | obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o | 103 | obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o |
102 | 104 | ||
103 | obj-$(CONFIG_IP_NF_QUEUE) += ip_queue.o | 105 | obj-$(CONFIG_IP_NF_QUEUE) += ip_queue.o |
104 | obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += ipt_NFQUEUE.o | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_gre.c b/net/ipv4/netfilter/ip_conntrack_proto_gre.c index de3cb9db6f85..744abb9d377a 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_gre.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_gre.c | |||
@@ -247,6 +247,7 @@ static int gre_packet(struct ip_conntrack *ct, | |||
247 | ct->proto.gre.stream_timeout); | 247 | ct->proto.gre.stream_timeout); |
248 | /* Also, more likely to be important, and not a probe. */ | 248 | /* Also, more likely to be important, and not a probe. */ |
249 | set_bit(IPS_ASSURED_BIT, &ct->status); | 249 | set_bit(IPS_ASSURED_BIT, &ct->status); |
250 | ip_conntrack_event_cache(IPCT_STATUS, skb); | ||
250 | } else | 251 | } else |
251 | ip_ct_refresh_acct(ct, conntrackinfo, skb, | 252 | ip_ct_refresh_acct(ct, conntrackinfo, skb, |
252 | ct->proto.gre.timeout); | 253 | ct->proto.gre.timeout); |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c index a875f35e576d..59a4a0111dd3 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c | |||
@@ -416,6 +416,7 @@ static int sctp_packet(struct ip_conntrack *conntrack, | |||
416 | && newconntrack == SCTP_CONNTRACK_ESTABLISHED) { | 416 | && newconntrack == SCTP_CONNTRACK_ESTABLISHED) { |
417 | DEBUGP("Setting assured bit\n"); | 417 | DEBUGP("Setting assured bit\n"); |
418 | set_bit(IPS_ASSURED_BIT, &conntrack->status); | 418 | set_bit(IPS_ASSURED_BIT, &conntrack->status); |
419 | ip_conntrack_event_cache(IPCT_STATUS, skb); | ||
419 | } | 420 | } |
420 | 421 | ||
421 | return NF_ACCEPT; | 422 | return NF_ACCEPT; |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index 1985abc59d24..121760d6cc50 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c | |||
@@ -1014,7 +1014,8 @@ static int tcp_packet(struct ip_conntrack *conntrack, | |||
1014 | /* Set ASSURED if we see see valid ack in ESTABLISHED | 1014 | /* Set ASSURED if we see see valid ack in ESTABLISHED |
1015 | after SYN_RECV or a valid answer for a picked up | 1015 | after SYN_RECV or a valid answer for a picked up |
1016 | connection. */ | 1016 | connection. */ |
1017 | set_bit(IPS_ASSURED_BIT, &conntrack->status); | 1017 | set_bit(IPS_ASSURED_BIT, &conntrack->status); |
1018 | ip_conntrack_event_cache(IPCT_STATUS, skb); | ||
1018 | } | 1019 | } |
1019 | ip_ct_refresh_acct(conntrack, ctinfo, skb, timeout); | 1020 | ip_ct_refresh_acct(conntrack, ctinfo, skb, timeout); |
1020 | 1021 | ||
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c index c3ea891d38e7..c5e3abd24672 100644 --- a/net/ipv4/netfilter/ip_nat_core.c +++ b/net/ipv4/netfilter/ip_nat_core.c | |||
@@ -74,12 +74,14 @@ ip_nat_proto_find_get(u_int8_t protonum) | |||
74 | 74 | ||
75 | return p; | 75 | return p; |
76 | } | 76 | } |
77 | EXPORT_SYMBOL_GPL(ip_nat_proto_find_get); | ||
77 | 78 | ||
78 | void | 79 | void |
79 | ip_nat_proto_put(struct ip_nat_protocol *p) | 80 | ip_nat_proto_put(struct ip_nat_protocol *p) |
80 | { | 81 | { |
81 | module_put(p->me); | 82 | module_put(p->me); |
82 | } | 83 | } |
84 | EXPORT_SYMBOL_GPL(ip_nat_proto_put); | ||
83 | 85 | ||
84 | /* We keep an extra hash for each conntrack, for fast searching. */ | 86 | /* We keep an extra hash for each conntrack, for fast searching. */ |
85 | static inline unsigned int | 87 | static inline unsigned int |
@@ -111,6 +113,7 @@ ip_nat_cheat_check(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck) | |||
111 | return csum_fold(csum_partial((char *)diffs, sizeof(diffs), | 113 | return csum_fold(csum_partial((char *)diffs, sizeof(diffs), |
112 | oldcheck^0xFFFF)); | 114 | oldcheck^0xFFFF)); |
113 | } | 115 | } |
116 | EXPORT_SYMBOL(ip_nat_cheat_check); | ||
114 | 117 | ||
115 | /* Is this tuple already taken? (not by us) */ | 118 | /* Is this tuple already taken? (not by us) */ |
116 | int | 119 | int |
@@ -127,6 +130,7 @@ ip_nat_used_tuple(const struct ip_conntrack_tuple *tuple, | |||
127 | invert_tuplepr(&reply, tuple); | 130 | invert_tuplepr(&reply, tuple); |
128 | return ip_conntrack_tuple_taken(&reply, ignored_conntrack); | 131 | return ip_conntrack_tuple_taken(&reply, ignored_conntrack); |
129 | } | 132 | } |
133 | EXPORT_SYMBOL(ip_nat_used_tuple); | ||
130 | 134 | ||
131 | /* If we source map this tuple so reply looks like reply_tuple, will | 135 | /* If we source map this tuple so reply looks like reply_tuple, will |
132 | * that meet the constraints of range. */ | 136 | * that meet the constraints of range. */ |
@@ -347,6 +351,7 @@ ip_nat_setup_info(struct ip_conntrack *conntrack, | |||
347 | 351 | ||
348 | return NF_ACCEPT; | 352 | return NF_ACCEPT; |
349 | } | 353 | } |
354 | EXPORT_SYMBOL(ip_nat_setup_info); | ||
350 | 355 | ||
351 | /* Returns true if succeeded. */ | 356 | /* Returns true if succeeded. */ |
352 | static int | 357 | static int |
@@ -387,10 +392,10 @@ manip_pkt(u_int16_t proto, | |||
387 | } | 392 | } |
388 | 393 | ||
389 | /* Do packet manipulations according to ip_nat_setup_info. */ | 394 | /* Do packet manipulations according to ip_nat_setup_info. */ |
390 | unsigned int nat_packet(struct ip_conntrack *ct, | 395 | unsigned int ip_nat_packet(struct ip_conntrack *ct, |
391 | enum ip_conntrack_info ctinfo, | 396 | enum ip_conntrack_info ctinfo, |
392 | unsigned int hooknum, | 397 | unsigned int hooknum, |
393 | struct sk_buff **pskb) | 398 | struct sk_buff **pskb) |
394 | { | 399 | { |
395 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); | 400 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); |
396 | unsigned long statusbit; | 401 | unsigned long statusbit; |
@@ -417,12 +422,13 @@ unsigned int nat_packet(struct ip_conntrack *ct, | |||
417 | } | 422 | } |
418 | return NF_ACCEPT; | 423 | return NF_ACCEPT; |
419 | } | 424 | } |
425 | EXPORT_SYMBOL_GPL(ip_nat_packet); | ||
420 | 426 | ||
421 | /* Dir is direction ICMP is coming from (opposite to packet it contains) */ | 427 | /* Dir is direction ICMP is coming from (opposite to packet it contains) */ |
422 | int icmp_reply_translation(struct sk_buff **pskb, | 428 | int ip_nat_icmp_reply_translation(struct sk_buff **pskb, |
423 | struct ip_conntrack *ct, | 429 | struct ip_conntrack *ct, |
424 | enum ip_nat_manip_type manip, | 430 | enum ip_nat_manip_type manip, |
425 | enum ip_conntrack_dir dir) | 431 | enum ip_conntrack_dir dir) |
426 | { | 432 | { |
427 | struct { | 433 | struct { |
428 | struct icmphdr icmp; | 434 | struct icmphdr icmp; |
@@ -509,6 +515,7 @@ int icmp_reply_translation(struct sk_buff **pskb, | |||
509 | 515 | ||
510 | return 1; | 516 | return 1; |
511 | } | 517 | } |
518 | EXPORT_SYMBOL_GPL(ip_nat_icmp_reply_translation); | ||
512 | 519 | ||
513 | /* Protocol registration. */ | 520 | /* Protocol registration. */ |
514 | int ip_nat_protocol_register(struct ip_nat_protocol *proto) | 521 | int ip_nat_protocol_register(struct ip_nat_protocol *proto) |
@@ -525,6 +532,7 @@ int ip_nat_protocol_register(struct ip_nat_protocol *proto) | |||
525 | write_unlock_bh(&ip_nat_lock); | 532 | write_unlock_bh(&ip_nat_lock); |
526 | return ret; | 533 | return ret; |
527 | } | 534 | } |
535 | EXPORT_SYMBOL(ip_nat_protocol_register); | ||
528 | 536 | ||
529 | /* Noone stores the protocol anywhere; simply delete it. */ | 537 | /* Noone stores the protocol anywhere; simply delete it. */ |
530 | void ip_nat_protocol_unregister(struct ip_nat_protocol *proto) | 538 | void ip_nat_protocol_unregister(struct ip_nat_protocol *proto) |
@@ -536,6 +544,7 @@ void ip_nat_protocol_unregister(struct ip_nat_protocol *proto) | |||
536 | /* Someone could be still looking at the proto in a bh. */ | 544 | /* Someone could be still looking at the proto in a bh. */ |
537 | synchronize_net(); | 545 | synchronize_net(); |
538 | } | 546 | } |
547 | EXPORT_SYMBOL(ip_nat_protocol_unregister); | ||
539 | 548 | ||
540 | #if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \ | 549 | #if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \ |
541 | defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE) | 550 | defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE) |
@@ -582,7 +591,7 @@ EXPORT_SYMBOL_GPL(ip_nat_port_nfattr_to_range); | |||
582 | EXPORT_SYMBOL_GPL(ip_nat_port_range_to_nfattr); | 591 | EXPORT_SYMBOL_GPL(ip_nat_port_range_to_nfattr); |
583 | #endif | 592 | #endif |
584 | 593 | ||
585 | int __init ip_nat_init(void) | 594 | static int __init ip_nat_init(void) |
586 | { | 595 | { |
587 | size_t i; | 596 | size_t i; |
588 | 597 | ||
@@ -624,10 +633,14 @@ static int clean_nat(struct ip_conntrack *i, void *data) | |||
624 | return 0; | 633 | return 0; |
625 | } | 634 | } |
626 | 635 | ||
627 | /* Not __exit: called from ip_nat_standalone.c:init_or_cleanup() --RR */ | 636 | static void __exit ip_nat_cleanup(void) |
628 | void ip_nat_cleanup(void) | ||
629 | { | 637 | { |
630 | ip_ct_iterate_cleanup(&clean_nat, NULL); | 638 | ip_ct_iterate_cleanup(&clean_nat, NULL); |
631 | ip_conntrack_destroyed = NULL; | 639 | ip_conntrack_destroyed = NULL; |
632 | vfree(bysource); | 640 | vfree(bysource); |
633 | } | 641 | } |
642 | |||
643 | MODULE_LICENSE("GPL"); | ||
644 | |||
645 | module_init(ip_nat_init); | ||
646 | module_exit(ip_nat_cleanup); | ||
diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c index d2dd5d313556..5d506e0564d5 100644 --- a/net/ipv4/netfilter/ip_nat_helper.c +++ b/net/ipv4/netfilter/ip_nat_helper.c | |||
@@ -199,6 +199,7 @@ ip_nat_mangle_tcp_packet(struct sk_buff **pskb, | |||
199 | } | 199 | } |
200 | return 1; | 200 | return 1; |
201 | } | 201 | } |
202 | EXPORT_SYMBOL(ip_nat_mangle_tcp_packet); | ||
202 | 203 | ||
203 | /* Generic function for mangling variable-length address changes inside | 204 | /* Generic function for mangling variable-length address changes inside |
204 | * NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX | 205 | * NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX |
@@ -256,6 +257,7 @@ ip_nat_mangle_udp_packet(struct sk_buff **pskb, | |||
256 | 257 | ||
257 | return 1; | 258 | return 1; |
258 | } | 259 | } |
260 | EXPORT_SYMBOL(ip_nat_mangle_udp_packet); | ||
259 | 261 | ||
260 | /* Adjust one found SACK option including checksum correction */ | 262 | /* Adjust one found SACK option including checksum correction */ |
261 | static void | 263 | static void |
@@ -399,6 +401,7 @@ ip_nat_seq_adjust(struct sk_buff **pskb, | |||
399 | 401 | ||
400 | return 1; | 402 | return 1; |
401 | } | 403 | } |
404 | EXPORT_SYMBOL(ip_nat_seq_adjust); | ||
402 | 405 | ||
403 | /* Setup NAT on this expected conntrack so it follows master. */ | 406 | /* Setup NAT on this expected conntrack so it follows master. */ |
404 | /* If we fail to get a free NAT slot, we'll get dropped on confirm */ | 407 | /* If we fail to get a free NAT slot, we'll get dropped on confirm */ |
@@ -425,3 +428,4 @@ void ip_nat_follow_master(struct ip_conntrack *ct, | |||
425 | /* hook doesn't matter, but it has to do destination manip */ | 428 | /* hook doesn't matter, but it has to do destination manip */ |
426 | ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING); | 429 | ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING); |
427 | } | 430 | } |
431 | EXPORT_SYMBOL(ip_nat_follow_master); | ||
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 0ff368b131f6..30cd4e18c129 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c | |||
@@ -108,8 +108,8 @@ ip_nat_fn(unsigned int hooknum, | |||
108 | case IP_CT_RELATED: | 108 | case IP_CT_RELATED: |
109 | case IP_CT_RELATED+IP_CT_IS_REPLY: | 109 | case IP_CT_RELATED+IP_CT_IS_REPLY: |
110 | if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP) { | 110 | if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP) { |
111 | if (!icmp_reply_translation(pskb, ct, maniptype, | 111 | if (!ip_nat_icmp_reply_translation(pskb, ct, maniptype, |
112 | CTINFO2DIR(ctinfo))) | 112 | CTINFO2DIR(ctinfo))) |
113 | return NF_DROP; | 113 | return NF_DROP; |
114 | else | 114 | else |
115 | return NF_ACCEPT; | 115 | return NF_ACCEPT; |
@@ -152,7 +152,7 @@ ip_nat_fn(unsigned int hooknum, | |||
152 | } | 152 | } |
153 | 153 | ||
154 | IP_NF_ASSERT(info); | 154 | IP_NF_ASSERT(info); |
155 | return nat_packet(ct, ctinfo, hooknum, pskb); | 155 | return ip_nat_packet(ct, ctinfo, hooknum, pskb); |
156 | } | 156 | } |
157 | 157 | ||
158 | static unsigned int | 158 | static unsigned int |
@@ -325,15 +325,10 @@ static int init_or_cleanup(int init) | |||
325 | printk("ip_nat_init: can't setup rules.\n"); | 325 | printk("ip_nat_init: can't setup rules.\n"); |
326 | goto cleanup_nothing; | 326 | goto cleanup_nothing; |
327 | } | 327 | } |
328 | ret = ip_nat_init(); | ||
329 | if (ret < 0) { | ||
330 | printk("ip_nat_init: can't setup rules.\n"); | ||
331 | goto cleanup_rule_init; | ||
332 | } | ||
333 | ret = nf_register_hook(&ip_nat_in_ops); | 328 | ret = nf_register_hook(&ip_nat_in_ops); |
334 | if (ret < 0) { | 329 | if (ret < 0) { |
335 | printk("ip_nat_init: can't register in hook.\n"); | 330 | printk("ip_nat_init: can't register in hook.\n"); |
336 | goto cleanup_nat; | 331 | goto cleanup_rule_init; |
337 | } | 332 | } |
338 | ret = nf_register_hook(&ip_nat_out_ops); | 333 | ret = nf_register_hook(&ip_nat_out_ops); |
339 | if (ret < 0) { | 334 | if (ret < 0) { |
@@ -374,8 +369,6 @@ static int init_or_cleanup(int init) | |||
374 | nf_unregister_hook(&ip_nat_out_ops); | 369 | nf_unregister_hook(&ip_nat_out_ops); |
375 | cleanup_inops: | 370 | cleanup_inops: |
376 | nf_unregister_hook(&ip_nat_in_ops); | 371 | nf_unregister_hook(&ip_nat_in_ops); |
377 | cleanup_nat: | ||
378 | ip_nat_cleanup(); | ||
379 | cleanup_rule_init: | 372 | cleanup_rule_init: |
380 | ip_nat_rule_cleanup(); | 373 | ip_nat_rule_cleanup(); |
381 | cleanup_nothing: | 374 | cleanup_nothing: |
@@ -395,14 +388,4 @@ static void __exit fini(void) | |||
395 | module_init(init); | 388 | module_init(init); |
396 | module_exit(fini); | 389 | module_exit(fini); |
397 | 390 | ||
398 | EXPORT_SYMBOL(ip_nat_setup_info); | ||
399 | EXPORT_SYMBOL(ip_nat_protocol_register); | ||
400 | EXPORT_SYMBOL(ip_nat_protocol_unregister); | ||
401 | EXPORT_SYMBOL_GPL(ip_nat_proto_find_get); | ||
402 | EXPORT_SYMBOL_GPL(ip_nat_proto_put); | ||
403 | EXPORT_SYMBOL(ip_nat_cheat_check); | ||
404 | EXPORT_SYMBOL(ip_nat_mangle_tcp_packet); | ||
405 | EXPORT_SYMBOL(ip_nat_mangle_udp_packet); | ||
406 | EXPORT_SYMBOL(ip_nat_used_tuple); | ||
407 | EXPORT_SYMBOL(ip_nat_follow_master); | ||
408 | MODULE_LICENSE("GPL"); | 391 | MODULE_LICENSE("GPL"); |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 2fea3f4402a0..4e509e52fbc1 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3520,6 +3520,8 @@ int __init addrconf_init(void) | |||
3520 | if (err) | 3520 | if (err) |
3521 | return err; | 3521 | return err; |
3522 | 3522 | ||
3523 | ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev); | ||
3524 | |||
3523 | register_netdevice_notifier(&ipv6_dev_notf); | 3525 | register_netdevice_notifier(&ipv6_dev_notf); |
3524 | 3526 | ||
3525 | #ifdef CONFIG_IPV6_PRIVACY | 3527 | #ifdef CONFIG_IPV6_PRIVACY |
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 216fbe1ac65c..bb7ccfe33f23 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
@@ -209,6 +209,17 @@ config IP6_NF_TARGET_REJECT | |||
209 | 209 | ||
210 | To compile it as a module, choose M here. If unsure, say N. | 210 | To compile it as a module, choose M here. If unsure, say N. |
211 | 211 | ||
212 | config IP6_NF_TARGET_NFQUEUE | ||
213 | tristate "NFQUEUE Target Support" | ||
214 | depends on IP_NF_IPTABLES | ||
215 | help | ||
216 | This Target replaced the old obsolete QUEUE target. | ||
217 | |||
218 | As opposed to QUEUE, it supports 65535 different queues, | ||
219 | not just one. | ||
220 | |||
221 | To compile it as a module, choose M here. If unsure, say N. | ||
222 | |||
212 | # if [ "$CONFIG_IP6_NF_FILTER" != "n" ]; then | 223 | # if [ "$CONFIG_IP6_NF_FILTER" != "n" ]; then |
213 | # dep_tristate ' REJECT target support' CONFIG_IP6_NF_TARGET_REJECT $CONFIG_IP6_NF_FILTER | 224 | # dep_tristate ' REJECT target support' CONFIG_IP6_NF_TARGET_REJECT $CONFIG_IP6_NF_FILTER |
214 | # if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then | 225 | # if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then |
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index bd9a16a5cbba..2b2c370e8b1c 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile | |||
@@ -21,9 +21,9 @@ obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o | |||
21 | obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o | 21 | obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o |
22 | obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o | 22 | obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o |
23 | obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o | 23 | obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o |
24 | obj-$(CONFIG_IP6_NF_TARGET_NFQUEUE) += ip6t_NFQUEUE.o | ||
24 | obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o | 25 | obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o |
25 | obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o | 26 | obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o |
26 | obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o | 27 | obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o |
27 | obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o | 28 | obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o |
28 | obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o | 29 | obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o |
29 | obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += ip6t_NFQUEUE.o | ||
diff --git a/net/irda/irttp.c b/net/irda/irttp.c index 6602d901f8b1..8aff254cb418 100644 --- a/net/irda/irttp.c +++ b/net/irda/irttp.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <net/irda/parameters.h> | 38 | #include <net/irda/parameters.h> |
39 | #include <net/irda/irttp.h> | 39 | #include <net/irda/irttp.h> |
40 | 40 | ||
41 | static struct irttp_cb *irttp = NULL; | 41 | static struct irttp_cb *irttp; |
42 | 42 | ||
43 | static void __irttp_close_tsap(struct tsap_cb *self); | 43 | static void __irttp_close_tsap(struct tsap_cb *self); |
44 | 44 | ||
@@ -86,12 +86,9 @@ static pi_param_info_t param_info = { pi_major_call_table, 1, 0x0f, 4 }; | |||
86 | */ | 86 | */ |
87 | int __init irttp_init(void) | 87 | int __init irttp_init(void) |
88 | { | 88 | { |
89 | /* Initialize the irttp structure. */ | 89 | irttp = kmalloc(sizeof(struct irttp_cb), GFP_KERNEL); |
90 | if (irttp == NULL) { | 90 | if (irttp == NULL) |
91 | irttp = kmalloc(sizeof(struct irttp_cb), GFP_KERNEL); | 91 | return -ENOMEM; |
92 | if (irttp == NULL) | ||
93 | return -ENOMEM; | ||
94 | } | ||
95 | memset(irttp, 0, sizeof(struct irttp_cb)); | 92 | memset(irttp, 0, sizeof(struct irttp_cb)); |
96 | 93 | ||
97 | irttp->magic = TTP_MAGIC; | 94 | irttp->magic = TTP_MAGIC; |
@@ -100,6 +97,7 @@ int __init irttp_init(void) | |||
100 | if (!irttp->tsaps) { | 97 | if (!irttp->tsaps) { |
101 | IRDA_ERROR("%s: can't allocate IrTTP hashbin!\n", | 98 | IRDA_ERROR("%s: can't allocate IrTTP hashbin!\n", |
102 | __FUNCTION__); | 99 | __FUNCTION__); |
100 | kfree(irttp); | ||
103 | return -ENOMEM; | 101 | return -ENOMEM; |
104 | } | 102 | } |
105 | 103 | ||
@@ -115,7 +113,6 @@ int __init irttp_init(void) | |||
115 | void __exit irttp_cleanup(void) | 113 | void __exit irttp_cleanup(void) |
116 | { | 114 | { |
117 | /* Check for main structure */ | 115 | /* Check for main structure */ |
118 | IRDA_ASSERT(irttp != NULL, return;); | ||
119 | IRDA_ASSERT(irttp->magic == TTP_MAGIC, return;); | 116 | IRDA_ASSERT(irttp->magic == TTP_MAGIC, return;); |
120 | 117 | ||
121 | /* | 118 | /* |
@@ -382,7 +379,6 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify) | |||
382 | struct lsap_cb *lsap; | 379 | struct lsap_cb *lsap; |
383 | notify_t ttp_notify; | 380 | notify_t ttp_notify; |
384 | 381 | ||
385 | IRDA_ASSERT(irttp != NULL, return NULL;); | ||
386 | IRDA_ASSERT(irttp->magic == TTP_MAGIC, return NULL;); | 382 | IRDA_ASSERT(irttp->magic == TTP_MAGIC, return NULL;); |
387 | 383 | ||
388 | /* The IrLMP spec (IrLMP 1.1 p10) says that we have the right to | 384 | /* The IrLMP spec (IrLMP 1.1 p10) says that we have the right to |
@@ -1880,8 +1876,6 @@ static int irttp_seq_open(struct inode *inode, struct file *file) | |||
1880 | struct seq_file *seq; | 1876 | struct seq_file *seq; |
1881 | int rc = -ENOMEM; | 1877 | int rc = -ENOMEM; |
1882 | struct irttp_iter_state *s; | 1878 | struct irttp_iter_state *s; |
1883 | |||
1884 | IRDA_ASSERT(irttp != NULL, return -EINVAL;); | ||
1885 | 1879 | ||
1886 | s = kmalloc(sizeof(*s), GFP_KERNEL); | 1880 | s = kmalloc(sizeof(*s), GFP_KERNEL); |
1887 | if (!s) | 1881 | if (!s) |
diff --git a/net/llc/Makefile b/net/llc/Makefile index 5ebd4ed2bd42..4e260cff3c5d 100644 --- a/net/llc/Makefile +++ b/net/llc/Makefile | |||
@@ -22,3 +22,4 @@ llc2-y := llc_if.o llc_c_ev.o llc_c_ac.o llc_conn.o llc_c_st.o llc_pdu.o \ | |||
22 | llc_sap.o llc_s_ac.o llc_s_ev.o llc_s_st.o af_llc.o llc_station.o | 22 | llc_sap.o llc_s_ac.o llc_s_ev.o llc_s_st.o af_llc.o llc_station.o |
23 | 23 | ||
24 | llc2-$(CONFIG_PROC_FS) += llc_proc.o | 24 | llc2-$(CONFIG_PROC_FS) += llc_proc.o |
25 | llc2-$(CONFIG_SYSCTL) += sysctl_net_llc.o | ||
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 66f55e514b56..59d02cbbeb9e 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
@@ -21,6 +21,7 @@ | |||
21 | * See the GNU General Public License for more details. | 21 | * See the GNU General Public License for more details. |
22 | */ | 22 | */ |
23 | #include <linux/config.h> | 23 | #include <linux/config.h> |
24 | #include <linux/compiler.h> | ||
24 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
25 | #include <linux/module.h> | 26 | #include <linux/module.h> |
26 | #include <linux/rtnetlink.h> | 27 | #include <linux/rtnetlink.h> |
@@ -37,10 +38,9 @@ static u16 llc_ui_sap_link_no_max[256]; | |||
37 | static struct sockaddr_llc llc_ui_addrnull; | 38 | static struct sockaddr_llc llc_ui_addrnull; |
38 | static struct proto_ops llc_ui_ops; | 39 | static struct proto_ops llc_ui_ops; |
39 | 40 | ||
40 | static int llc_ui_wait_for_conn(struct sock *sk, int timeout); | 41 | static int llc_ui_wait_for_conn(struct sock *sk, long timeout); |
41 | static int llc_ui_wait_for_disc(struct sock *sk, int timeout); | 42 | static int llc_ui_wait_for_disc(struct sock *sk, long timeout); |
42 | static int llc_ui_wait_for_data(struct sock *sk, int timeout); | 43 | static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout); |
43 | static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout); | ||
44 | 44 | ||
45 | #if 0 | 45 | #if 0 |
46 | #define dprintk(args...) printk(KERN_DEBUG args) | 46 | #define dprintk(args...) printk(KERN_DEBUG args) |
@@ -116,12 +116,12 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, int noblock) | |||
116 | struct llc_sock* llc = llc_sk(sk); | 116 | struct llc_sock* llc = llc_sk(sk); |
117 | int rc = 0; | 117 | int rc = 0; |
118 | 118 | ||
119 | if (llc_data_accept_state(llc->state) || llc->p_flag) { | 119 | if (unlikely(llc_data_accept_state(llc->state) || llc->p_flag)) { |
120 | int timeout = sock_sndtimeo(sk, noblock); | 120 | long timeout = sock_sndtimeo(sk, noblock); |
121 | 121 | ||
122 | rc = llc_ui_wait_for_busy_core(sk, timeout); | 122 | rc = llc_ui_wait_for_busy_core(sk, timeout); |
123 | } | 123 | } |
124 | if (!rc) | 124 | if (unlikely(!rc)) |
125 | rc = llc_build_and_send_pkt(sk, skb); | 125 | rc = llc_build_and_send_pkt(sk, skb); |
126 | return rc; | 126 | return rc; |
127 | } | 127 | } |
@@ -155,7 +155,7 @@ static int llc_ui_create(struct socket *sock, int protocol) | |||
155 | struct sock *sk; | 155 | struct sock *sk; |
156 | int rc = -ESOCKTNOSUPPORT; | 156 | int rc = -ESOCKTNOSUPPORT; |
157 | 157 | ||
158 | if (sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM) { | 158 | if (likely(sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM)) { |
159 | rc = -ENOMEM; | 159 | rc = -ENOMEM; |
160 | sk = llc_sk_alloc(PF_LLC, GFP_KERNEL, &llc_proto); | 160 | sk = llc_sk_alloc(PF_LLC, GFP_KERNEL, &llc_proto); |
161 | if (sk) { | 161 | if (sk) { |
@@ -177,7 +177,7 @@ static int llc_ui_release(struct socket *sock) | |||
177 | struct sock *sk = sock->sk; | 177 | struct sock *sk = sock->sk; |
178 | struct llc_sock *llc; | 178 | struct llc_sock *llc; |
179 | 179 | ||
180 | if (!sk) | 180 | if (unlikely(sk == NULL)) |
181 | goto out; | 181 | goto out; |
182 | sock_hold(sk); | 182 | sock_hold(sk); |
183 | lock_sock(sk); | 183 | lock_sock(sk); |
@@ -189,10 +189,6 @@ static int llc_ui_release(struct socket *sock) | |||
189 | if (!sock_flag(sk, SOCK_ZAPPED)) | 189 | if (!sock_flag(sk, SOCK_ZAPPED)) |
190 | llc_sap_remove_socket(llc->sap, sk); | 190 | llc_sap_remove_socket(llc->sap, sk); |
191 | release_sock(sk); | 191 | release_sock(sk); |
192 | if (llc->sap && hlist_empty(&llc->sap->sk_list.list)) { | ||
193 | llc_release_sockets(llc->sap); | ||
194 | llc_sap_close(llc->sap); | ||
195 | } | ||
196 | if (llc->dev) | 192 | if (llc->dev) |
197 | dev_put(llc->dev); | 193 | dev_put(llc->dev); |
198 | sock_put(sk); | 194 | sock_put(sk); |
@@ -221,6 +217,7 @@ static int llc_ui_autoport(void) | |||
221 | llc_ui_sap_last_autoport = i + 2; | 217 | llc_ui_sap_last_autoport = i + 2; |
222 | goto out; | 218 | goto out; |
223 | } | 219 | } |
220 | llc_sap_put(sap); | ||
224 | } | 221 | } |
225 | llc_ui_sap_last_autoport = LLC_SAP_DYN_START; | 222 | llc_ui_sap_last_autoport = LLC_SAP_DYN_START; |
226 | tries++; | 223 | tries++; |
@@ -231,20 +228,13 @@ out: | |||
231 | } | 228 | } |
232 | 229 | ||
233 | /** | 230 | /** |
234 | * llc_ui_autobind - Bind a socket to a specific address. | 231 | * llc_ui_autobind - automatically bind a socket to a sap |
235 | * @sk: Socket to bind an address to. | 232 | * @sock: socket to bind |
236 | * @addr: Address the user wants the socket bound to. | 233 | * @addr: address to connect to |
234 | * | ||
235 | * Used by llc_ui_connect and llc_ui_sendmsg when the user hasn't | ||
236 | * specifically used llc_ui_bind to bind to an specific address/sap | ||
237 | * | 237 | * |
238 | * Bind a socket to a specific address. For llc a user is able to bind to | ||
239 | * a specific sap only or mac + sap. If the user only specifies a sap and | ||
240 | * a null dmac (all zeros) the user is attempting to bind to an entire | ||
241 | * sap. This will stop anyone else on the local system from using that | ||
242 | * sap. If someone else has a mac + sap open the bind to null + sap will | ||
243 | * fail. | ||
244 | * If the user desires to bind to a specific mac + sap, it is possible to | ||
245 | * have multiple sap connections via multiple macs. | ||
246 | * Bind and autobind for that matter must enforce the correct sap usage | ||
247 | * otherwise all hell will break loose. | ||
248 | * Returns: 0 upon success, negative otherwise. | 238 | * Returns: 0 upon success, negative otherwise. |
249 | */ | 239 | */ |
250 | static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) | 240 | static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) |
@@ -285,11 +275,7 @@ out: | |||
285 | * @addrlen: Length of the uaddr structure. | 275 | * @addrlen: Length of the uaddr structure. |
286 | * | 276 | * |
287 | * Bind a socket to a specific address. For llc a user is able to bind to | 277 | * Bind a socket to a specific address. For llc a user is able to bind to |
288 | * a specific sap only or mac + sap. If the user only specifies a sap and | 278 | * a specific sap only or mac + sap. |
289 | * a null dmac (all zeros) the user is attempting to bind to an entire | ||
290 | * sap. This will stop anyone else on the local system from using that | ||
291 | * sap. If someone else has a mac + sap open the bind to null + sap will | ||
292 | * fail. | ||
293 | * If the user desires to bind to a specific mac + sap, it is possible to | 279 | * If the user desires to bind to a specific mac + sap, it is possible to |
294 | * have multiple sap connections via multiple macs. | 280 | * have multiple sap connections via multiple macs. |
295 | * Bind and autobind for that matter must enforce the correct sap usage | 281 | * Bind and autobind for that matter must enforce the correct sap usage |
@@ -305,10 +291,16 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) | |||
305 | int rc = -EINVAL; | 291 | int rc = -EINVAL; |
306 | 292 | ||
307 | dprintk("%s: binding %02X\n", __FUNCTION__, addr->sllc_sap); | 293 | dprintk("%s: binding %02X\n", __FUNCTION__, addr->sllc_sap); |
308 | if (!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr)) | 294 | if (unlikely(!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr))) |
309 | goto out; | 295 | goto out; |
310 | rc = -EAFNOSUPPORT; | 296 | rc = -EAFNOSUPPORT; |
311 | if (addr->sllc_family != AF_LLC) | 297 | if (unlikely(addr->sllc_family != AF_LLC)) |
298 | goto out; | ||
299 | rc = -ENODEV; | ||
300 | rtnl_lock(); | ||
301 | llc->dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_mac); | ||
302 | rtnl_unlock(); | ||
303 | if (!llc->dev) | ||
312 | goto out; | 304 | goto out; |
313 | if (!addr->sllc_sap) { | 305 | if (!addr->sllc_sap) { |
314 | rc = -EUSERS; | 306 | rc = -EUSERS; |
@@ -322,6 +314,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) | |||
322 | rc = -EBUSY; /* some other network layer is using the sap */ | 314 | rc = -EBUSY; /* some other network layer is using the sap */ |
323 | if (!sap) | 315 | if (!sap) |
324 | goto out; | 316 | goto out; |
317 | llc_sap_hold(sap); | ||
325 | } else { | 318 | } else { |
326 | struct llc_addr laddr, daddr; | 319 | struct llc_addr laddr, daddr; |
327 | struct sock *ask; | 320 | struct sock *ask; |
@@ -338,7 +331,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) | |||
338 | ask = llc_lookup_established(sap, &daddr, &laddr); | 331 | ask = llc_lookup_established(sap, &daddr, &laddr); |
339 | if (ask) { | 332 | if (ask) { |
340 | sock_put(ask); | 333 | sock_put(ask); |
341 | goto out; | 334 | goto out_put; |
342 | } | 335 | } |
343 | } | 336 | } |
344 | llc->laddr.lsap = addr->sllc_sap; | 337 | llc->laddr.lsap = addr->sllc_sap; |
@@ -348,6 +341,8 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) | |||
348 | llc_sap_add_socket(sap, sk); | 341 | llc_sap_add_socket(sap, sk); |
349 | sock_reset_flag(sk, SOCK_ZAPPED); | 342 | sock_reset_flag(sk, SOCK_ZAPPED); |
350 | rc = 0; | 343 | rc = 0; |
344 | out_put: | ||
345 | llc_sap_put(sap); | ||
351 | out: | 346 | out: |
352 | return rc; | 347 | return rc; |
353 | } | 348 | } |
@@ -369,7 +364,7 @@ static int llc_ui_shutdown(struct socket *sock, int how) | |||
369 | int rc = -ENOTCONN; | 364 | int rc = -ENOTCONN; |
370 | 365 | ||
371 | lock_sock(sk); | 366 | lock_sock(sk); |
372 | if (sk->sk_state != TCP_ESTABLISHED) | 367 | if (unlikely(sk->sk_state != TCP_ESTABLISHED)) |
373 | goto out; | 368 | goto out; |
374 | rc = -EINVAL; | 369 | rc = -EINVAL; |
375 | if (how != 2) | 370 | if (how != 2) |
@@ -404,14 +399,18 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr, | |||
404 | struct sock *sk = sock->sk; | 399 | struct sock *sk = sock->sk; |
405 | struct llc_sock *llc = llc_sk(sk); | 400 | struct llc_sock *llc = llc_sk(sk); |
406 | struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr; | 401 | struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr; |
407 | struct net_device *dev; | ||
408 | int rc = -EINVAL; | 402 | int rc = -EINVAL; |
409 | 403 | ||
410 | lock_sock(sk); | 404 | lock_sock(sk); |
411 | if (addrlen != sizeof(*addr)) | 405 | if (unlikely(addrlen != sizeof(*addr))) |
412 | goto out; | 406 | goto out; |
413 | rc = -EAFNOSUPPORT; | 407 | rc = -EAFNOSUPPORT; |
414 | if (addr->sllc_family != AF_LLC) | 408 | if (unlikely(addr->sllc_family != AF_LLC)) |
409 | goto out; | ||
410 | if (unlikely(sk->sk_type != SOCK_STREAM)) | ||
411 | goto out; | ||
412 | rc = -EALREADY; | ||
413 | if (unlikely(sock->state == SS_CONNECTING)) | ||
415 | goto out; | 414 | goto out; |
416 | /* bind connection to sap if user hasn't done it. */ | 415 | /* bind connection to sap if user hasn't done it. */ |
417 | if (sock_flag(sk, SOCK_ZAPPED)) { | 416 | if (sock_flag(sk, SOCK_ZAPPED)) { |
@@ -419,19 +418,13 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr, | |||
419 | rc = llc_ui_autobind(sock, addr); | 418 | rc = llc_ui_autobind(sock, addr); |
420 | if (rc) | 419 | if (rc) |
421 | goto out; | 420 | goto out; |
422 | llc->daddr.lsap = addr->sllc_sap; | ||
423 | memcpy(llc->daddr.mac, addr->sllc_mac, IFHWADDRLEN); | ||
424 | } | 421 | } |
425 | dev = llc->dev; | 422 | llc->daddr.lsap = addr->sllc_sap; |
426 | if (sk->sk_type != SOCK_STREAM) | 423 | memcpy(llc->daddr.mac, addr->sllc_mac, IFHWADDRLEN); |
427 | goto out; | ||
428 | rc = -EALREADY; | ||
429 | if (sock->state == SS_CONNECTING) | ||
430 | goto out; | ||
431 | sock->state = SS_CONNECTING; | 424 | sock->state = SS_CONNECTING; |
432 | sk->sk_state = TCP_SYN_SENT; | 425 | sk->sk_state = TCP_SYN_SENT; |
433 | llc->link = llc_ui_next_link_no(llc->sap->laddr.lsap); | 426 | llc->link = llc_ui_next_link_no(llc->sap->laddr.lsap); |
434 | rc = llc_establish_connection(sk, dev->dev_addr, | 427 | rc = llc_establish_connection(sk, llc->dev->dev_addr, |
435 | addr->sllc_mac, addr->sllc_sap); | 428 | addr->sllc_mac, addr->sllc_sap); |
436 | if (rc) { | 429 | if (rc) { |
437 | dprintk("%s: llc_ui_send_conn failed :-(\n", __FUNCTION__); | 430 | dprintk("%s: llc_ui_send_conn failed :-(\n", __FUNCTION__); |
@@ -439,12 +432,30 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr, | |||
439 | sk->sk_state = TCP_CLOSE; | 432 | sk->sk_state = TCP_CLOSE; |
440 | goto out; | 433 | goto out; |
441 | } | 434 | } |
442 | rc = llc_ui_wait_for_conn(sk, sk->sk_rcvtimeo); | 435 | |
443 | if (rc) | 436 | if (sk->sk_state == TCP_SYN_SENT) { |
444 | dprintk("%s: llc_ui_wait_for_conn failed=%d\n", __FUNCTION__, rc); | 437 | const long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); |
438 | |||
439 | if (!timeo || !llc_ui_wait_for_conn(sk, timeo)) | ||
440 | goto out; | ||
441 | |||
442 | rc = sock_intr_errno(timeo); | ||
443 | if (signal_pending(current)) | ||
444 | goto out; | ||
445 | } | ||
446 | |||
447 | if (sk->sk_state == TCP_CLOSE) | ||
448 | goto sock_error; | ||
449 | |||
450 | sock->state = SS_CONNECTED; | ||
451 | rc = 0; | ||
445 | out: | 452 | out: |
446 | release_sock(sk); | 453 | release_sock(sk); |
447 | return rc; | 454 | return rc; |
455 | sock_error: | ||
456 | rc = sock_error(sk) ? : -ECONNABORTED; | ||
457 | sock->state = SS_UNCONNECTED; | ||
458 | goto out; | ||
448 | } | 459 | } |
449 | 460 | ||
450 | /** | 461 | /** |
@@ -461,10 +472,10 @@ static int llc_ui_listen(struct socket *sock, int backlog) | |||
461 | int rc = -EINVAL; | 472 | int rc = -EINVAL; |
462 | 473 | ||
463 | lock_sock(sk); | 474 | lock_sock(sk); |
464 | if (sock->state != SS_UNCONNECTED) | 475 | if (unlikely(sock->state != SS_UNCONNECTED)) |
465 | goto out; | 476 | goto out; |
466 | rc = -EOPNOTSUPP; | 477 | rc = -EOPNOTSUPP; |
467 | if (sk->sk_type != SOCK_STREAM) | 478 | if (unlikely(sk->sk_type != SOCK_STREAM)) |
468 | goto out; | 479 | goto out; |
469 | rc = -EAGAIN; | 480 | rc = -EAGAIN; |
470 | if (sock_flag(sk, SOCK_ZAPPED)) | 481 | if (sock_flag(sk, SOCK_ZAPPED)) |
@@ -483,20 +494,14 @@ out: | |||
483 | return rc; | 494 | return rc; |
484 | } | 495 | } |
485 | 496 | ||
486 | static int llc_ui_wait_for_disc(struct sock *sk, int timeout) | 497 | static int llc_ui_wait_for_disc(struct sock *sk, long timeout) |
487 | { | 498 | { |
488 | DECLARE_WAITQUEUE(wait, current); | 499 | DEFINE_WAIT(wait); |
489 | int rc; | 500 | int rc = 0; |
490 | 501 | ||
491 | add_wait_queue_exclusive(sk->sk_sleep, &wait); | 502 | while (1) { |
492 | for (;;) { | 503 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); |
493 | __set_current_state(TASK_INTERRUPTIBLE); | 504 | if (sk_wait_event(sk, &timeout, sk->sk_state == TCP_CLOSE)) |
494 | rc = 0; | ||
495 | if (sk->sk_state != TCP_CLOSE) { | ||
496 | release_sock(sk); | ||
497 | timeout = schedule_timeout(timeout); | ||
498 | lock_sock(sk); | ||
499 | } else | ||
500 | break; | 505 | break; |
501 | rc = -ERESTARTSYS; | 506 | rc = -ERESTARTSYS; |
502 | if (signal_pending(current)) | 507 | if (signal_pending(current)) |
@@ -504,65 +509,40 @@ static int llc_ui_wait_for_disc(struct sock *sk, int timeout) | |||
504 | rc = -EAGAIN; | 509 | rc = -EAGAIN; |
505 | if (!timeout) | 510 | if (!timeout) |
506 | break; | 511 | break; |
512 | rc = 0; | ||
507 | } | 513 | } |
508 | __set_current_state(TASK_RUNNING); | 514 | finish_wait(sk->sk_sleep, &wait); |
509 | remove_wait_queue(sk->sk_sleep, &wait); | ||
510 | return rc; | 515 | return rc; |
511 | } | 516 | } |
512 | 517 | ||
513 | static int llc_ui_wait_for_conn(struct sock *sk, int timeout) | 518 | static int llc_ui_wait_for_conn(struct sock *sk, long timeout) |
514 | { | 519 | { |
515 | DECLARE_WAITQUEUE(wait, current); | 520 | DEFINE_WAIT(wait); |
516 | int rc; | ||
517 | 521 | ||
518 | add_wait_queue_exclusive(sk->sk_sleep, &wait); | 522 | while (1) { |
519 | for (;;) { | 523 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); |
520 | __set_current_state(TASK_INTERRUPTIBLE); | 524 | if (sk_wait_event(sk, &timeout, sk->sk_state != TCP_SYN_SENT)) |
521 | rc = -EAGAIN; | ||
522 | if (sk->sk_state == TCP_CLOSE) | ||
523 | break; | ||
524 | rc = 0; | ||
525 | if (sk->sk_state != TCP_ESTABLISHED) { | ||
526 | release_sock(sk); | ||
527 | timeout = schedule_timeout(timeout); | ||
528 | lock_sock(sk); | ||
529 | } else | ||
530 | break; | 525 | break; |
531 | rc = -ERESTARTSYS; | 526 | if (signal_pending(current) || !timeout) |
532 | if (signal_pending(current)) | ||
533 | break; | ||
534 | rc = -EAGAIN; | ||
535 | if (!timeout) | ||
536 | break; | 527 | break; |
537 | } | 528 | } |
538 | __set_current_state(TASK_RUNNING); | 529 | finish_wait(sk->sk_sleep, &wait); |
539 | remove_wait_queue(sk->sk_sleep, &wait); | 530 | return timeout; |
540 | return rc; | ||
541 | } | 531 | } |
542 | 532 | ||
543 | static int llc_ui_wait_for_data(struct sock *sk, int timeout) | 533 | static int llc_ui_wait_for_busy_core(struct sock *sk, long timeout) |
544 | { | 534 | { |
545 | DECLARE_WAITQUEUE(wait, current); | 535 | DEFINE_WAIT(wait); |
546 | int rc = 0; | 536 | struct llc_sock *llc = llc_sk(sk); |
537 | int rc; | ||
547 | 538 | ||
548 | add_wait_queue_exclusive(sk->sk_sleep, &wait); | 539 | while (1) { |
549 | for (;;) { | 540 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); |
550 | __set_current_state(TASK_INTERRUPTIBLE); | ||
551 | if (sk->sk_shutdown & RCV_SHUTDOWN) | ||
552 | break; | ||
553 | /* | ||
554 | * Well, if we have backlog, try to process it now. | ||
555 | */ | ||
556 | if (sk->sk_backlog.tail) { | ||
557 | release_sock(sk); | ||
558 | lock_sock(sk); | ||
559 | } | ||
560 | rc = 0; | 541 | rc = 0; |
561 | if (skb_queue_empty(&sk->sk_receive_queue)) { | 542 | if (sk_wait_event(sk, &timeout, |
562 | release_sock(sk); | 543 | (sk->sk_shutdown & RCV_SHUTDOWN) || |
563 | timeout = schedule_timeout(timeout); | 544 | (!llc_data_accept_state(llc->state) && |
564 | lock_sock(sk); | 545 | !llc->p_flag))) |
565 | } else | ||
566 | break; | 546 | break; |
567 | rc = -ERESTARTSYS; | 547 | rc = -ERESTARTSYS; |
568 | if (signal_pending(current)) | 548 | if (signal_pending(current)) |
@@ -571,40 +551,35 @@ static int llc_ui_wait_for_data(struct sock *sk, int timeout) | |||
571 | if (!timeout) | 551 | if (!timeout) |
572 | break; | 552 | break; |
573 | } | 553 | } |
574 | __set_current_state(TASK_RUNNING); | 554 | finish_wait(sk->sk_sleep, &wait); |
575 | remove_wait_queue(sk->sk_sleep, &wait); | ||
576 | return rc; | 555 | return rc; |
577 | } | 556 | } |
578 | 557 | ||
579 | static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout) | 558 | static int llc_wait_data(struct sock *sk, long timeo) |
580 | { | 559 | { |
581 | DECLARE_WAITQUEUE(wait, current); | ||
582 | struct llc_sock *llc = llc_sk(sk); | ||
583 | int rc; | 560 | int rc; |
584 | 561 | ||
585 | add_wait_queue_exclusive(sk->sk_sleep, &wait); | 562 | while (1) { |
586 | for (;;) { | 563 | /* |
587 | dprintk("%s: looping...\n", __FUNCTION__); | 564 | * POSIX 1003.1g mandates this order. |
588 | __set_current_state(TASK_INTERRUPTIBLE); | 565 | */ |
589 | rc = -ENOTCONN; | 566 | if (sk->sk_err) { |
590 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 567 | rc = sock_error(sk); |
591 | break; | 568 | break; |
569 | } | ||
592 | rc = 0; | 570 | rc = 0; |
593 | if (llc_data_accept_state(llc->state) || llc->p_flag) { | 571 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
594 | release_sock(sk); | ||
595 | timeout = schedule_timeout(timeout); | ||
596 | lock_sock(sk); | ||
597 | } else | ||
598 | break; | 572 | break; |
599 | rc = -ERESTARTSYS; | 573 | rc = -EAGAIN; |
574 | if (!timeo) | ||
575 | break; | ||
576 | rc = sock_intr_errno(timeo); | ||
600 | if (signal_pending(current)) | 577 | if (signal_pending(current)) |
601 | break; | 578 | break; |
602 | rc = -EAGAIN; | 579 | rc = 0; |
603 | if (!timeout) | 580 | if (sk_wait_data(sk, &timeo)) |
604 | break; | 581 | break; |
605 | } | 582 | } |
606 | __set_current_state(TASK_RUNNING); | ||
607 | remove_wait_queue(sk->sk_sleep, &wait); | ||
608 | return rc; | 583 | return rc; |
609 | } | 584 | } |
610 | 585 | ||
@@ -627,15 +602,18 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags) | |||
627 | dprintk("%s: accepting on %02X\n", __FUNCTION__, | 602 | dprintk("%s: accepting on %02X\n", __FUNCTION__, |
628 | llc_sk(sk)->laddr.lsap); | 603 | llc_sk(sk)->laddr.lsap); |
629 | lock_sock(sk); | 604 | lock_sock(sk); |
630 | if (sk->sk_type != SOCK_STREAM) | 605 | if (unlikely(sk->sk_type != SOCK_STREAM)) |
631 | goto out; | 606 | goto out; |
632 | rc = -EINVAL; | 607 | rc = -EINVAL; |
633 | if (sock->state != SS_UNCONNECTED || sk->sk_state != TCP_LISTEN) | 608 | if (unlikely(sock->state != SS_UNCONNECTED || |
609 | sk->sk_state != TCP_LISTEN)) | ||
634 | goto out; | 610 | goto out; |
635 | /* wait for a connection to arrive. */ | 611 | /* wait for a connection to arrive. */ |
636 | rc = llc_ui_wait_for_data(sk, sk->sk_rcvtimeo); | 612 | if (skb_queue_empty(&sk->sk_receive_queue)) { |
637 | if (rc) | 613 | rc = llc_wait_data(sk, sk->sk_rcvtimeo); |
638 | goto out; | 614 | if (rc) |
615 | goto out; | ||
616 | } | ||
639 | dprintk("%s: got a new connection on %02X\n", __FUNCTION__, | 617 | dprintk("%s: got a new connection on %02X\n", __FUNCTION__, |
640 | llc_sk(sk)->laddr.lsap); | 618 | llc_sk(sk)->laddr.lsap); |
641 | skb = skb_dequeue(&sk->sk_receive_queue); | 619 | skb = skb_dequeue(&sk->sk_receive_queue); |
@@ -657,7 +635,6 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags) | |||
657 | /* put original socket back into a clean listen state. */ | 635 | /* put original socket back into a clean listen state. */ |
658 | sk->sk_state = TCP_LISTEN; | 636 | sk->sk_state = TCP_LISTEN; |
659 | sk->sk_ack_backlog--; | 637 | sk->sk_ack_backlog--; |
660 | skb->sk = NULL; | ||
661 | dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__, | 638 | dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__, |
662 | llc_sk(sk)->addr.sllc_sap, newllc->daddr.lsap); | 639 | llc_sk(sk)->addr.sllc_sap, newllc->daddr.lsap); |
663 | frees: | 640 | frees: |
@@ -671,56 +648,167 @@ out: | |||
671 | * llc_ui_recvmsg - copy received data to the socket user. | 648 | * llc_ui_recvmsg - copy received data to the socket user. |
672 | * @sock: Socket to copy data from. | 649 | * @sock: Socket to copy data from. |
673 | * @msg: Various user space related information. | 650 | * @msg: Various user space related information. |
674 | * @size: Size of user buffer. | 651 | * @len: Size of user buffer. |
675 | * @flags: User specified flags. | 652 | * @flags: User specified flags. |
676 | * | 653 | * |
677 | * Copy received data to the socket user. | 654 | * Copy received data to the socket user. |
678 | * Returns non-negative upon success, negative otherwise. | 655 | * Returns non-negative upon success, negative otherwise. |
679 | */ | 656 | */ |
680 | static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, | 657 | static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, |
681 | struct msghdr *msg, size_t size, int flags) | 658 | struct msghdr *msg, size_t len, int flags) |
682 | { | 659 | { |
683 | struct sock *sk = sock->sk; | ||
684 | struct sockaddr_llc *uaddr = (struct sockaddr_llc *)msg->msg_name; | 660 | struct sockaddr_llc *uaddr = (struct sockaddr_llc *)msg->msg_name; |
685 | struct sk_buff *skb; | 661 | const int nonblock = flags & MSG_DONTWAIT; |
662 | struct sk_buff *skb = NULL; | ||
663 | struct sock *sk = sock->sk; | ||
664 | struct llc_sock *llc = llc_sk(sk); | ||
686 | size_t copied = 0; | 665 | size_t copied = 0; |
687 | int rc = -ENOMEM, timeout; | 666 | u32 peek_seq = 0; |
688 | int noblock = flags & MSG_DONTWAIT; | 667 | u32 *seq; |
668 | unsigned long used; | ||
669 | int target; /* Read at least this many bytes */ | ||
670 | long timeo; | ||
689 | 671 | ||
690 | dprintk("%s: receiving in %02X from %02X\n", __FUNCTION__, | ||
691 | llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap); | ||
692 | lock_sock(sk); | 672 | lock_sock(sk); |
693 | timeout = sock_rcvtimeo(sk, noblock); | 673 | copied = -ENOTCONN; |
694 | rc = llc_ui_wait_for_data(sk, timeout); | 674 | if (sk->sk_state == TCP_LISTEN) |
695 | if (rc) { | ||
696 | dprintk("%s: llc_ui_wait_for_data failed recv " | ||
697 | "in %02X from %02X\n", __FUNCTION__, | ||
698 | llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap); | ||
699 | goto out; | 675 | goto out; |
700 | } | 676 | |
701 | skb = skb_dequeue(&sk->sk_receive_queue); | 677 | timeo = sock_rcvtimeo(sk, nonblock); |
702 | if (!skb) /* shutdown */ | 678 | |
703 | goto out; | 679 | seq = &llc->copied_seq; |
704 | copied = skb->len; | 680 | if (flags & MSG_PEEK) { |
705 | if (copied > size) | 681 | peek_seq = llc->copied_seq; |
706 | copied = size; | 682 | seq = &peek_seq; |
707 | rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); | 683 | } |
708 | if (rc) | 684 | |
709 | goto dgram_free; | 685 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, len); |
710 | if (skb->len > copied) { | 686 | copied = 0; |
711 | skb_pull(skb, copied); | 687 | |
712 | skb_queue_head(&sk->sk_receive_queue, skb); | 688 | do { |
713 | } | 689 | u32 offset; |
714 | if (uaddr) | 690 | |
715 | memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr)); | 691 | /* |
716 | msg->msg_namelen = sizeof(*uaddr); | 692 | * We need to check signals first, to get correct SIGURG |
717 | if (!skb->next) { | 693 | * handling. FIXME: Need to check this doesn't impact 1003.1g |
718 | dgram_free: | 694 | * and move it down to the bottom of the loop |
719 | kfree_skb(skb); | 695 | */ |
720 | } | 696 | if (signal_pending(current)) { |
697 | if (copied) | ||
698 | break; | ||
699 | copied = timeo ? sock_intr_errno(timeo) : -EAGAIN; | ||
700 | break; | ||
701 | } | ||
702 | |||
703 | /* Next get a buffer. */ | ||
704 | |||
705 | skb = skb_peek(&sk->sk_receive_queue); | ||
706 | if (skb) { | ||
707 | offset = *seq; | ||
708 | goto found_ok_skb; | ||
709 | } | ||
710 | /* Well, if we have backlog, try to process it now yet. */ | ||
711 | |||
712 | if (copied >= target && !sk->sk_backlog.tail) | ||
713 | break; | ||
714 | |||
715 | if (copied) { | ||
716 | if (sk->sk_err || | ||
717 | sk->sk_state == TCP_CLOSE || | ||
718 | (sk->sk_shutdown & RCV_SHUTDOWN) || | ||
719 | !timeo || | ||
720 | (flags & MSG_PEEK)) | ||
721 | break; | ||
722 | } else { | ||
723 | if (sock_flag(sk, SOCK_DONE)) | ||
724 | break; | ||
725 | |||
726 | if (sk->sk_err) { | ||
727 | copied = sock_error(sk); | ||
728 | break; | ||
729 | } | ||
730 | if (sk->sk_shutdown & RCV_SHUTDOWN) | ||
731 | break; | ||
732 | |||
733 | if (sk->sk_state == TCP_CLOSE) { | ||
734 | if (!sock_flag(sk, SOCK_DONE)) { | ||
735 | /* | ||
736 | * This occurs when user tries to read | ||
737 | * from never connected socket. | ||
738 | */ | ||
739 | copied = -ENOTCONN; | ||
740 | break; | ||
741 | } | ||
742 | break; | ||
743 | } | ||
744 | if (!timeo) { | ||
745 | copied = -EAGAIN; | ||
746 | break; | ||
747 | } | ||
748 | } | ||
749 | |||
750 | if (copied >= target) { /* Do not sleep, just process backlog. */ | ||
751 | release_sock(sk); | ||
752 | lock_sock(sk); | ||
753 | } else | ||
754 | sk_wait_data(sk, &timeo); | ||
755 | |||
756 | if ((flags & MSG_PEEK) && peek_seq != llc->copied_seq) { | ||
757 | if (net_ratelimit()) | ||
758 | printk(KERN_DEBUG "LLC(%s:%d): Application " | ||
759 | "bug, race in MSG_PEEK.\n", | ||
760 | current->comm, current->pid); | ||
761 | peek_seq = llc->copied_seq; | ||
762 | } | ||
763 | continue; | ||
764 | found_ok_skb: | ||
765 | /* Ok so how much can we use? */ | ||
766 | used = skb->len - offset; | ||
767 | if (len < used) | ||
768 | used = len; | ||
769 | |||
770 | if (!(flags & MSG_TRUNC)) { | ||
771 | int rc = skb_copy_datagram_iovec(skb, offset, | ||
772 | msg->msg_iov, used); | ||
773 | if (rc) { | ||
774 | /* Exception. Bailout! */ | ||
775 | if (!copied) | ||
776 | copied = -EFAULT; | ||
777 | break; | ||
778 | } | ||
779 | } | ||
780 | |||
781 | *seq += used; | ||
782 | copied += used; | ||
783 | len -= used; | ||
784 | |||
785 | if (used + offset < skb->len) | ||
786 | continue; | ||
787 | |||
788 | if (!(flags & MSG_PEEK)) { | ||
789 | sk_eat_skb(sk, skb); | ||
790 | *seq = 0; | ||
791 | } | ||
792 | } while (len > 0); | ||
793 | |||
794 | /* | ||
795 | * According to UNIX98, msg_name/msg_namelen are ignored | ||
796 | * on connected socket. -ANK | ||
797 | * But... af_llc still doesn't have separate sets of methods for | ||
798 | * SOCK_DGRAM and SOCK_STREAM :-( So we have to do this test, will | ||
799 | * eventually fix this tho :-) -acme | ||
800 | */ | ||
801 | if (sk->sk_type == SOCK_DGRAM) | ||
802 | goto copy_uaddr; | ||
721 | out: | 803 | out: |
722 | release_sock(sk); | 804 | release_sock(sk); |
723 | return rc ? : copied; | 805 | return copied; |
806 | copy_uaddr: | ||
807 | if (uaddr != NULL && skb != NULL) { | ||
808 | memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr)); | ||
809 | msg->msg_namelen = sizeof(*uaddr); | ||
810 | } | ||
811 | goto out; | ||
724 | } | 812 | } |
725 | 813 | ||
726 | /** | 814 | /** |
@@ -740,7 +828,6 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
740 | struct sockaddr_llc *addr = (struct sockaddr_llc *)msg->msg_name; | 828 | struct sockaddr_llc *addr = (struct sockaddr_llc *)msg->msg_name; |
741 | int flags = msg->msg_flags; | 829 | int flags = msg->msg_flags; |
742 | int noblock = flags & MSG_DONTWAIT; | 830 | int noblock = flags & MSG_DONTWAIT; |
743 | struct net_device *dev; | ||
744 | struct sk_buff *skb; | 831 | struct sk_buff *skb; |
745 | size_t size = 0; | 832 | size_t size = 0; |
746 | int rc = -EINVAL, copied = 0, hdrlen; | 833 | int rc = -EINVAL, copied = 0, hdrlen; |
@@ -763,19 +850,17 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
763 | if (rc) | 850 | if (rc) |
764 | goto release; | 851 | goto release; |
765 | } | 852 | } |
766 | dev = llc->dev; | 853 | hdrlen = llc->dev->hard_header_len + llc_ui_header_len(sk, addr); |
767 | hdrlen = dev->hard_header_len + llc_ui_header_len(sk, addr); | ||
768 | size = hdrlen + len; | 854 | size = hdrlen + len; |
769 | if (size > dev->mtu) | 855 | if (size > llc->dev->mtu) |
770 | size = dev->mtu; | 856 | size = llc->dev->mtu; |
771 | copied = size - hdrlen; | 857 | copied = size - hdrlen; |
772 | release_sock(sk); | 858 | release_sock(sk); |
773 | skb = sock_alloc_send_skb(sk, size, noblock, &rc); | 859 | skb = sock_alloc_send_skb(sk, size, noblock, &rc); |
774 | lock_sock(sk); | 860 | lock_sock(sk); |
775 | if (!skb) | 861 | if (!skb) |
776 | goto release; | 862 | goto release; |
777 | skb->sk = sk; | 863 | skb->dev = llc->dev; |
778 | skb->dev = dev; | ||
779 | skb->protocol = llc_proto_type(addr->sllc_arphrd); | 864 | skb->protocol = llc_proto_type(addr->sllc_arphrd); |
780 | skb_reserve(skb, hdrlen); | 865 | skb_reserve(skb, hdrlen); |
781 | rc = memcpy_fromiovec(skb_put(skb, copied), msg->msg_iov, copied); | 866 | rc = memcpy_fromiovec(skb_put(skb, copied), msg->msg_iov, copied); |
@@ -800,15 +885,13 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
800 | if (!(sk->sk_type == SOCK_STREAM && !addr->sllc_ua)) | 885 | if (!(sk->sk_type == SOCK_STREAM && !addr->sllc_ua)) |
801 | goto out; | 886 | goto out; |
802 | rc = llc_ui_send_data(sk, skb, noblock); | 887 | rc = llc_ui_send_data(sk, skb, noblock); |
803 | if (rc) | ||
804 | dprintk("%s: llc_ui_send_data failed: %d\n", __FUNCTION__, rc); | ||
805 | out: | 888 | out: |
806 | if (rc) | 889 | if (rc) { |
807 | kfree_skb(skb); | 890 | kfree_skb(skb); |
808 | release: | 891 | release: |
809 | if (rc) | ||
810 | dprintk("%s: failed sending from %02X to %02X: %d\n", | 892 | dprintk("%s: failed sending from %02X to %02X: %d\n", |
811 | __FUNCTION__, llc->laddr.lsap, llc->daddr.lsap, rc); | 893 | __FUNCTION__, llc->laddr.lsap, llc->daddr.lsap, rc); |
894 | } | ||
812 | release_sock(sk); | 895 | release_sock(sk); |
813 | return rc ? : copied; | 896 | return rc ? : copied; |
814 | } | 897 | } |
@@ -895,7 +978,7 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname, | |||
895 | int rc = -EINVAL, opt; | 978 | int rc = -EINVAL, opt; |
896 | 979 | ||
897 | lock_sock(sk); | 980 | lock_sock(sk); |
898 | if (level != SOL_LLC || optlen != sizeof(int)) | 981 | if (unlikely(level != SOL_LLC || optlen != sizeof(int))) |
899 | goto out; | 982 | goto out; |
900 | rc = get_user(opt, (int __user *)optval); | 983 | rc = get_user(opt, (int __user *)optval); |
901 | if (rc) | 984 | if (rc) |
@@ -915,22 +998,22 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname, | |||
915 | case LLC_OPT_ACK_TMR_EXP: | 998 | case LLC_OPT_ACK_TMR_EXP: |
916 | if (opt > LLC_OPT_MAX_ACK_TMR_EXP) | 999 | if (opt > LLC_OPT_MAX_ACK_TMR_EXP) |
917 | goto out; | 1000 | goto out; |
918 | llc->ack_timer.expire = opt; | 1001 | llc->ack_timer.expire = opt * HZ; |
919 | break; | 1002 | break; |
920 | case LLC_OPT_P_TMR_EXP: | 1003 | case LLC_OPT_P_TMR_EXP: |
921 | if (opt > LLC_OPT_MAX_P_TMR_EXP) | 1004 | if (opt > LLC_OPT_MAX_P_TMR_EXP) |
922 | goto out; | 1005 | goto out; |
923 | llc->pf_cycle_timer.expire = opt; | 1006 | llc->pf_cycle_timer.expire = opt * HZ; |
924 | break; | 1007 | break; |
925 | case LLC_OPT_REJ_TMR_EXP: | 1008 | case LLC_OPT_REJ_TMR_EXP: |
926 | if (opt > LLC_OPT_MAX_REJ_TMR_EXP) | 1009 | if (opt > LLC_OPT_MAX_REJ_TMR_EXP) |
927 | goto out; | 1010 | goto out; |
928 | llc->rej_sent_timer.expire = opt; | 1011 | llc->rej_sent_timer.expire = opt * HZ; |
929 | break; | 1012 | break; |
930 | case LLC_OPT_BUSY_TMR_EXP: | 1013 | case LLC_OPT_BUSY_TMR_EXP: |
931 | if (opt > LLC_OPT_MAX_BUSY_TMR_EXP) | 1014 | if (opt > LLC_OPT_MAX_BUSY_TMR_EXP) |
932 | goto out; | 1015 | goto out; |
933 | llc->busy_state_timer.expire = opt; | 1016 | llc->busy_state_timer.expire = opt * HZ; |
934 | break; | 1017 | break; |
935 | case LLC_OPT_TX_WIN: | 1018 | case LLC_OPT_TX_WIN: |
936 | if (opt > LLC_OPT_MAX_WIN) | 1019 | if (opt > LLC_OPT_MAX_WIN) |
@@ -970,7 +1053,7 @@ static int llc_ui_getsockopt(struct socket *sock, int level, int optname, | |||
970 | int val = 0, len = 0, rc = -EINVAL; | 1053 | int val = 0, len = 0, rc = -EINVAL; |
971 | 1054 | ||
972 | lock_sock(sk); | 1055 | lock_sock(sk); |
973 | if (level != SOL_LLC) | 1056 | if (unlikely(level != SOL_LLC)) |
974 | goto out; | 1057 | goto out; |
975 | rc = get_user(len, optlen); | 1058 | rc = get_user(len, optlen); |
976 | if (rc) | 1059 | if (rc) |
@@ -980,17 +1063,17 @@ static int llc_ui_getsockopt(struct socket *sock, int level, int optname, | |||
980 | goto out; | 1063 | goto out; |
981 | switch (optname) { | 1064 | switch (optname) { |
982 | case LLC_OPT_RETRY: | 1065 | case LLC_OPT_RETRY: |
983 | val = llc->n2; break; | 1066 | val = llc->n2; break; |
984 | case LLC_OPT_SIZE: | 1067 | case LLC_OPT_SIZE: |
985 | val = llc->n1; break; | 1068 | val = llc->n1; break; |
986 | case LLC_OPT_ACK_TMR_EXP: | 1069 | case LLC_OPT_ACK_TMR_EXP: |
987 | val = llc->ack_timer.expire; break; | 1070 | val = llc->ack_timer.expire / HZ; break; |
988 | case LLC_OPT_P_TMR_EXP: | 1071 | case LLC_OPT_P_TMR_EXP: |
989 | val = llc->pf_cycle_timer.expire; break; | 1072 | val = llc->pf_cycle_timer.expire / HZ; break; |
990 | case LLC_OPT_REJ_TMR_EXP: | 1073 | case LLC_OPT_REJ_TMR_EXP: |
991 | val = llc->rej_sent_timer.expire; break; | 1074 | val = llc->rej_sent_timer.expire / HZ; break; |
992 | case LLC_OPT_BUSY_TMR_EXP: | 1075 | case LLC_OPT_BUSY_TMR_EXP: |
993 | val = llc->busy_state_timer.expire; break; | 1076 | val = llc->busy_state_timer.expire / HZ; break; |
994 | case LLC_OPT_TX_WIN: | 1077 | case LLC_OPT_TX_WIN: |
995 | val = llc->k; break; | 1078 | val = llc->k; break; |
996 | case LLC_OPT_RX_WIN: | 1079 | case LLC_OPT_RX_WIN: |
@@ -1034,8 +1117,12 @@ static struct proto_ops llc_ui_ops = { | |||
1034 | .sendpage = sock_no_sendpage, | 1117 | .sendpage = sock_no_sendpage, |
1035 | }; | 1118 | }; |
1036 | 1119 | ||
1037 | extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb); | 1120 | static char llc_proc_err_msg[] __initdata = |
1038 | extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb); | 1121 | KERN_CRIT "LLC: Unable to register the proc_fs entries\n"; |
1122 | static char llc_sysctl_err_msg[] __initdata = | ||
1123 | KERN_CRIT "LLC: Unable to register the sysctl entries\n"; | ||
1124 | static char llc_sock_err_msg[] __initdata = | ||
1125 | KERN_CRIT "LLC: Unable to register the network family\n"; | ||
1039 | 1126 | ||
1040 | static int __init llc2_init(void) | 1127 | static int __init llc2_init(void) |
1041 | { | 1128 | { |
@@ -1048,13 +1135,28 @@ static int __init llc2_init(void) | |||
1048 | llc_station_init(); | 1135 | llc_station_init(); |
1049 | llc_ui_sap_last_autoport = LLC_SAP_DYN_START; | 1136 | llc_ui_sap_last_autoport = LLC_SAP_DYN_START; |
1050 | rc = llc_proc_init(); | 1137 | rc = llc_proc_init(); |
1051 | if (rc != 0) | 1138 | if (rc != 0) { |
1139 | printk(llc_proc_err_msg); | ||
1052 | goto out_unregister_llc_proto; | 1140 | goto out_unregister_llc_proto; |
1053 | sock_register(&llc_ui_family_ops); | 1141 | } |
1142 | rc = llc_sysctl_init(); | ||
1143 | if (rc) { | ||
1144 | printk(llc_sysctl_err_msg); | ||
1145 | goto out_proc; | ||
1146 | } | ||
1147 | rc = sock_register(&llc_ui_family_ops); | ||
1148 | if (rc) { | ||
1149 | printk(llc_sock_err_msg); | ||
1150 | goto out_sysctl; | ||
1151 | } | ||
1054 | llc_add_pack(LLC_DEST_SAP, llc_sap_handler); | 1152 | llc_add_pack(LLC_DEST_SAP, llc_sap_handler); |
1055 | llc_add_pack(LLC_DEST_CONN, llc_conn_handler); | 1153 | llc_add_pack(LLC_DEST_CONN, llc_conn_handler); |
1056 | out: | 1154 | out: |
1057 | return rc; | 1155 | return rc; |
1156 | out_sysctl: | ||
1157 | llc_sysctl_exit(); | ||
1158 | out_proc: | ||
1159 | llc_proc_exit(); | ||
1058 | out_unregister_llc_proto: | 1160 | out_unregister_llc_proto: |
1059 | proto_unregister(&llc_proto); | 1161 | proto_unregister(&llc_proto); |
1060 | goto out; | 1162 | goto out; |
@@ -1067,6 +1169,7 @@ static void __exit llc2_exit(void) | |||
1067 | llc_remove_pack(LLC_DEST_CONN); | 1169 | llc_remove_pack(LLC_DEST_CONN); |
1068 | sock_unregister(PF_LLC); | 1170 | sock_unregister(PF_LLC); |
1069 | llc_proc_exit(); | 1171 | llc_proc_exit(); |
1172 | llc_sysctl_exit(); | ||
1070 | proto_unregister(&llc_proto); | 1173 | proto_unregister(&llc_proto); |
1071 | } | 1174 | } |
1072 | 1175 | ||
diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c index b218be4c10ec..b0bcfb1f12dd 100644 --- a/net/llc/llc_c_ac.c +++ b/net/llc/llc_c_ac.c | |||
@@ -60,23 +60,10 @@ int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb) | |||
60 | 60 | ||
61 | int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb) | 61 | int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb) |
62 | { | 62 | { |
63 | int rc = -ENOTCONN; | 63 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
64 | u8 dsap; | ||
65 | struct llc_sap *sap; | ||
66 | |||
67 | llc_pdu_decode_dsap(skb, &dsap); | ||
68 | sap = llc_sap_find(dsap); | ||
69 | if (sap) { | ||
70 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | ||
71 | struct llc_sock *llc = llc_sk(sk); | ||
72 | 64 | ||
73 | llc_pdu_decode_sa(skb, llc->daddr.mac); | 65 | ev->ind_prim = LLC_CONN_PRIM; |
74 | llc_pdu_decode_da(skb, llc->laddr.mac); | 66 | return 0; |
75 | llc->dev = skb->dev; | ||
76 | ev->ind_prim = LLC_CONN_PRIM; | ||
77 | rc = 0; | ||
78 | } | ||
79 | return rc; | ||
80 | } | 67 | } |
81 | 68 | ||
82 | int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb) | 69 | int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb) |
@@ -120,10 +107,8 @@ int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb) | |||
120 | reason = LLC_DISC_REASON_RX_DISC_CMD_PDU; | 107 | reason = LLC_DISC_REASON_RX_DISC_CMD_PDU; |
121 | } else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR) | 108 | } else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR) |
122 | reason = LLC_DISC_REASON_ACK_TMR_EXP; | 109 | reason = LLC_DISC_REASON_ACK_TMR_EXP; |
123 | else { | 110 | else |
124 | reason = 0; | ||
125 | rc = -EINVAL; | 111 | rc = -EINVAL; |
126 | } | ||
127 | if (!rc) { | 112 | if (!rc) { |
128 | ev->reason = reason; | 113 | ev->reason = reason; |
129 | ev->ind_prim = LLC_DISC_PRIM; | 114 | ev->ind_prim = LLC_DISC_PRIM; |
@@ -160,9 +145,6 @@ int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb) | |||
160 | LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME) { | 145 | LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME) { |
161 | reason = LLC_RESET_REASON_REMOTE; | 146 | reason = LLC_RESET_REASON_REMOTE; |
162 | rc = 0; | 147 | rc = 0; |
163 | } else { | ||
164 | reason = 0; | ||
165 | rc = 1; | ||
166 | } | 148 | } |
167 | break; | 149 | break; |
168 | case LLC_CONN_EV_TYPE_ACK_TMR: | 150 | case LLC_CONN_EV_TYPE_ACK_TMR: |
@@ -172,8 +154,7 @@ int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb) | |||
172 | if (llc->retry_count > llc->n2) { | 154 | if (llc->retry_count > llc->n2) { |
173 | reason = LLC_RESET_REASON_LOCAL; | 155 | reason = LLC_RESET_REASON_LOCAL; |
174 | rc = 0; | 156 | rc = 0; |
175 | } else | 157 | } |
176 | rc = 1; | ||
177 | break; | 158 | break; |
178 | } | 159 | } |
179 | if (!rc) { | 160 | if (!rc) { |
@@ -217,18 +198,17 @@ int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk, | |||
217 | int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb) | 198 | int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb) |
218 | { | 199 | { |
219 | int rc = -ENOBUFS; | 200 | int rc = -ENOBUFS; |
220 | struct sk_buff *nskb = llc_alloc_frame(); | 201 | struct llc_sock *llc = llc_sk(sk); |
202 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
221 | 203 | ||
222 | if (nskb) { | 204 | if (nskb) { |
223 | struct llc_sock *llc = llc_sk(sk); | ||
224 | struct llc_sap *sap = llc->sap; | 205 | struct llc_sap *sap = llc->sap; |
225 | 206 | ||
226 | nskb->dev = llc->dev; | ||
227 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, | 207 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, |
228 | llc->daddr.lsap, LLC_PDU_CMD); | 208 | llc->daddr.lsap, LLC_PDU_CMD); |
229 | llc_pdu_init_as_disc_cmd(nskb, 1); | 209 | llc_pdu_init_as_disc_cmd(nskb, 1); |
230 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 210 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
231 | if (rc) | 211 | if (unlikely(rc)) |
232 | goto free; | 212 | goto free; |
233 | llc_conn_send_pdu(sk, nskb); | 213 | llc_conn_send_pdu(sk, nskb); |
234 | llc_conn_ac_set_p_flag_1(sk, skb); | 214 | llc_conn_ac_set_p_flag_1(sk, skb); |
@@ -243,20 +223,19 @@ free: | |||
243 | int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) | 223 | int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) |
244 | { | 224 | { |
245 | int rc = -ENOBUFS; | 225 | int rc = -ENOBUFS; |
246 | struct sk_buff *nskb = llc_alloc_frame(); | 226 | struct llc_sock *llc = llc_sk(sk); |
227 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
247 | 228 | ||
248 | if (nskb) { | 229 | if (nskb) { |
249 | struct llc_sock *llc = llc_sk(sk); | ||
250 | struct llc_sap *sap = llc->sap; | 230 | struct llc_sap *sap = llc->sap; |
251 | u8 f_bit; | 231 | u8 f_bit; |
252 | 232 | ||
253 | nskb->dev = llc->dev; | ||
254 | llc_pdu_decode_pf_bit(skb, &f_bit); | 233 | llc_pdu_decode_pf_bit(skb, &f_bit); |
255 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, | 234 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, |
256 | llc->daddr.lsap, LLC_PDU_RSP); | 235 | llc->daddr.lsap, LLC_PDU_RSP); |
257 | llc_pdu_init_as_dm_rsp(nskb, f_bit); | 236 | llc_pdu_init_as_dm_rsp(nskb, f_bit); |
258 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 237 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
259 | if (rc) | 238 | if (unlikely(rc)) |
260 | goto free; | 239 | goto free; |
261 | llc_conn_send_pdu(sk, nskb); | 240 | llc_conn_send_pdu(sk, nskb); |
262 | } | 241 | } |
@@ -270,19 +249,17 @@ free: | |||
270 | int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) | 249 | int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) |
271 | { | 250 | { |
272 | int rc = -ENOBUFS; | 251 | int rc = -ENOBUFS; |
273 | struct sk_buff *nskb = llc_alloc_frame(); | 252 | struct llc_sock *llc = llc_sk(sk); |
253 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
274 | 254 | ||
275 | if (nskb) { | 255 | if (nskb) { |
276 | struct llc_sock *llc = llc_sk(sk); | ||
277 | struct llc_sap *sap = llc->sap; | 256 | struct llc_sap *sap = llc->sap; |
278 | u8 f_bit = 1; | ||
279 | 257 | ||
280 | nskb->dev = llc->dev; | ||
281 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, | 258 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, |
282 | llc->daddr.lsap, LLC_PDU_RSP); | 259 | llc->daddr.lsap, LLC_PDU_RSP); |
283 | llc_pdu_init_as_dm_rsp(nskb, f_bit); | 260 | llc_pdu_init_as_dm_rsp(nskb, 1); |
284 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 261 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
285 | if (rc) | 262 | if (unlikely(rc)) |
286 | goto free; | 263 | goto free; |
287 | llc_conn_send_pdu(sk, nskb); | 264 | llc_conn_send_pdu(sk, nskb); |
288 | } | 265 | } |
@@ -306,17 +283,16 @@ int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb) | |||
306 | llc_pdu_decode_pf_bit(skb, &f_bit); | 283 | llc_pdu_decode_pf_bit(skb, &f_bit); |
307 | else | 284 | else |
308 | f_bit = 0; | 285 | f_bit = 0; |
309 | nskb = llc_alloc_frame(); | 286 | nskb = llc_alloc_frame(sk, llc->dev); |
310 | if (nskb) { | 287 | if (nskb) { |
311 | struct llc_sap *sap = llc->sap; | 288 | struct llc_sap *sap = llc->sap; |
312 | 289 | ||
313 | nskb->dev = llc->dev; | ||
314 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, | 290 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, |
315 | llc->daddr.lsap, LLC_PDU_RSP); | 291 | llc->daddr.lsap, LLC_PDU_RSP); |
316 | llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS, | 292 | llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS, |
317 | llc->vR, INCORRECT); | 293 | llc->vR, INCORRECT); |
318 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 294 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
319 | if (rc) | 295 | if (unlikely(rc)) |
320 | goto free; | 296 | goto free; |
321 | llc_conn_send_pdu(sk, nskb); | 297 | llc_conn_send_pdu(sk, nskb); |
322 | } | 298 | } |
@@ -330,21 +306,19 @@ free: | |||
330 | int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb) | 306 | int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb) |
331 | { | 307 | { |
332 | int rc = -ENOBUFS; | 308 | int rc = -ENOBUFS; |
333 | struct sk_buff *nskb = llc_alloc_frame(); | 309 | struct llc_sock *llc = llc_sk(sk); |
310 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
334 | 311 | ||
335 | if (nskb) { | 312 | if (nskb) { |
336 | u8 f_bit = 0; | ||
337 | struct llc_sock *llc = llc_sk(sk); | ||
338 | struct llc_sap *sap = llc->sap; | 313 | struct llc_sap *sap = llc->sap; |
339 | struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)&llc->rx_pdu_hdr; | 314 | struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)&llc->rx_pdu_hdr; |
340 | 315 | ||
341 | nskb->dev = llc->dev; | ||
342 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, | 316 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, |
343 | llc->daddr.lsap, LLC_PDU_RSP); | 317 | llc->daddr.lsap, LLC_PDU_RSP); |
344 | llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS, | 318 | llc_pdu_init_as_frmr_rsp(nskb, pdu, 0, llc->vS, |
345 | llc->vR, INCORRECT); | 319 | llc->vR, INCORRECT); |
346 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 320 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
347 | if (rc) | 321 | if (unlikely(rc)) |
348 | goto free; | 322 | goto free; |
349 | llc_conn_send_pdu(sk, nskb); | 323 | llc_conn_send_pdu(sk, nskb); |
350 | } | 324 | } |
@@ -360,21 +334,20 @@ int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) | |||
360 | u8 f_bit; | 334 | u8 f_bit; |
361 | int rc = -ENOBUFS; | 335 | int rc = -ENOBUFS; |
362 | struct sk_buff *nskb; | 336 | struct sk_buff *nskb; |
337 | struct llc_sock *llc = llc_sk(sk); | ||
363 | 338 | ||
364 | llc_pdu_decode_pf_bit(skb, &f_bit); | 339 | llc_pdu_decode_pf_bit(skb, &f_bit); |
365 | nskb = llc_alloc_frame(); | 340 | nskb = llc_alloc_frame(sk, llc->dev); |
366 | if (nskb) { | 341 | if (nskb) { |
367 | struct llc_sock *llc = llc_sk(sk); | ||
368 | struct llc_sap *sap = llc->sap; | 342 | struct llc_sap *sap = llc->sap; |
369 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 343 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
370 | 344 | ||
371 | nskb->dev = llc->dev; | ||
372 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, | 345 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, |
373 | llc->daddr.lsap, LLC_PDU_RSP); | 346 | llc->daddr.lsap, LLC_PDU_RSP); |
374 | llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS, | 347 | llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS, |
375 | llc->vR, INCORRECT); | 348 | llc->vR, INCORRECT); |
376 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 349 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
377 | if (rc) | 350 | if (unlikely(rc)) |
378 | goto free; | 351 | goto free; |
379 | llc_conn_send_pdu(sk, nskb); | 352 | llc_conn_send_pdu(sk, nskb); |
380 | } | 353 | } |
@@ -395,7 +368,7 @@ int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) | |||
395 | llc->daddr.lsap, LLC_PDU_CMD); | 368 | llc->daddr.lsap, LLC_PDU_CMD); |
396 | llc_pdu_init_as_i_cmd(skb, 1, llc->vS, llc->vR); | 369 | llc_pdu_init_as_i_cmd(skb, 1, llc->vS, llc->vR); |
397 | rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); | 370 | rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); |
398 | if (!rc) { | 371 | if (likely(!rc)) { |
399 | llc_conn_send_pdu(sk, skb); | 372 | llc_conn_send_pdu(sk, skb); |
400 | llc_conn_ac_inc_vs_by_1(sk, skb); | 373 | llc_conn_ac_inc_vs_by_1(sk, skb); |
401 | } | 374 | } |
@@ -412,7 +385,7 @@ static int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb) | |||
412 | llc->daddr.lsap, LLC_PDU_CMD); | 385 | llc->daddr.lsap, LLC_PDU_CMD); |
413 | llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR); | 386 | llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR); |
414 | rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); | 387 | rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); |
415 | if (!rc) { | 388 | if (likely(!rc)) { |
416 | llc_conn_send_pdu(sk, skb); | 389 | llc_conn_send_pdu(sk, skb); |
417 | llc_conn_ac_inc_vs_by_1(sk, skb); | 390 | llc_conn_ac_inc_vs_by_1(sk, skb); |
418 | } | 391 | } |
@@ -429,7 +402,7 @@ int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) | |||
429 | llc->daddr.lsap, LLC_PDU_CMD); | 402 | llc->daddr.lsap, LLC_PDU_CMD); |
430 | llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR); | 403 | llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR); |
431 | rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); | 404 | rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); |
432 | if (!rc) { | 405 | if (likely(!rc)) { |
433 | llc_conn_send_pdu(sk, skb); | 406 | llc_conn_send_pdu(sk, skb); |
434 | llc_conn_ac_inc_vs_by_1(sk, skb); | 407 | llc_conn_ac_inc_vs_by_1(sk, skb); |
435 | } | 408 | } |
@@ -451,18 +424,17 @@ int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk, | |||
451 | u8 nr; | 424 | u8 nr; |
452 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 425 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
453 | int rc = -ENOBUFS; | 426 | int rc = -ENOBUFS; |
454 | struct sk_buff *nskb = llc_alloc_frame(); | 427 | struct llc_sock *llc = llc_sk(sk); |
428 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
455 | 429 | ||
456 | if (nskb) { | 430 | if (nskb) { |
457 | struct llc_sock *llc = llc_sk(sk); | ||
458 | struct llc_sap *sap = llc->sap; | 431 | struct llc_sap *sap = llc->sap; |
459 | 432 | ||
460 | nskb->dev = llc->dev; | ||
461 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, | 433 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, |
462 | llc->daddr.lsap, LLC_PDU_RSP); | 434 | llc->daddr.lsap, LLC_PDU_RSP); |
463 | llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR); | 435 | llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR); |
464 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 436 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
465 | if (!rc) | 437 | if (likely(!rc)) |
466 | llc_conn_send_pdu(sk, nskb); | 438 | llc_conn_send_pdu(sk, nskb); |
467 | else | 439 | else |
468 | kfree_skb(skb); | 440 | kfree_skb(skb); |
@@ -487,18 +459,17 @@ int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) | |||
487 | int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) | 459 | int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) |
488 | { | 460 | { |
489 | int rc = -ENOBUFS; | 461 | int rc = -ENOBUFS; |
490 | struct sk_buff *nskb = llc_alloc_frame(); | 462 | struct llc_sock *llc = llc_sk(sk); |
463 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
491 | 464 | ||
492 | if (nskb) { | 465 | if (nskb) { |
493 | struct llc_sock *llc = llc_sk(sk); | ||
494 | struct llc_sap *sap = llc->sap; | 466 | struct llc_sap *sap = llc->sap; |
495 | 467 | ||
496 | nskb->dev = llc->dev; | ||
497 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, | 468 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, |
498 | llc->daddr.lsap, LLC_PDU_CMD); | 469 | llc->daddr.lsap, LLC_PDU_CMD); |
499 | llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR); | 470 | llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR); |
500 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 471 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
501 | if (rc) | 472 | if (unlikely(rc)) |
502 | goto free; | 473 | goto free; |
503 | llc_conn_send_pdu(sk, nskb); | 474 | llc_conn_send_pdu(sk, nskb); |
504 | } | 475 | } |
@@ -512,19 +483,17 @@ free: | |||
512 | int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) | 483 | int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) |
513 | { | 484 | { |
514 | int rc = -ENOBUFS; | 485 | int rc = -ENOBUFS; |
515 | struct sk_buff *nskb = llc_alloc_frame(); | 486 | struct llc_sock *llc = llc_sk(sk); |
487 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
516 | 488 | ||
517 | if (nskb) { | 489 | if (nskb) { |
518 | u8 f_bit = 1; | ||
519 | struct llc_sock *llc = llc_sk(sk); | ||
520 | struct llc_sap *sap = llc->sap; | 490 | struct llc_sap *sap = llc->sap; |
521 | 491 | ||
522 | nskb->dev = llc->dev; | ||
523 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, | 492 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, |
524 | llc->daddr.lsap, LLC_PDU_RSP); | 493 | llc->daddr.lsap, LLC_PDU_RSP); |
525 | llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR); | 494 | llc_pdu_init_as_rej_rsp(nskb, 1, llc->vR); |
526 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 495 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
527 | if (rc) | 496 | if (unlikely(rc)) |
528 | goto free; | 497 | goto free; |
529 | llc_conn_send_pdu(sk, nskb); | 498 | llc_conn_send_pdu(sk, nskb); |
530 | } | 499 | } |
@@ -538,19 +507,17 @@ free: | |||
538 | int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) | 507 | int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) |
539 | { | 508 | { |
540 | int rc = -ENOBUFS; | 509 | int rc = -ENOBUFS; |
541 | struct sk_buff *nskb = llc_alloc_frame(); | 510 | struct llc_sock *llc = llc_sk(sk); |
511 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
542 | 512 | ||
543 | if (nskb) { | 513 | if (nskb) { |
544 | struct llc_sock *llc = llc_sk(sk); | ||
545 | struct llc_sap *sap = llc->sap; | 514 | struct llc_sap *sap = llc->sap; |
546 | u8 f_bit = 0; | ||
547 | 515 | ||
548 | nskb->dev = llc->dev; | ||
549 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, | 516 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, |
550 | llc->daddr.lsap, LLC_PDU_RSP); | 517 | llc->daddr.lsap, LLC_PDU_RSP); |
551 | llc_pdu_init_as_rej_rsp(nskb, f_bit, llc->vR); | 518 | llc_pdu_init_as_rej_rsp(nskb, 0, llc->vR); |
552 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 519 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
553 | if (rc) | 520 | if (unlikely(rc)) |
554 | goto free; | 521 | goto free; |
555 | llc_conn_send_pdu(sk, nskb); | 522 | llc_conn_send_pdu(sk, nskb); |
556 | } | 523 | } |
@@ -564,18 +531,17 @@ free: | |||
564 | int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) | 531 | int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) |
565 | { | 532 | { |
566 | int rc = -ENOBUFS; | 533 | int rc = -ENOBUFS; |
567 | struct sk_buff *nskb = llc_alloc_frame(); | 534 | struct llc_sock *llc = llc_sk(sk); |
535 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
568 | 536 | ||
569 | if (nskb) { | 537 | if (nskb) { |
570 | struct llc_sock *llc = llc_sk(sk); | ||
571 | struct llc_sap *sap = llc->sap; | 538 | struct llc_sap *sap = llc->sap; |
572 | 539 | ||
573 | nskb->dev = llc->dev; | ||
574 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, | 540 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, |
575 | llc->daddr.lsap, LLC_PDU_CMD); | 541 | llc->daddr.lsap, LLC_PDU_CMD); |
576 | llc_pdu_init_as_rnr_cmd(nskb, 1, llc->vR); | 542 | llc_pdu_init_as_rnr_cmd(nskb, 1, llc->vR); |
577 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 543 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
578 | if (rc) | 544 | if (unlikely(rc)) |
579 | goto free; | 545 | goto free; |
580 | llc_conn_send_pdu(sk, nskb); | 546 | llc_conn_send_pdu(sk, nskb); |
581 | } | 547 | } |
@@ -589,19 +555,17 @@ free: | |||
589 | int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) | 555 | int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) |
590 | { | 556 | { |
591 | int rc = -ENOBUFS; | 557 | int rc = -ENOBUFS; |
592 | struct sk_buff *nskb = llc_alloc_frame(); | 558 | struct llc_sock *llc = llc_sk(sk); |
559 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
593 | 560 | ||
594 | if (nskb) { | 561 | if (nskb) { |
595 | struct llc_sock *llc = llc_sk(sk); | ||
596 | struct llc_sap *sap = llc->sap; | 562 | struct llc_sap *sap = llc->sap; |
597 | u8 f_bit = 1; | ||
598 | 563 | ||
599 | nskb->dev = llc->dev; | ||
600 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, | 564 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, |
601 | llc->daddr.lsap, LLC_PDU_RSP); | 565 | llc->daddr.lsap, LLC_PDU_RSP); |
602 | llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR); | 566 | llc_pdu_init_as_rnr_rsp(nskb, 1, llc->vR); |
603 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 567 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
604 | if (rc) | 568 | if (unlikely(rc)) |
605 | goto free; | 569 | goto free; |
606 | llc_conn_send_pdu(sk, nskb); | 570 | llc_conn_send_pdu(sk, nskb); |
607 | } | 571 | } |
@@ -615,19 +579,17 @@ free: | |||
615 | int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) | 579 | int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) |
616 | { | 580 | { |
617 | int rc = -ENOBUFS; | 581 | int rc = -ENOBUFS; |
618 | struct sk_buff *nskb = llc_alloc_frame(); | 582 | struct llc_sock *llc = llc_sk(sk); |
583 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
619 | 584 | ||
620 | if (nskb) { | 585 | if (nskb) { |
621 | u8 f_bit = 0; | ||
622 | struct llc_sock *llc = llc_sk(sk); | ||
623 | struct llc_sap *sap = llc->sap; | 586 | struct llc_sap *sap = llc->sap; |
624 | 587 | ||
625 | nskb->dev = llc->dev; | ||
626 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, | 588 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, |
627 | llc->daddr.lsap, LLC_PDU_RSP); | 589 | llc->daddr.lsap, LLC_PDU_RSP); |
628 | llc_pdu_init_as_rnr_rsp(nskb, f_bit, llc->vR); | 590 | llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR); |
629 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 591 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
630 | if (rc) | 592 | if (unlikely(rc)) |
631 | goto free; | 593 | goto free; |
632 | llc_conn_send_pdu(sk, nskb); | 594 | llc_conn_send_pdu(sk, nskb); |
633 | } | 595 | } |
@@ -645,7 +607,7 @@ int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb) | |||
645 | if (!llc->remote_busy_flag) { | 607 | if (!llc->remote_busy_flag) { |
646 | llc->remote_busy_flag = 1; | 608 | llc->remote_busy_flag = 1; |
647 | mod_timer(&llc->busy_state_timer.timer, | 609 | mod_timer(&llc->busy_state_timer.timer, |
648 | jiffies + llc->busy_state_timer.expire * HZ); | 610 | jiffies + llc->busy_state_timer.expire); |
649 | } | 611 | } |
650 | return 0; | 612 | return 0; |
651 | } | 613 | } |
@@ -653,18 +615,17 @@ int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb) | |||
653 | int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) | 615 | int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) |
654 | { | 616 | { |
655 | int rc = -ENOBUFS; | 617 | int rc = -ENOBUFS; |
656 | struct sk_buff *nskb = llc_alloc_frame(); | 618 | struct llc_sock *llc = llc_sk(sk); |
619 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
657 | 620 | ||
658 | if (nskb) { | 621 | if (nskb) { |
659 | struct llc_sock *llc = llc_sk(sk); | ||
660 | struct llc_sap *sap = llc->sap; | 622 | struct llc_sap *sap = llc->sap; |
661 | 623 | ||
662 | nskb->dev = llc->dev; | ||
663 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, | 624 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, |
664 | llc->daddr.lsap, LLC_PDU_RSP); | 625 | llc->daddr.lsap, LLC_PDU_RSP); |
665 | llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR); | 626 | llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR); |
666 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 627 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
667 | if (rc) | 628 | if (unlikely(rc)) |
668 | goto free; | 629 | goto free; |
669 | llc_conn_send_pdu(sk, nskb); | 630 | llc_conn_send_pdu(sk, nskb); |
670 | } | 631 | } |
@@ -678,18 +639,17 @@ free: | |||
678 | int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) | 639 | int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) |
679 | { | 640 | { |
680 | int rc = -ENOBUFS; | 641 | int rc = -ENOBUFS; |
681 | struct sk_buff *nskb = llc_alloc_frame(); | 642 | struct llc_sock *llc = llc_sk(sk); |
643 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
682 | 644 | ||
683 | if (nskb) { | 645 | if (nskb) { |
684 | struct llc_sock *llc = llc_sk(sk); | ||
685 | struct llc_sap *sap = llc->sap; | 646 | struct llc_sap *sap = llc->sap; |
686 | 647 | ||
687 | nskb->dev = llc->dev; | ||
688 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, | 648 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, |
689 | llc->daddr.lsap, LLC_PDU_CMD); | 649 | llc->daddr.lsap, LLC_PDU_CMD); |
690 | llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR); | 650 | llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR); |
691 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 651 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
692 | if (rc) | 652 | if (unlikely(rc)) |
693 | goto free; | 653 | goto free; |
694 | llc_conn_send_pdu(sk, nskb); | 654 | llc_conn_send_pdu(sk, nskb); |
695 | } | 655 | } |
@@ -703,19 +663,18 @@ free: | |||
703 | int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) | 663 | int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) |
704 | { | 664 | { |
705 | int rc = -ENOBUFS; | 665 | int rc = -ENOBUFS; |
706 | struct sk_buff *nskb = llc_alloc_frame(); | 666 | struct llc_sock *llc = llc_sk(sk); |
667 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
707 | 668 | ||
708 | if (nskb) { | 669 | if (nskb) { |
709 | struct llc_sock *llc = llc_sk(sk); | ||
710 | struct llc_sap *sap = llc->sap; | 670 | struct llc_sap *sap = llc->sap; |
711 | u8 f_bit = 1; | 671 | u8 f_bit = 1; |
712 | 672 | ||
713 | nskb->dev = llc->dev; | ||
714 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, | 673 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, |
715 | llc->daddr.lsap, LLC_PDU_RSP); | 674 | llc->daddr.lsap, LLC_PDU_RSP); |
716 | llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR); | 675 | llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR); |
717 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 676 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
718 | if (rc) | 677 | if (unlikely(rc)) |
719 | goto free; | 678 | goto free; |
720 | llc_conn_send_pdu(sk, nskb); | 679 | llc_conn_send_pdu(sk, nskb); |
721 | } | 680 | } |
@@ -729,19 +688,17 @@ free: | |||
729 | int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) | 688 | int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) |
730 | { | 689 | { |
731 | int rc = -ENOBUFS; | 690 | int rc = -ENOBUFS; |
732 | struct sk_buff *nskb = llc_alloc_frame(); | 691 | struct llc_sock *llc = llc_sk(sk); |
692 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
733 | 693 | ||
734 | if (nskb) { | 694 | if (nskb) { |
735 | struct llc_sock *llc = llc_sk(sk); | ||
736 | struct llc_sap *sap = llc->sap; | 695 | struct llc_sap *sap = llc->sap; |
737 | u8 f_bit = 1; | ||
738 | 696 | ||
739 | nskb->dev = llc->dev; | ||
740 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, | 697 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, |
741 | llc->daddr.lsap, LLC_PDU_RSP); | 698 | llc->daddr.lsap, LLC_PDU_RSP); |
742 | llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR); | 699 | llc_pdu_init_as_rr_rsp(nskb, 1, llc->vR); |
743 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 700 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
744 | if (rc) | 701 | if (unlikely(rc)) |
745 | goto free; | 702 | goto free; |
746 | llc_conn_send_pdu(sk, nskb); | 703 | llc_conn_send_pdu(sk, nskb); |
747 | } | 704 | } |
@@ -755,18 +712,17 @@ free: | |||
755 | int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) | 712 | int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) |
756 | { | 713 | { |
757 | int rc = -ENOBUFS; | 714 | int rc = -ENOBUFS; |
758 | struct sk_buff *nskb = llc_alloc_frame(); | 715 | struct llc_sock *llc = llc_sk(sk); |
716 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
759 | 717 | ||
760 | if (nskb) { | 718 | if (nskb) { |
761 | struct llc_sock *llc = llc_sk(sk); | ||
762 | struct llc_sap *sap = llc->sap; | 719 | struct llc_sap *sap = llc->sap; |
763 | 720 | ||
764 | nskb->dev = llc->dev; | ||
765 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, | 721 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, |
766 | llc->daddr.lsap, LLC_PDU_RSP); | 722 | llc->daddr.lsap, LLC_PDU_RSP); |
767 | llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR); | 723 | llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR); |
768 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 724 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
769 | if (rc) | 725 | if (unlikely(rc)) |
770 | goto free; | 726 | goto free; |
771 | llc_conn_send_pdu(sk, nskb); | 727 | llc_conn_send_pdu(sk, nskb); |
772 | } | 728 | } |
@@ -780,18 +736,17 @@ free: | |||
780 | int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) | 736 | int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) |
781 | { | 737 | { |
782 | int rc = -ENOBUFS; | 738 | int rc = -ENOBUFS; |
783 | struct sk_buff *nskb = llc_alloc_frame(); | 739 | struct llc_sock *llc = llc_sk(sk); |
740 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
784 | 741 | ||
785 | if (nskb) { | 742 | if (nskb) { |
786 | struct llc_sock *llc = llc_sk(sk); | ||
787 | struct llc_sap *sap = llc->sap; | 743 | struct llc_sap *sap = llc->sap; |
788 | 744 | ||
789 | nskb->dev = llc->dev; | ||
790 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, | 745 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, |
791 | llc->daddr.lsap, LLC_PDU_RSP); | 746 | llc->daddr.lsap, LLC_PDU_RSP); |
792 | llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR); | 747 | llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR); |
793 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 748 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
794 | if (rc) | 749 | if (unlikely(rc)) |
795 | goto free; | 750 | goto free; |
796 | llc_conn_send_pdu(sk, nskb); | 751 | llc_conn_send_pdu(sk, nskb); |
797 | } | 752 | } |
@@ -815,8 +770,8 @@ void llc_conn_set_p_flag(struct sock *sk, u8 value) | |||
815 | int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb) | 770 | int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb) |
816 | { | 771 | { |
817 | int rc = -ENOBUFS; | 772 | int rc = -ENOBUFS; |
818 | struct sk_buff *nskb = llc_alloc_frame(); | ||
819 | struct llc_sock *llc = llc_sk(sk); | 773 | struct llc_sock *llc = llc_sk(sk); |
774 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
820 | 775 | ||
821 | if (nskb) { | 776 | if (nskb) { |
822 | struct llc_sap *sap = llc->sap; | 777 | struct llc_sap *sap = llc->sap; |
@@ -824,12 +779,11 @@ int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb) | |||
824 | 779 | ||
825 | if (llc->dev->flags & IFF_LOOPBACK) | 780 | if (llc->dev->flags & IFF_LOOPBACK) |
826 | dmac = llc->dev->dev_addr; | 781 | dmac = llc->dev->dev_addr; |
827 | nskb->dev = llc->dev; | ||
828 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, | 782 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, |
829 | llc->daddr.lsap, LLC_PDU_CMD); | 783 | llc->daddr.lsap, LLC_PDU_CMD); |
830 | llc_pdu_init_as_sabme_cmd(nskb, 1); | 784 | llc_pdu_init_as_sabme_cmd(nskb, 1); |
831 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, dmac); | 785 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, dmac); |
832 | if (rc) | 786 | if (unlikely(rc)) |
833 | goto free; | 787 | goto free; |
834 | llc_conn_send_pdu(sk, nskb); | 788 | llc_conn_send_pdu(sk, nskb); |
835 | llc_conn_set_p_flag(sk, 1); | 789 | llc_conn_set_p_flag(sk, 1); |
@@ -845,11 +799,11 @@ int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) | |||
845 | { | 799 | { |
846 | u8 f_bit; | 800 | u8 f_bit; |
847 | int rc = -ENOBUFS; | 801 | int rc = -ENOBUFS; |
848 | struct sk_buff *nskb = llc_alloc_frame(); | 802 | struct llc_sock *llc = llc_sk(sk); |
803 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
849 | 804 | ||
850 | llc_pdu_decode_pf_bit(skb, &f_bit); | 805 | llc_pdu_decode_pf_bit(skb, &f_bit); |
851 | if (nskb) { | 806 | if (nskb) { |
852 | struct llc_sock *llc = llc_sk(sk); | ||
853 | struct llc_sap *sap = llc->sap; | 807 | struct llc_sap *sap = llc->sap; |
854 | 808 | ||
855 | nskb->dev = llc->dev; | 809 | nskb->dev = llc->dev; |
@@ -857,7 +811,7 @@ int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) | |||
857 | llc->daddr.lsap, LLC_PDU_RSP); | 811 | llc->daddr.lsap, LLC_PDU_RSP); |
858 | llc_pdu_init_as_ua_rsp(nskb, f_bit); | 812 | llc_pdu_init_as_ua_rsp(nskb, f_bit); |
859 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 813 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
860 | if (rc) | 814 | if (unlikely(rc)) |
861 | goto free; | 815 | goto free; |
862 | llc_conn_send_pdu(sk, nskb); | 816 | llc_conn_send_pdu(sk, nskb); |
863 | } | 817 | } |
@@ -886,7 +840,7 @@ int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb) | |||
886 | 840 | ||
887 | llc_conn_set_p_flag(sk, 1); | 841 | llc_conn_set_p_flag(sk, 1); |
888 | mod_timer(&llc->pf_cycle_timer.timer, | 842 | mod_timer(&llc->pf_cycle_timer.timer, |
889 | jiffies + llc->pf_cycle_timer.expire * HZ); | 843 | jiffies + llc->pf_cycle_timer.expire); |
890 | return 0; | 844 | return 0; |
891 | } | 845 | } |
892 | 846 | ||
@@ -957,7 +911,7 @@ static int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk, | |||
957 | llc->daddr.lsap, LLC_PDU_RSP); | 911 | llc->daddr.lsap, LLC_PDU_RSP); |
958 | llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR); | 912 | llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR); |
959 | rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); | 913 | rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); |
960 | if (!rc) { | 914 | if (likely(!rc)) { |
961 | llc_conn_send_pdu(sk, skb); | 915 | llc_conn_send_pdu(sk, skb); |
962 | llc_conn_ac_inc_vs_by_1(sk, skb); | 916 | llc_conn_ac_inc_vs_by_1(sk, skb); |
963 | } | 917 | } |
@@ -1001,18 +955,17 @@ static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk, | |||
1001 | struct sk_buff *skb) | 955 | struct sk_buff *skb) |
1002 | { | 956 | { |
1003 | int rc = -ENOBUFS; | 957 | int rc = -ENOBUFS; |
1004 | struct sk_buff *nskb = llc_alloc_frame(); | 958 | struct llc_sock *llc = llc_sk(sk); |
959 | struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); | ||
1005 | 960 | ||
1006 | if (nskb) { | 961 | if (nskb) { |
1007 | struct llc_sock *llc = llc_sk(sk); | ||
1008 | struct llc_sap *sap = llc->sap; | 962 | struct llc_sap *sap = llc->sap; |
1009 | 963 | ||
1010 | nskb->dev = llc->dev; | ||
1011 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, | 964 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap, |
1012 | llc->daddr.lsap, LLC_PDU_RSP); | 965 | llc->daddr.lsap, LLC_PDU_RSP); |
1013 | llc_pdu_init_as_rr_rsp(nskb, llc->ack_pf, llc->vR); | 966 | llc_pdu_init_as_rr_rsp(nskb, llc->ack_pf, llc->vR); |
1014 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); | 967 | rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac); |
1015 | if (rc) | 968 | if (unlikely(rc)) |
1016 | goto free; | 969 | goto free; |
1017 | llc_conn_send_pdu(sk, nskb); | 970 | llc_conn_send_pdu(sk, nskb); |
1018 | } | 971 | } |
@@ -1165,7 +1118,7 @@ int llc_conn_ac_start_ack_timer(struct sock *sk, struct sk_buff *skb) | |||
1165 | { | 1118 | { |
1166 | struct llc_sock *llc = llc_sk(sk); | 1119 | struct llc_sock *llc = llc_sk(sk); |
1167 | 1120 | ||
1168 | mod_timer(&llc->ack_timer.timer, jiffies + llc->ack_timer.expire * HZ); | 1121 | mod_timer(&llc->ack_timer.timer, jiffies + llc->ack_timer.expire); |
1169 | return 0; | 1122 | return 0; |
1170 | } | 1123 | } |
1171 | 1124 | ||
@@ -1174,7 +1127,7 @@ int llc_conn_ac_start_rej_timer(struct sock *sk, struct sk_buff *skb) | |||
1174 | struct llc_sock *llc = llc_sk(sk); | 1127 | struct llc_sock *llc = llc_sk(sk); |
1175 | 1128 | ||
1176 | mod_timer(&llc->rej_sent_timer.timer, | 1129 | mod_timer(&llc->rej_sent_timer.timer, |
1177 | jiffies + llc->rej_sent_timer.expire * HZ); | 1130 | jiffies + llc->rej_sent_timer.expire); |
1178 | return 0; | 1131 | return 0; |
1179 | } | 1132 | } |
1180 | 1133 | ||
@@ -1185,7 +1138,7 @@ int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk, | |||
1185 | 1138 | ||
1186 | if (!timer_pending(&llc->ack_timer.timer)) | 1139 | if (!timer_pending(&llc->ack_timer.timer)) |
1187 | mod_timer(&llc->ack_timer.timer, | 1140 | mod_timer(&llc->ack_timer.timer, |
1188 | jiffies + llc->ack_timer.expire * HZ); | 1141 | jiffies + llc->ack_timer.expire); |
1189 | return 0; | 1142 | return 0; |
1190 | } | 1143 | } |
1191 | 1144 | ||
@@ -1233,7 +1186,7 @@ int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb) | |||
1233 | } | 1186 | } |
1234 | if (unacked) | 1187 | if (unacked) |
1235 | mod_timer(&llc->ack_timer.timer, | 1188 | mod_timer(&llc->ack_timer.timer, |
1236 | jiffies + llc->ack_timer.expire * HZ); | 1189 | jiffies + llc->ack_timer.expire); |
1237 | } else if (llc->failed_data_req) { | 1190 | } else if (llc->failed_data_req) { |
1238 | u8 f_bit; | 1191 | u8 f_bit; |
1239 | 1192 | ||
@@ -1354,13 +1307,13 @@ int llc_conn_ac_set_vs_nr(struct sock *sk, struct sk_buff *skb) | |||
1354 | return 0; | 1307 | return 0; |
1355 | } | 1308 | } |
1356 | 1309 | ||
1357 | int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb) | 1310 | static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb) |
1358 | { | 1311 | { |
1359 | llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % 128; | 1312 | llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % 128; |
1360 | return 0; | 1313 | return 0; |
1361 | } | 1314 | } |
1362 | 1315 | ||
1363 | void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data) | 1316 | static void llc_conn_tmr_common_cb(unsigned long timeout_data, u8 type) |
1364 | { | 1317 | { |
1365 | struct sock *sk = (struct sock *)timeout_data; | 1318 | struct sock *sk = (struct sock *)timeout_data; |
1366 | struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); | 1319 | struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); |
@@ -1369,59 +1322,31 @@ void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data) | |||
1369 | if (skb) { | 1322 | if (skb) { |
1370 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 1323 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
1371 | 1324 | ||
1372 | skb->sk = sk; | 1325 | skb_set_owner_r(skb, sk); |
1373 | ev->type = LLC_CONN_EV_TYPE_P_TMR; | 1326 | ev->type = type; |
1374 | llc_process_tmr_ev(sk, skb); | 1327 | llc_process_tmr_ev(sk, skb); |
1375 | } | 1328 | } |
1376 | bh_unlock_sock(sk); | 1329 | bh_unlock_sock(sk); |
1377 | } | 1330 | } |
1378 | 1331 | ||
1379 | void llc_conn_busy_tmr_cb(unsigned long timeout_data) | 1332 | void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data) |
1380 | { | 1333 | { |
1381 | struct sock *sk = (struct sock *)timeout_data; | 1334 | llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_P_TMR); |
1382 | struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); | 1335 | } |
1383 | |||
1384 | bh_lock_sock(sk); | ||
1385 | if (skb) { | ||
1386 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | ||
1387 | 1336 | ||
1388 | skb->sk = sk; | 1337 | void llc_conn_busy_tmr_cb(unsigned long timeout_data) |
1389 | ev->type = LLC_CONN_EV_TYPE_BUSY_TMR; | 1338 | { |
1390 | llc_process_tmr_ev(sk, skb); | 1339 | llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_BUSY_TMR); |
1391 | } | ||
1392 | bh_unlock_sock(sk); | ||
1393 | } | 1340 | } |
1394 | 1341 | ||
1395 | void llc_conn_ack_tmr_cb(unsigned long timeout_data) | 1342 | void llc_conn_ack_tmr_cb(unsigned long timeout_data) |
1396 | { | 1343 | { |
1397 | struct sock* sk = (struct sock *)timeout_data; | 1344 | llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_ACK_TMR); |
1398 | struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); | ||
1399 | |||
1400 | bh_lock_sock(sk); | ||
1401 | if (skb) { | ||
1402 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | ||
1403 | |||
1404 | skb->sk = sk; | ||
1405 | ev->type = LLC_CONN_EV_TYPE_ACK_TMR; | ||
1406 | llc_process_tmr_ev(sk, skb); | ||
1407 | } | ||
1408 | bh_unlock_sock(sk); | ||
1409 | } | 1345 | } |
1410 | 1346 | ||
1411 | void llc_conn_rej_tmr_cb(unsigned long timeout_data) | 1347 | void llc_conn_rej_tmr_cb(unsigned long timeout_data) |
1412 | { | 1348 | { |
1413 | struct sock *sk = (struct sock *)timeout_data; | 1349 | llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_REJ_TMR); |
1414 | struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC); | ||
1415 | |||
1416 | bh_lock_sock(sk); | ||
1417 | if (skb) { | ||
1418 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | ||
1419 | |||
1420 | skb->sk = sk; | ||
1421 | ev->type = LLC_CONN_EV_TYPE_REJ_TMR; | ||
1422 | llc_process_tmr_ev(sk, skb); | ||
1423 | } | ||
1424 | bh_unlock_sock(sk); | ||
1425 | } | 1350 | } |
1426 | 1351 | ||
1427 | int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb) | 1352 | int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb) |
diff --git a/net/llc/llc_c_ev.c b/net/llc/llc_c_ev.c index d5bdb53a348f..c5deda246614 100644 --- a/net/llc/llc_c_ev.c +++ b/net/llc/llc_c_ev.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <net/llc_conn.h> | 37 | #include <net/llc_conn.h> |
38 | #include <net/llc_sap.h> | 38 | #include <net/llc_sap.h> |
39 | #include <net/sock.h> | 39 | #include <net/sock.h> |
40 | #include <net/llc_c_ac.h> | ||
40 | #include <net/llc_c_ev.h> | 41 | #include <net/llc_c_ev.h> |
41 | #include <net/llc_pdu.h> | 42 | #include <net/llc_pdu.h> |
42 | 43 | ||
@@ -46,8 +47,6 @@ | |||
46 | #define dprintk(args...) | 47 | #define dprintk(args...) |
47 | #endif | 48 | #endif |
48 | 49 | ||
49 | extern u16 llc_circular_between(u8 a, u8 b, u8 c); | ||
50 | |||
51 | /** | 50 | /** |
52 | * llc_util_ns_inside_rx_window - check if sequence number is in rx window | 51 | * llc_util_ns_inside_rx_window - check if sequence number is in rx window |
53 | * @ns: sequence number of received pdu. | 52 | * @ns: sequence number of received pdu. |
@@ -99,7 +98,7 @@ out: | |||
99 | 98 | ||
100 | int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb) | 99 | int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb) |
101 | { | 100 | { |
102 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 101 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
103 | 102 | ||
104 | return ev->prim == LLC_CONN_PRIM && | 103 | return ev->prim == LLC_CONN_PRIM && |
105 | ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1; | 104 | ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1; |
@@ -107,7 +106,7 @@ int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb) | |||
107 | 106 | ||
108 | int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb) | 107 | int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb) |
109 | { | 108 | { |
110 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 109 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
111 | 110 | ||
112 | return ev->prim == LLC_DATA_PRIM && | 111 | return ev->prim == LLC_DATA_PRIM && |
113 | ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1; | 112 | ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1; |
@@ -115,7 +114,7 @@ int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb) | |||
115 | 114 | ||
116 | int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb) | 115 | int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb) |
117 | { | 116 | { |
118 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 117 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
119 | 118 | ||
120 | return ev->prim == LLC_DISC_PRIM && | 119 | return ev->prim == LLC_DISC_PRIM && |
121 | ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1; | 120 | ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1; |
@@ -123,7 +122,7 @@ int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb) | |||
123 | 122 | ||
124 | int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb) | 123 | int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb) |
125 | { | 124 | { |
126 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 125 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
127 | 126 | ||
128 | return ev->prim == LLC_RESET_PRIM && | 127 | return ev->prim == LLC_RESET_PRIM && |
129 | ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1; | 128 | ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1; |
@@ -131,7 +130,7 @@ int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb) | |||
131 | 130 | ||
132 | int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb) | 131 | int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb) |
133 | { | 132 | { |
134 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 133 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
135 | 134 | ||
136 | return ev->type == LLC_CONN_EV_TYPE_SIMPLE && | 135 | return ev->type == LLC_CONN_EV_TYPE_SIMPLE && |
137 | ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1; | 136 | ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1; |
@@ -139,7 +138,7 @@ int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb) | |||
139 | 138 | ||
140 | int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb) | 139 | int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb) |
141 | { | 140 | { |
142 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 141 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
143 | 142 | ||
144 | return ev->type == LLC_CONN_EV_TYPE_SIMPLE && | 143 | return ev->type == LLC_CONN_EV_TYPE_SIMPLE && |
145 | ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1; | 144 | ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1; |
@@ -152,7 +151,7 @@ int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb) | |||
152 | 151 | ||
153 | int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb) | 152 | int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb) |
154 | { | 153 | { |
155 | struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | 154 | const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); |
156 | 155 | ||
157 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) && | 156 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) && |
158 | LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1; | 157 | LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1; |
@@ -160,7 +159,7 @@ int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb) | |||
160 | 159 | ||
161 | int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | 160 | int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) |
162 | { | 161 | { |
163 | struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | 162 | const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); |
164 | 163 | ||
165 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) && | 164 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) && |
166 | LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1; | 165 | LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1; |
@@ -168,7 +167,7 @@ int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | |||
168 | 167 | ||
169 | int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | 168 | int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) |
170 | { | 169 | { |
171 | struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | 170 | const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); |
172 | 171 | ||
173 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) && | 172 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) && |
174 | LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1; | 173 | LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1; |
@@ -176,7 +175,7 @@ int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | |||
176 | 175 | ||
177 | int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) | 176 | int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) |
178 | { | 177 | { |
179 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 178 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
180 | 179 | ||
181 | return llc_conn_space(sk, skb) && | 180 | return llc_conn_space(sk, skb) && |
182 | LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 181 | LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && |
@@ -186,7 +185,7 @@ int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) | |||
186 | 185 | ||
187 | int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) | 186 | int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) |
188 | { | 187 | { |
189 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 188 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
190 | 189 | ||
191 | return llc_conn_space(sk, skb) && | 190 | return llc_conn_space(sk, skb) && |
192 | LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 191 | LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && |
@@ -197,9 +196,9 @@ int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) | |||
197 | int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk, | 196 | int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk, |
198 | struct sk_buff *skb) | 197 | struct sk_buff *skb) |
199 | { | 198 | { |
200 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 199 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
201 | u8 vr = llc_sk(sk)->vR; | 200 | const u8 vr = llc_sk(sk)->vR; |
202 | u8 ns = LLC_I_GET_NS(pdu); | 201 | const u8 ns = LLC_I_GET_NS(pdu); |
203 | 202 | ||
204 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 203 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && |
205 | LLC_I_PF_IS_0(pdu) && ns != vr && | 204 | LLC_I_PF_IS_0(pdu) && ns != vr && |
@@ -209,9 +208,9 @@ int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk, | |||
209 | int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk, | 208 | int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk, |
210 | struct sk_buff *skb) | 209 | struct sk_buff *skb) |
211 | { | 210 | { |
212 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 211 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
213 | u8 vr = llc_sk(sk)->vR; | 212 | const u8 vr = llc_sk(sk)->vR; |
214 | u8 ns = LLC_I_GET_NS(pdu); | 213 | const u8 ns = LLC_I_GET_NS(pdu); |
215 | 214 | ||
216 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 215 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && |
217 | LLC_I_PF_IS_1(pdu) && ns != vr && | 216 | LLC_I_PF_IS_1(pdu) && ns != vr && |
@@ -221,10 +220,11 @@ int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk, | |||
221 | int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk, | 220 | int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk, |
222 | struct sk_buff *skb) | 221 | struct sk_buff *skb) |
223 | { | 222 | { |
224 | struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb); | 223 | const struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb); |
225 | u8 vr = llc_sk(sk)->vR; | 224 | const u8 vr = llc_sk(sk)->vR; |
226 | u8 ns = LLC_I_GET_NS(pdu); | 225 | const u8 ns = LLC_I_GET_NS(pdu); |
227 | u16 rc = LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr && | 226 | const u16 rc = LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && |
227 | ns != vr && | ||
228 | llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; | 228 | llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; |
229 | if (!rc) | 229 | if (!rc) |
230 | dprintk("%s: matched, state=%d, ns=%d, vr=%d\n", | 230 | dprintk("%s: matched, state=%d, ns=%d, vr=%d\n", |
@@ -234,7 +234,7 @@ int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk, | |||
234 | 234 | ||
235 | int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) | 235 | int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) |
236 | { | 236 | { |
237 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 237 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
238 | 238 | ||
239 | return llc_conn_space(sk, skb) && | 239 | return llc_conn_space(sk, skb) && |
240 | LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 240 | LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && |
@@ -244,7 +244,7 @@ int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) | |||
244 | 244 | ||
245 | int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) | 245 | int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) |
246 | { | 246 | { |
247 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 247 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
248 | 248 | ||
249 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 249 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && |
250 | LLC_I_PF_IS_1(pdu) && | 250 | LLC_I_PF_IS_1(pdu) && |
@@ -253,7 +253,7 @@ int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) | |||
253 | 253 | ||
254 | int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | 254 | int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) |
255 | { | 255 | { |
256 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 256 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
257 | 257 | ||
258 | return llc_conn_space(sk, skb) && | 258 | return llc_conn_space(sk, skb) && |
259 | LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 259 | LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && |
@@ -263,9 +263,9 @@ int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | |||
263 | int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk, | 263 | int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk, |
264 | struct sk_buff *skb) | 264 | struct sk_buff *skb) |
265 | { | 265 | { |
266 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 266 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
267 | u8 vr = llc_sk(sk)->vR; | 267 | const u8 vr = llc_sk(sk)->vR; |
268 | u8 ns = LLC_I_GET_NS(pdu); | 268 | const u8 ns = LLC_I_GET_NS(pdu); |
269 | 269 | ||
270 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 270 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && |
271 | LLC_I_PF_IS_0(pdu) && ns != vr && | 271 | LLC_I_PF_IS_0(pdu) && ns != vr && |
@@ -275,9 +275,9 @@ int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk, | |||
275 | int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk, | 275 | int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk, |
276 | struct sk_buff *skb) | 276 | struct sk_buff *skb) |
277 | { | 277 | { |
278 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 278 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
279 | u8 vr = llc_sk(sk)->vR; | 279 | const u8 vr = llc_sk(sk)->vR; |
280 | u8 ns = LLC_I_GET_NS(pdu); | 280 | const u8 ns = LLC_I_GET_NS(pdu); |
281 | 281 | ||
282 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && | 282 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && |
283 | LLC_I_PF_IS_1(pdu) && ns != vr && | 283 | LLC_I_PF_IS_1(pdu) && ns != vr && |
@@ -287,9 +287,9 @@ int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk, | |||
287 | int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk, | 287 | int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk, |
288 | struct sk_buff *skb) | 288 | struct sk_buff *skb) |
289 | { | 289 | { |
290 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 290 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
291 | u8 vr = llc_sk(sk)->vR; | 291 | const u8 vr = llc_sk(sk)->vR; |
292 | u8 ns = LLC_I_GET_NS(pdu); | 292 | const u8 ns = LLC_I_GET_NS(pdu); |
293 | 293 | ||
294 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr && | 294 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr && |
295 | !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; | 295 | !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; |
@@ -298,10 +298,11 @@ int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk, | |||
298 | int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk, | 298 | int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk, |
299 | struct sk_buff *skb) | 299 | struct sk_buff *skb) |
300 | { | 300 | { |
301 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 301 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
302 | u8 vr = llc_sk(sk)->vR; | 302 | const u8 vr = llc_sk(sk)->vR; |
303 | u8 ns = LLC_I_GET_NS(pdu); | 303 | const u8 ns = LLC_I_GET_NS(pdu); |
304 | u16 rc = LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr && | 304 | const u16 rc = LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && |
305 | ns != vr && | ||
305 | llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; | 306 | llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1; |
306 | if (!rc) | 307 | if (!rc) |
307 | dprintk("%s: matched, state=%d, ns=%d, vr=%d\n", | 308 | dprintk("%s: matched, state=%d, ns=%d, vr=%d\n", |
@@ -311,7 +312,7 @@ int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk, | |||
311 | 312 | ||
312 | int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) | 313 | int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) |
313 | { | 314 | { |
314 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 315 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
315 | 316 | ||
316 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 317 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && |
317 | LLC_S_PF_IS_0(pdu) && | 318 | LLC_S_PF_IS_0(pdu) && |
@@ -320,7 +321,7 @@ int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) | |||
320 | 321 | ||
321 | int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) | 322 | int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) |
322 | { | 323 | { |
323 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 324 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
324 | 325 | ||
325 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 326 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && |
326 | LLC_S_PF_IS_1(pdu) && | 327 | LLC_S_PF_IS_1(pdu) && |
@@ -329,7 +330,7 @@ int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) | |||
329 | 330 | ||
330 | int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) | 331 | int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) |
331 | { | 332 | { |
332 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 333 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
333 | 334 | ||
334 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 335 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && |
335 | LLC_S_PF_IS_0(pdu) && | 336 | LLC_S_PF_IS_0(pdu) && |
@@ -338,7 +339,7 @@ int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) | |||
338 | 339 | ||
339 | int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) | 340 | int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) |
340 | { | 341 | { |
341 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 342 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
342 | 343 | ||
343 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 344 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && |
344 | LLC_S_PF_IS_1(pdu) && | 345 | LLC_S_PF_IS_1(pdu) && |
@@ -347,7 +348,7 @@ int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) | |||
347 | 348 | ||
348 | int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | 349 | int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) |
349 | { | 350 | { |
350 | struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | 351 | const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); |
351 | 352 | ||
352 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 353 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && |
353 | LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1; | 354 | LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1; |
@@ -355,7 +356,7 @@ int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | |||
355 | 356 | ||
356 | int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) | 357 | int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) |
357 | { | 358 | { |
358 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 359 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
359 | 360 | ||
360 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 361 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && |
361 | LLC_S_PF_IS_0(pdu) && | 362 | LLC_S_PF_IS_0(pdu) && |
@@ -364,7 +365,7 @@ int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) | |||
364 | 365 | ||
365 | int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) | 366 | int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) |
366 | { | 367 | { |
367 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 368 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
368 | 369 | ||
369 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 370 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && |
370 | LLC_S_PF_IS_1(pdu) && | 371 | LLC_S_PF_IS_1(pdu) && |
@@ -373,7 +374,7 @@ int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) | |||
373 | 374 | ||
374 | int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) | 375 | int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) |
375 | { | 376 | { |
376 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 377 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
377 | 378 | ||
378 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 379 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && |
379 | LLC_S_PF_IS_0(pdu) && | 380 | LLC_S_PF_IS_0(pdu) && |
@@ -382,7 +383,7 @@ int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) | |||
382 | 383 | ||
383 | int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) | 384 | int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) |
384 | { | 385 | { |
385 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 386 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
386 | 387 | ||
387 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 388 | return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && |
388 | LLC_S_PF_IS_1(pdu) && | 389 | LLC_S_PF_IS_1(pdu) && |
@@ -391,7 +392,7 @@ int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) | |||
391 | 392 | ||
392 | int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) | 393 | int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) |
393 | { | 394 | { |
394 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 395 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
395 | 396 | ||
396 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 397 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && |
397 | LLC_S_PF_IS_0(pdu) && | 398 | LLC_S_PF_IS_0(pdu) && |
@@ -400,7 +401,7 @@ int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb) | |||
400 | 401 | ||
401 | int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) | 402 | int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) |
402 | { | 403 | { |
403 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 404 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
404 | 405 | ||
405 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 406 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) && |
406 | LLC_S_PF_IS_1(pdu) && | 407 | LLC_S_PF_IS_1(pdu) && |
@@ -409,7 +410,7 @@ int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) | |||
409 | 410 | ||
410 | int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) | 411 | int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) |
411 | { | 412 | { |
412 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 413 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
413 | 414 | ||
414 | return llc_conn_space(sk, skb) && | 415 | return llc_conn_space(sk, skb) && |
415 | LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 416 | LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && |
@@ -419,7 +420,7 @@ int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb) | |||
419 | 420 | ||
420 | int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) | 421 | int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) |
421 | { | 422 | { |
422 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 423 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
423 | 424 | ||
424 | return llc_conn_space(sk, skb) && | 425 | return llc_conn_space(sk, skb) && |
425 | LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && | 426 | LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) && |
@@ -429,7 +430,7 @@ int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) | |||
429 | 430 | ||
430 | int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb) | 431 | int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb) |
431 | { | 432 | { |
432 | struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | 433 | const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); |
433 | 434 | ||
434 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) && | 435 | return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) && |
435 | LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1; | 436 | LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1; |
@@ -446,7 +447,7 @@ int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | |||
446 | int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) | 447 | int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) |
447 | { | 448 | { |
448 | u16 rc = 1; | 449 | u16 rc = 1; |
449 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 450 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
450 | 451 | ||
451 | if (LLC_PDU_IS_CMD(pdu)) { | 452 | if (LLC_PDU_IS_CMD(pdu)) { |
452 | if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) { | 453 | if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) { |
@@ -461,7 +462,7 @@ int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb) | |||
461 | int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb) | 462 | int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb) |
462 | { | 463 | { |
463 | u16 rc = 1; | 464 | u16 rc = 1; |
464 | struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | 465 | const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); |
465 | 466 | ||
466 | if (LLC_PDU_IS_CMD(pdu)) { | 467 | if (LLC_PDU_IS_CMD(pdu)) { |
467 | if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) | 468 | if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) |
@@ -477,32 +478,10 @@ int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb) | |||
477 | return rc; | 478 | return rc; |
478 | } | 479 | } |
479 | 480 | ||
480 | int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb) | ||
481 | { | ||
482 | u16 rc = 1; | ||
483 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | ||
484 | |||
485 | if (LLC_PDU_IS_RSP(pdu)) { | ||
486 | if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) { | ||
487 | if (LLC_I_PF_IS_1(pdu)) | ||
488 | rc = 0; | ||
489 | } else if (LLC_PDU_TYPE_IS_U(pdu)) | ||
490 | switch (LLC_U_PDU_RSP(pdu)) { | ||
491 | case LLC_2_PDU_RSP_UA: | ||
492 | case LLC_2_PDU_RSP_DM: | ||
493 | case LLC_2_PDU_RSP_FRMR: | ||
494 | if (LLC_U_PF_IS_1(pdu)) | ||
495 | rc = 0; | ||
496 | break; | ||
497 | } | ||
498 | } | ||
499 | return rc; | ||
500 | } | ||
501 | |||
502 | int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) | 481 | int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb) |
503 | { | 482 | { |
504 | u16 rc = 1; | 483 | u16 rc = 1; |
505 | struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | 484 | const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); |
506 | 485 | ||
507 | if (LLC_PDU_IS_RSP(pdu)) { | 486 | if (LLC_PDU_IS_RSP(pdu)) { |
508 | if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) | 487 | if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) |
@@ -524,9 +503,9 @@ int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk, | |||
524 | struct sk_buff *skb) | 503 | struct sk_buff *skb) |
525 | { | 504 | { |
526 | u16 rc = 1; | 505 | u16 rc = 1; |
527 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 506 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
528 | u8 vs = llc_sk(sk)->vS; | 507 | const u8 vs = llc_sk(sk)->vS; |
529 | u8 nr = LLC_I_GET_NR(pdu); | 508 | const u8 nr = LLC_I_GET_NR(pdu); |
530 | 509 | ||
531 | if (LLC_PDU_IS_CMD(pdu) && | 510 | if (LLC_PDU_IS_CMD(pdu) && |
532 | (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) && | 511 | (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) && |
@@ -542,9 +521,9 @@ int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk, | |||
542 | struct sk_buff *skb) | 521 | struct sk_buff *skb) |
543 | { | 522 | { |
544 | u16 rc = 1; | 523 | u16 rc = 1; |
545 | struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); | 524 | const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); |
546 | u8 vs = llc_sk(sk)->vS; | 525 | const u8 vs = llc_sk(sk)->vS; |
547 | u8 nr = LLC_I_GET_NR(pdu); | 526 | const u8 nr = LLC_I_GET_NR(pdu); |
548 | 527 | ||
549 | if (LLC_PDU_IS_RSP(pdu) && | 528 | if (LLC_PDU_IS_RSP(pdu) && |
550 | (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) && | 529 | (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) && |
@@ -563,28 +542,28 @@ int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb) | |||
563 | 542 | ||
564 | int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb) | 543 | int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb) |
565 | { | 544 | { |
566 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 545 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
567 | 546 | ||
568 | return ev->type != LLC_CONN_EV_TYPE_P_TMR; | 547 | return ev->type != LLC_CONN_EV_TYPE_P_TMR; |
569 | } | 548 | } |
570 | 549 | ||
571 | int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb) | 550 | int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb) |
572 | { | 551 | { |
573 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 552 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
574 | 553 | ||
575 | return ev->type != LLC_CONN_EV_TYPE_ACK_TMR; | 554 | return ev->type != LLC_CONN_EV_TYPE_ACK_TMR; |
576 | } | 555 | } |
577 | 556 | ||
578 | int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb) | 557 | int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb) |
579 | { | 558 | { |
580 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 559 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
581 | 560 | ||
582 | return ev->type != LLC_CONN_EV_TYPE_REJ_TMR; | 561 | return ev->type != LLC_CONN_EV_TYPE_REJ_TMR; |
583 | } | 562 | } |
584 | 563 | ||
585 | int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb) | 564 | int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb) |
586 | { | 565 | { |
587 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 566 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
588 | 567 | ||
589 | return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR; | 568 | return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR; |
590 | } | 569 | } |
@@ -596,7 +575,7 @@ int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb) | |||
596 | 575 | ||
597 | int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb) | 576 | int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb) |
598 | { | 577 | { |
599 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 578 | const struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
600 | 579 | ||
601 | return ev->type == LLC_CONN_EV_TYPE_SIMPLE && | 580 | return ev->type == LLC_CONN_EV_TYPE_SIMPLE && |
602 | ev->prim_type == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1; | 581 | ev->prim_type == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1; |
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 4c644bc70eae..042b24a8ca4c 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c | |||
@@ -40,6 +40,11 @@ static struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk, | |||
40 | /* Offset table on connection states transition diagram */ | 40 | /* Offset table on connection states transition diagram */ |
41 | static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV]; | 41 | static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV]; |
42 | 42 | ||
43 | int sysctl_llc2_ack_timeout = LLC2_ACK_TIME * HZ; | ||
44 | int sysctl_llc2_p_timeout = LLC2_P_TIME * HZ; | ||
45 | int sysctl_llc2_rej_timeout = LLC2_REJ_TIME * HZ; | ||
46 | int sysctl_llc2_busy_timeout = LLC2_BUSY_TIME * HZ; | ||
47 | |||
43 | /** | 48 | /** |
44 | * llc_conn_state_process - sends event to connection state machine | 49 | * llc_conn_state_process - sends event to connection state machine |
45 | * @sk: connection | 50 | * @sk: connection |
@@ -53,7 +58,7 @@ static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV]; | |||
53 | int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) | 58 | int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) |
54 | { | 59 | { |
55 | int rc; | 60 | int rc; |
56 | struct llc_sock *llc = llc_sk(sk); | 61 | struct llc_sock *llc = llc_sk(skb->sk); |
57 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 62 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
58 | 63 | ||
59 | /* | 64 | /* |
@@ -63,13 +68,16 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) | |||
63 | */ | 68 | */ |
64 | skb_get(skb); | 69 | skb_get(skb); |
65 | ev->ind_prim = ev->cfm_prim = 0; | 70 | ev->ind_prim = ev->cfm_prim = 0; |
66 | rc = llc_conn_service(sk, skb); /* sending event to state machine */ | 71 | /* |
67 | if (rc) { | 72 | * Send event to state machine |
73 | */ | ||
74 | rc = llc_conn_service(skb->sk, skb); | ||
75 | if (unlikely(rc != 0)) { | ||
68 | printk(KERN_ERR "%s: llc_conn_service failed\n", __FUNCTION__); | 76 | printk(KERN_ERR "%s: llc_conn_service failed\n", __FUNCTION__); |
69 | goto out_kfree_skb; | 77 | goto out_kfree_skb; |
70 | } | 78 | } |
71 | 79 | ||
72 | if (!ev->ind_prim && !ev->cfm_prim) { | 80 | if (unlikely(!ev->ind_prim && !ev->cfm_prim)) { |
73 | /* indicate or confirm not required */ | 81 | /* indicate or confirm not required */ |
74 | /* XXX this is not very pretty, perhaps we should store | 82 | /* XXX this is not very pretty, perhaps we should store |
75 | * XXX indicate/confirm-needed state in the llc_conn_state_ev | 83 | * XXX indicate/confirm-needed state in the llc_conn_state_ev |
@@ -80,13 +88,13 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) | |||
80 | goto out_skb_put; | 88 | goto out_skb_put; |
81 | } | 89 | } |
82 | 90 | ||
83 | if (ev->ind_prim && ev->cfm_prim) /* Paranoia */ | 91 | if (unlikely(ev->ind_prim && ev->cfm_prim)) /* Paranoia */ |
84 | skb_get(skb); | 92 | skb_get(skb); |
85 | 93 | ||
86 | switch (ev->ind_prim) { | 94 | switch (ev->ind_prim) { |
87 | case LLC_DATA_PRIM: | 95 | case LLC_DATA_PRIM: |
88 | llc_save_primitive(skb, LLC_DATA_PRIM); | 96 | llc_save_primitive(sk, skb, LLC_DATA_PRIM); |
89 | if (sock_queue_rcv_skb(sk, skb)) { | 97 | if (unlikely(sock_queue_rcv_skb(sk, skb))) { |
90 | /* | 98 | /* |
91 | * shouldn't happen | 99 | * shouldn't happen |
92 | */ | 100 | */ |
@@ -95,13 +103,14 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) | |||
95 | kfree_skb(skb); | 103 | kfree_skb(skb); |
96 | } | 104 | } |
97 | break; | 105 | break; |
98 | case LLC_CONN_PRIM: { | 106 | case LLC_CONN_PRIM: |
99 | struct sock *parent = skb->sk; | 107 | /* |
100 | 108 | * Can't be sock_queue_rcv_skb, because we have to leave the | |
101 | skb->sk = sk; | 109 | * skb->sk pointing to the newly created struct sock in |
102 | skb_queue_tail(&parent->sk_receive_queue, skb); | 110 | * llc_conn_handler. -acme |
103 | sk->sk_state_change(parent); | 111 | */ |
104 | } | 112 | skb_queue_tail(&sk->sk_receive_queue, skb); |
113 | sk->sk_state_change(sk); | ||
105 | break; | 114 | break; |
106 | case LLC_DISC_PRIM: | 115 | case LLC_DISC_PRIM: |
107 | sock_hold(sk); | 116 | sock_hold(sk); |
@@ -111,8 +120,8 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) | |||
111 | sk->sk_socket->state = SS_UNCONNECTED; | 120 | sk->sk_socket->state = SS_UNCONNECTED; |
112 | sk->sk_state = TCP_CLOSE; | 121 | sk->sk_state = TCP_CLOSE; |
113 | if (!sock_flag(sk, SOCK_DEAD)) { | 122 | if (!sock_flag(sk, SOCK_DEAD)) { |
114 | sk->sk_state_change(sk); | ||
115 | sock_set_flag(sk, SOCK_DEAD); | 123 | sock_set_flag(sk, SOCK_DEAD); |
124 | sk->sk_state_change(sk); | ||
116 | } | 125 | } |
117 | } | 126 | } |
118 | kfree_skb(skb); | 127 | kfree_skb(skb); |
@@ -465,7 +474,7 @@ static int llc_exec_conn_trans_actions(struct sock *sk, | |||
465 | } | 474 | } |
466 | 475 | ||
467 | /** | 476 | /** |
468 | * llc_lookup_established - Finds connection for the remote/local sap/mac | 477 | * __llc_lookup_established - Finds connection for the remote/local sap/mac |
469 | * @sap: SAP | 478 | * @sap: SAP |
470 | * @daddr: address of remote LLC (MAC + SAP) | 479 | * @daddr: address of remote LLC (MAC + SAP) |
471 | * @laddr: address of local LLC (MAC + SAP) | 480 | * @laddr: address of local LLC (MAC + SAP) |
@@ -473,14 +482,16 @@ static int llc_exec_conn_trans_actions(struct sock *sk, | |||
473 | * Search connection list of the SAP and finds connection using the remote | 482 | * Search connection list of the SAP and finds connection using the remote |
474 | * mac, remote sap, local mac, and local sap. Returns pointer for | 483 | * mac, remote sap, local mac, and local sap. Returns pointer for |
475 | * connection found, %NULL otherwise. | 484 | * connection found, %NULL otherwise. |
485 | * Caller has to make sure local_bh is disabled. | ||
476 | */ | 486 | */ |
477 | struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr, | 487 | static struct sock *__llc_lookup_established(struct llc_sap *sap, |
478 | struct llc_addr *laddr) | 488 | struct llc_addr *daddr, |
489 | struct llc_addr *laddr) | ||
479 | { | 490 | { |
480 | struct sock *rc; | 491 | struct sock *rc; |
481 | struct hlist_node *node; | 492 | struct hlist_node *node; |
482 | 493 | ||
483 | read_lock_bh(&sap->sk_list.lock); | 494 | read_lock(&sap->sk_list.lock); |
484 | sk_for_each(rc, node, &sap->sk_list.list) { | 495 | sk_for_each(rc, node, &sap->sk_list.list) { |
485 | struct llc_sock *llc = llc_sk(rc); | 496 | struct llc_sock *llc = llc_sk(rc); |
486 | 497 | ||
@@ -494,10 +505,22 @@ struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr, | |||
494 | } | 505 | } |
495 | rc = NULL; | 506 | rc = NULL; |
496 | found: | 507 | found: |
497 | read_unlock_bh(&sap->sk_list.lock); | 508 | read_unlock(&sap->sk_list.lock); |
498 | return rc; | 509 | return rc; |
499 | } | 510 | } |
500 | 511 | ||
512 | struct sock *llc_lookup_established(struct llc_sap *sap, | ||
513 | struct llc_addr *daddr, | ||
514 | struct llc_addr *laddr) | ||
515 | { | ||
516 | struct sock *sk; | ||
517 | |||
518 | local_bh_disable(); | ||
519 | sk = __llc_lookup_established(sap, daddr, laddr); | ||
520 | local_bh_enable(); | ||
521 | return sk; | ||
522 | } | ||
523 | |||
501 | /** | 524 | /** |
502 | * llc_lookup_listener - Finds listener for local MAC + SAP | 525 | * llc_lookup_listener - Finds listener for local MAC + SAP |
503 | * @sap: SAP | 526 | * @sap: SAP |
@@ -506,6 +529,7 @@ found: | |||
506 | * Search connection list of the SAP and finds connection listening on | 529 | * Search connection list of the SAP and finds connection listening on |
507 | * local mac, and local sap. Returns pointer for parent socket found, | 530 | * local mac, and local sap. Returns pointer for parent socket found, |
508 | * %NULL otherwise. | 531 | * %NULL otherwise. |
532 | * Caller has to make sure local_bh is disabled. | ||
509 | */ | 533 | */ |
510 | static struct sock *llc_lookup_listener(struct llc_sap *sap, | 534 | static struct sock *llc_lookup_listener(struct llc_sap *sap, |
511 | struct llc_addr *laddr) | 535 | struct llc_addr *laddr) |
@@ -513,7 +537,7 @@ static struct sock *llc_lookup_listener(struct llc_sap *sap, | |||
513 | struct sock *rc; | 537 | struct sock *rc; |
514 | struct hlist_node *node; | 538 | struct hlist_node *node; |
515 | 539 | ||
516 | read_lock_bh(&sap->sk_list.lock); | 540 | read_lock(&sap->sk_list.lock); |
517 | sk_for_each(rc, node, &sap->sk_list.list) { | 541 | sk_for_each(rc, node, &sap->sk_list.list) { |
518 | struct llc_sock *llc = llc_sk(rc); | 542 | struct llc_sock *llc = llc_sk(rc); |
519 | 543 | ||
@@ -527,10 +551,19 @@ static struct sock *llc_lookup_listener(struct llc_sap *sap, | |||
527 | } | 551 | } |
528 | rc = NULL; | 552 | rc = NULL; |
529 | found: | 553 | found: |
530 | read_unlock_bh(&sap->sk_list.lock); | 554 | read_unlock(&sap->sk_list.lock); |
531 | return rc; | 555 | return rc; |
532 | } | 556 | } |
533 | 557 | ||
558 | static struct sock *__llc_lookup(struct llc_sap *sap, | ||
559 | struct llc_addr *daddr, | ||
560 | struct llc_addr *laddr) | ||
561 | { | ||
562 | struct sock *sk = __llc_lookup_established(sap, daddr, laddr); | ||
563 | |||
564 | return sk ? : llc_lookup_listener(sap, laddr); | ||
565 | } | ||
566 | |||
534 | /** | 567 | /** |
535 | * llc_data_accept_state - designates if in this state data can be sent. | 568 | * llc_data_accept_state - designates if in this state data can be sent. |
536 | * @state: state of connection. | 569 | * @state: state of connection. |
@@ -544,14 +577,14 @@ u8 llc_data_accept_state(u8 state) | |||
544 | } | 577 | } |
545 | 578 | ||
546 | /** | 579 | /** |
547 | * find_next_offset - finds offset for next category of transitions | 580 | * llc_find_next_offset - finds offset for next category of transitions |
548 | * @state: state table. | 581 | * @state: state table. |
549 | * @offset: start offset. | 582 | * @offset: start offset. |
550 | * | 583 | * |
551 | * Finds offset of next category of transitions in transition table. | 584 | * Finds offset of next category of transitions in transition table. |
552 | * Returns the start index of next category. | 585 | * Returns the start index of next category. |
553 | */ | 586 | */ |
554 | static u16 find_next_offset(struct llc_conn_state *state, u16 offset) | 587 | static u16 __init llc_find_next_offset(struct llc_conn_state *state, u16 offset) |
555 | { | 588 | { |
556 | u16 cnt = 0; | 589 | u16 cnt = 0; |
557 | struct llc_conn_state_trans **next_trans; | 590 | struct llc_conn_state_trans **next_trans; |
@@ -578,8 +611,8 @@ void __init llc_build_offset_table(void) | |||
578 | next_offset = 0; | 611 | next_offset = 0; |
579 | for (ev_type = 0; ev_type < NBR_CONN_EV; ev_type++) { | 612 | for (ev_type = 0; ev_type < NBR_CONN_EV; ev_type++) { |
580 | llc_offset_table[state][ev_type] = next_offset; | 613 | llc_offset_table[state][ev_type] = next_offset; |
581 | next_offset += find_next_offset(curr_state, | 614 | next_offset += llc_find_next_offset(curr_state, |
582 | next_offset) + 1; | 615 | next_offset) + 1; |
583 | } | 616 | } |
584 | } | 617 | } |
585 | } | 618 | } |
@@ -623,6 +656,7 @@ static int llc_find_offset(int state, int ev_type) | |||
623 | */ | 656 | */ |
624 | void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk) | 657 | void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk) |
625 | { | 658 | { |
659 | llc_sap_hold(sap); | ||
626 | write_lock_bh(&sap->sk_list.lock); | 660 | write_lock_bh(&sap->sk_list.lock); |
627 | llc_sk(sk)->sap = sap; | 661 | llc_sk(sk)->sap = sap; |
628 | sk_add_node(sk, &sap->sk_list.list); | 662 | sk_add_node(sk, &sap->sk_list.list); |
@@ -642,6 +676,7 @@ void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk) | |||
642 | write_lock_bh(&sap->sk_list.lock); | 676 | write_lock_bh(&sap->sk_list.lock); |
643 | sk_del_node_init(sk); | 677 | sk_del_node_init(sk); |
644 | write_unlock_bh(&sap->sk_list.lock); | 678 | write_unlock_bh(&sap->sk_list.lock); |
679 | llc_sap_put(sap); | ||
645 | } | 680 | } |
646 | 681 | ||
647 | /** | 682 | /** |
@@ -654,15 +689,34 @@ void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk) | |||
654 | static int llc_conn_rcv(struct sock* sk, struct sk_buff *skb) | 689 | static int llc_conn_rcv(struct sock* sk, struct sk_buff *skb) |
655 | { | 690 | { |
656 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); | 691 | struct llc_conn_state_ev *ev = llc_conn_ev(skb); |
657 | struct llc_sock *llc = llc_sk(sk); | ||
658 | 692 | ||
659 | if (!llc->dev) | ||
660 | llc->dev = skb->dev; | ||
661 | ev->type = LLC_CONN_EV_TYPE_PDU; | 693 | ev->type = LLC_CONN_EV_TYPE_PDU; |
662 | ev->reason = 0; | 694 | ev->reason = 0; |
663 | return llc_conn_state_process(sk, skb); | 695 | return llc_conn_state_process(sk, skb); |
664 | } | 696 | } |
665 | 697 | ||
698 | static struct sock *llc_create_incoming_sock(struct sock *sk, | ||
699 | struct net_device *dev, | ||
700 | struct llc_addr *saddr, | ||
701 | struct llc_addr *daddr) | ||
702 | { | ||
703 | struct sock *newsk = llc_sk_alloc(sk->sk_family, GFP_ATOMIC, | ||
704 | sk->sk_prot); | ||
705 | struct llc_sock *newllc, *llc = llc_sk(sk); | ||
706 | |||
707 | if (!newsk) | ||
708 | goto out; | ||
709 | newllc = llc_sk(newsk); | ||
710 | memcpy(&newllc->laddr, daddr, sizeof(newllc->laddr)); | ||
711 | memcpy(&newllc->daddr, saddr, sizeof(newllc->daddr)); | ||
712 | newllc->dev = dev; | ||
713 | dev_hold(dev); | ||
714 | llc_sap_add_socket(llc->sap, newsk); | ||
715 | llc_sap_hold(llc->sap); | ||
716 | out: | ||
717 | return newsk; | ||
718 | } | ||
719 | |||
666 | void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb) | 720 | void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb) |
667 | { | 721 | { |
668 | struct llc_addr saddr, daddr; | 722 | struct llc_addr saddr, daddr; |
@@ -673,35 +727,35 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb) | |||
673 | llc_pdu_decode_da(skb, daddr.mac); | 727 | llc_pdu_decode_da(skb, daddr.mac); |
674 | llc_pdu_decode_dsap(skb, &daddr.lsap); | 728 | llc_pdu_decode_dsap(skb, &daddr.lsap); |
675 | 729 | ||
676 | sk = llc_lookup_established(sap, &saddr, &daddr); | 730 | sk = __llc_lookup(sap, &saddr, &daddr); |
677 | if (!sk) { | 731 | if (!sk) |
732 | goto drop; | ||
733 | |||
734 | bh_lock_sock(sk); | ||
735 | /* | ||
736 | * This has to be done here and not at the upper layer ->accept | ||
737 | * method because of the way the PROCOM state machine works: | ||
738 | * it needs to set several state variables (see, for instance, | ||
739 | * llc_adm_actions_2 in net/llc/llc_c_st.c) and send a packet to | ||
740 | * the originator of the new connection, and this state has to be | ||
741 | * in the newly created struct sock private area. -acme | ||
742 | */ | ||
743 | if (unlikely(sk->sk_state == TCP_LISTEN)) { | ||
744 | struct sock *newsk = llc_create_incoming_sock(sk, skb->dev, | ||
745 | &saddr, &daddr); | ||
746 | if (!newsk) | ||
747 | goto drop_unlock; | ||
748 | skb_set_owner_r(skb, newsk); | ||
749 | } else { | ||
678 | /* | 750 | /* |
679 | * Didn't find an active connection; verify if there | 751 | * Can't be skb_set_owner_r, this will be done at the |
680 | * is a listening socket for this llc addr | 752 | * llc_conn_state_process function, later on, when we will use |
753 | * skb_queue_rcv_skb to send it to upper layers, this is | ||
754 | * another trick required to cope with how the PROCOM state | ||
755 | * machine works. -acme | ||
681 | */ | 756 | */ |
682 | struct llc_sock *llc; | ||
683 | struct sock *parent = llc_lookup_listener(sap, &daddr); | ||
684 | |||
685 | if (!parent) { | ||
686 | dprintk("llc_lookup_listener failed!\n"); | ||
687 | goto drop; | ||
688 | } | ||
689 | |||
690 | sk = llc_sk_alloc(parent->sk_family, GFP_ATOMIC, parent->sk_prot); | ||
691 | if (!sk) { | ||
692 | sock_put(parent); | ||
693 | goto drop; | ||
694 | } | ||
695 | llc = llc_sk(sk); | ||
696 | memcpy(&llc->laddr, &daddr, sizeof(llc->laddr)); | ||
697 | memcpy(&llc->daddr, &saddr, sizeof(llc->daddr)); | ||
698 | llc_sap_add_socket(sap, sk); | ||
699 | sock_hold(sk); | ||
700 | sock_put(parent); | ||
701 | skb->sk = parent; | ||
702 | } else | ||
703 | skb->sk = sk; | 757 | skb->sk = sk; |
704 | bh_lock_sock(sk); | 758 | } |
705 | if (!sock_owned_by_user(sk)) | 759 | if (!sock_owned_by_user(sk)) |
706 | llc_conn_rcv(sk, skb); | 760 | llc_conn_rcv(sk, skb); |
707 | else { | 761 | else { |
@@ -709,11 +763,16 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb) | |||
709 | llc_set_backlog_type(skb, LLC_PACKET); | 763 | llc_set_backlog_type(skb, LLC_PACKET); |
710 | sk_add_backlog(sk, skb); | 764 | sk_add_backlog(sk, skb); |
711 | } | 765 | } |
766 | out: | ||
712 | bh_unlock_sock(sk); | 767 | bh_unlock_sock(sk); |
713 | sock_put(sk); | 768 | sock_put(sk); |
714 | return; | 769 | return; |
715 | drop: | 770 | drop: |
716 | kfree_skb(skb); | 771 | kfree_skb(skb); |
772 | return; | ||
773 | drop_unlock: | ||
774 | kfree_skb(skb); | ||
775 | goto out; | ||
717 | } | 776 | } |
718 | 777 | ||
719 | #undef LLC_REFCNT_DEBUG | 778 | #undef LLC_REFCNT_DEBUG |
@@ -722,32 +781,6 @@ static atomic_t llc_sock_nr; | |||
722 | #endif | 781 | #endif |
723 | 782 | ||
724 | /** | 783 | /** |
725 | * llc_release_sockets - releases all sockets in a sap | ||
726 | * @sap: sap to release its sockets | ||
727 | * | ||
728 | * Releases all connections of a sap. Returns 0 if all actions complete | ||
729 | * successfully, nonzero otherwise | ||
730 | */ | ||
731 | int llc_release_sockets(struct llc_sap *sap) | ||
732 | { | ||
733 | int rc = 0; | ||
734 | struct sock *sk; | ||
735 | struct hlist_node *node; | ||
736 | |||
737 | write_lock_bh(&sap->sk_list.lock); | ||
738 | |||
739 | sk_for_each(sk, node, &sap->sk_list.list) { | ||
740 | llc_sk(sk)->state = LLC_CONN_STATE_TEMP; | ||
741 | |||
742 | if (llc_send_disc(sk)) | ||
743 | rc = 1; | ||
744 | } | ||
745 | |||
746 | write_unlock_bh(&sap->sk_list.lock); | ||
747 | return rc; | ||
748 | } | ||
749 | |||
750 | /** | ||
751 | * llc_backlog_rcv - Processes rx frames and expired timers. | 784 | * llc_backlog_rcv - Processes rx frames and expired timers. |
752 | * @sk: LLC sock (p8022 connection) | 785 | * @sk: LLC sock (p8022 connection) |
753 | * @skb: queued rx frame or event | 786 | * @skb: queued rx frame or event |
@@ -762,14 +795,14 @@ static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb) | |||
762 | int rc = 0; | 795 | int rc = 0; |
763 | struct llc_sock *llc = llc_sk(sk); | 796 | struct llc_sock *llc = llc_sk(sk); |
764 | 797 | ||
765 | if (llc_backlog_type(skb) == LLC_PACKET) { | 798 | if (likely(llc_backlog_type(skb) == LLC_PACKET)) { |
766 | if (llc->state > 1) /* not closed */ | 799 | if (likely(llc->state > 1)) /* not closed */ |
767 | rc = llc_conn_rcv(sk, skb); | 800 | rc = llc_conn_rcv(sk, skb); |
768 | else | 801 | else |
769 | goto out_kfree_skb; | 802 | goto out_kfree_skb; |
770 | } else if (llc_backlog_type(skb) == LLC_EVENT) { | 803 | } else if (llc_backlog_type(skb) == LLC_EVENT) { |
771 | /* timer expiration event */ | 804 | /* timer expiration event */ |
772 | if (llc->state > 1) /* not closed */ | 805 | if (likely(llc->state > 1)) /* not closed */ |
773 | rc = llc_conn_state_process(sk, skb); | 806 | rc = llc_conn_state_process(sk, skb); |
774 | else | 807 | else |
775 | goto out_kfree_skb; | 808 | goto out_kfree_skb; |
@@ -799,22 +832,22 @@ static void llc_sk_init(struct sock* sk) | |||
799 | llc->dec_step = llc->connect_step = 1; | 832 | llc->dec_step = llc->connect_step = 1; |
800 | 833 | ||
801 | init_timer(&llc->ack_timer.timer); | 834 | init_timer(&llc->ack_timer.timer); |
802 | llc->ack_timer.expire = LLC_ACK_TIME; | 835 | llc->ack_timer.expire = sysctl_llc2_ack_timeout; |
803 | llc->ack_timer.timer.data = (unsigned long)sk; | 836 | llc->ack_timer.timer.data = (unsigned long)sk; |
804 | llc->ack_timer.timer.function = llc_conn_ack_tmr_cb; | 837 | llc->ack_timer.timer.function = llc_conn_ack_tmr_cb; |
805 | 838 | ||
806 | init_timer(&llc->pf_cycle_timer.timer); | 839 | init_timer(&llc->pf_cycle_timer.timer); |
807 | llc->pf_cycle_timer.expire = LLC_P_TIME; | 840 | llc->pf_cycle_timer.expire = sysctl_llc2_p_timeout; |
808 | llc->pf_cycle_timer.timer.data = (unsigned long)sk; | 841 | llc->pf_cycle_timer.timer.data = (unsigned long)sk; |
809 | llc->pf_cycle_timer.timer.function = llc_conn_pf_cycle_tmr_cb; | 842 | llc->pf_cycle_timer.timer.function = llc_conn_pf_cycle_tmr_cb; |
810 | 843 | ||
811 | init_timer(&llc->rej_sent_timer.timer); | 844 | init_timer(&llc->rej_sent_timer.timer); |
812 | llc->rej_sent_timer.expire = LLC_REJ_TIME; | 845 | llc->rej_sent_timer.expire = sysctl_llc2_rej_timeout; |
813 | llc->rej_sent_timer.timer.data = (unsigned long)sk; | 846 | llc->rej_sent_timer.timer.data = (unsigned long)sk; |
814 | llc->rej_sent_timer.timer.function = llc_conn_rej_tmr_cb; | 847 | llc->rej_sent_timer.timer.function = llc_conn_rej_tmr_cb; |
815 | 848 | ||
816 | init_timer(&llc->busy_state_timer.timer); | 849 | init_timer(&llc->busy_state_timer.timer); |
817 | llc->busy_state_timer.expire = LLC_BUSY_TIME; | 850 | llc->busy_state_timer.expire = sysctl_llc2_busy_timeout; |
818 | llc->busy_state_timer.timer.data = (unsigned long)sk; | 851 | llc->busy_state_timer.timer.data = (unsigned long)sk; |
819 | llc->busy_state_timer.timer.function = llc_conn_busy_tmr_cb; | 852 | llc->busy_state_timer.timer.function = llc_conn_busy_tmr_cb; |
820 | 853 | ||
@@ -834,7 +867,8 @@ static void llc_sk_init(struct sock* sk) | |||
834 | * Allocates a LLC sock and initializes it. Returns the new LLC sock | 867 | * Allocates a LLC sock and initializes it. Returns the new LLC sock |
835 | * or %NULL if there's no memory available for one | 868 | * or %NULL if there's no memory available for one |
836 | */ | 869 | */ |
837 | struct sock *llc_sk_alloc(int family, int priority, struct proto *prot) | 870 | struct sock *llc_sk_alloc(int family, unsigned int __nocast priority, |
871 | struct proto *prot) | ||
838 | { | 872 | { |
839 | struct sock *sk = sk_alloc(family, priority, prot, 1); | 873 | struct sock *sk = sk_alloc(family, priority, prot, 1); |
840 | 874 | ||
diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c index 9727455bf0e7..ab0fcd32fd84 100644 --- a/net/llc/llc_core.c +++ b/net/llc/llc_core.c | |||
@@ -40,6 +40,7 @@ static struct llc_sap *llc_sap_alloc(void) | |||
40 | sap->state = LLC_SAP_STATE_ACTIVE; | 40 | sap->state = LLC_SAP_STATE_ACTIVE; |
41 | memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN); | 41 | memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN); |
42 | rwlock_init(&sap->sk_list.lock); | 42 | rwlock_init(&sap->sk_list.lock); |
43 | atomic_set(&sap->refcnt, 1); | ||
43 | } | 44 | } |
44 | return sap; | 45 | return sap; |
45 | } | 46 | } |
@@ -52,9 +53,7 @@ static struct llc_sap *llc_sap_alloc(void) | |||
52 | */ | 53 | */ |
53 | static void llc_add_sap(struct llc_sap *sap) | 54 | static void llc_add_sap(struct llc_sap *sap) |
54 | { | 55 | { |
55 | write_lock_bh(&llc_sap_list_lock); | ||
56 | list_add_tail(&sap->node, &llc_sap_list); | 56 | list_add_tail(&sap->node, &llc_sap_list); |
57 | write_unlock_bh(&llc_sap_list_lock); | ||
58 | } | 57 | } |
59 | 58 | ||
60 | /** | 59 | /** |
@@ -70,11 +69,25 @@ static void llc_del_sap(struct llc_sap *sap) | |||
70 | write_unlock_bh(&llc_sap_list_lock); | 69 | write_unlock_bh(&llc_sap_list_lock); |
71 | } | 70 | } |
72 | 71 | ||
72 | static struct llc_sap *__llc_sap_find(unsigned char sap_value) | ||
73 | { | ||
74 | struct llc_sap* sap; | ||
75 | |||
76 | list_for_each_entry(sap, &llc_sap_list, node) | ||
77 | if (sap->laddr.lsap == sap_value) | ||
78 | goto out; | ||
79 | sap = NULL; | ||
80 | out: | ||
81 | return sap; | ||
82 | } | ||
83 | |||
73 | /** | 84 | /** |
74 | * llc_sap_find - searchs a SAP in station | 85 | * llc_sap_find - searchs a SAP in station |
75 | * @sap_value: sap to be found | 86 | * @sap_value: sap to be found |
76 | * | 87 | * |
77 | * Searchs for a sap in the sap list of the LLC's station upon the sap ID. | 88 | * Searchs for a sap in the sap list of the LLC's station upon the sap ID. |
89 | * If the sap is found it will be refcounted and the user will have to do | ||
90 | * a llc_sap_put after use. | ||
78 | * Returns the sap or %NULL if not found. | 91 | * Returns the sap or %NULL if not found. |
79 | */ | 92 | */ |
80 | struct llc_sap *llc_sap_find(unsigned char sap_value) | 93 | struct llc_sap *llc_sap_find(unsigned char sap_value) |
@@ -82,11 +95,9 @@ struct llc_sap *llc_sap_find(unsigned char sap_value) | |||
82 | struct llc_sap* sap; | 95 | struct llc_sap* sap; |
83 | 96 | ||
84 | read_lock_bh(&llc_sap_list_lock); | 97 | read_lock_bh(&llc_sap_list_lock); |
85 | list_for_each_entry(sap, &llc_sap_list, node) | 98 | sap = __llc_sap_find(sap_value); |
86 | if (sap->laddr.lsap == sap_value) | 99 | if (sap) |
87 | goto out; | 100 | llc_sap_hold(sap); |
88 | sap = NULL; | ||
89 | out: | ||
90 | read_unlock_bh(&llc_sap_list_lock); | 101 | read_unlock_bh(&llc_sap_list_lock); |
91 | return sap; | 102 | return sap; |
92 | } | 103 | } |
@@ -106,19 +117,20 @@ struct llc_sap *llc_sap_open(unsigned char lsap, | |||
106 | struct packet_type *pt, | 117 | struct packet_type *pt, |
107 | struct net_device *orig_dev)) | 118 | struct net_device *orig_dev)) |
108 | { | 119 | { |
109 | struct llc_sap *sap = llc_sap_find(lsap); | 120 | struct llc_sap *sap = NULL; |
110 | 121 | ||
111 | if (sap) { /* SAP already exists */ | 122 | write_lock_bh(&llc_sap_list_lock); |
112 | sap = NULL; | 123 | if (__llc_sap_find(lsap)) /* SAP already exists */ |
113 | goto out; | 124 | goto out; |
114 | } | ||
115 | sap = llc_sap_alloc(); | 125 | sap = llc_sap_alloc(); |
116 | if (!sap) | 126 | if (!sap) |
117 | goto out; | 127 | goto out; |
118 | sap->laddr.lsap = lsap; | 128 | sap->laddr.lsap = lsap; |
119 | sap->rcv_func = func; | 129 | sap->rcv_func = func; |
130 | llc_sap_hold(sap); | ||
120 | llc_add_sap(sap); | 131 | llc_add_sap(sap); |
121 | out: | 132 | out: |
133 | write_unlock_bh(&llc_sap_list_lock); | ||
122 | return sap; | 134 | return sap; |
123 | } | 135 | } |
124 | 136 | ||
diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c index 0f84f66018e4..ba90f7f0801a 100644 --- a/net/llc/llc_if.c +++ b/net/llc/llc_if.c | |||
@@ -47,14 +47,11 @@ int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb) | |||
47 | int rc = -ECONNABORTED; | 47 | int rc = -ECONNABORTED; |
48 | struct llc_sock *llc = llc_sk(sk); | 48 | struct llc_sock *llc = llc_sk(sk); |
49 | 49 | ||
50 | if (llc->state == LLC_CONN_STATE_ADM) | 50 | if (unlikely(llc->state == LLC_CONN_STATE_ADM)) |
51 | goto out; | 51 | goto out; |
52 | rc = -EBUSY; | 52 | rc = -EBUSY; |
53 | if (llc_data_accept_state(llc->state)) { /* data_conn_refuse */ | 53 | if (unlikely(llc_data_accept_state(llc->state) || /* data_conn_refuse */ |
54 | llc->failed_data_req = 1; | 54 | llc->p_flag)) { |
55 | goto out; | ||
56 | } | ||
57 | if (llc->p_flag) { | ||
58 | llc->failed_data_req = 1; | 55 | llc->failed_data_req = 1; |
59 | goto out; | 56 | goto out; |
60 | } | 57 | } |
@@ -110,6 +107,7 @@ int llc_establish_connection(struct sock *sk, u8 *lmac, u8 *dmac, u8 dsap) | |||
110 | ev->type = LLC_CONN_EV_TYPE_PRIM; | 107 | ev->type = LLC_CONN_EV_TYPE_PRIM; |
111 | ev->prim = LLC_CONN_PRIM; | 108 | ev->prim = LLC_CONN_PRIM; |
112 | ev->prim_type = LLC_PRIM_TYPE_REQ; | 109 | ev->prim_type = LLC_PRIM_TYPE_REQ; |
110 | skb_set_owner_w(skb, sk); | ||
113 | rc = llc_conn_state_process(sk, skb); | 111 | rc = llc_conn_state_process(sk, skb); |
114 | } | 112 | } |
115 | out_put: | 113 | out_put: |
@@ -144,6 +142,7 @@ int llc_send_disc(struct sock *sk) | |||
144 | skb = alloc_skb(0, GFP_ATOMIC); | 142 | skb = alloc_skb(0, GFP_ATOMIC); |
145 | if (!skb) | 143 | if (!skb) |
146 | goto out; | 144 | goto out; |
145 | skb_set_owner_w(skb, sk); | ||
147 | sk->sk_state = TCP_CLOSING; | 146 | sk->sk_state = TCP_CLOSING; |
148 | ev = llc_conn_ev(skb); | 147 | ev = llc_conn_ev(skb); |
149 | ev->type = LLC_CONN_EV_TYPE_PRIM; | 148 | ev->type = LLC_CONN_EV_TYPE_PRIM; |
diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c index 13b46240b7a1..8f3addf0724c 100644 --- a/net/llc/llc_input.c +++ b/net/llc/llc_input.c | |||
@@ -99,15 +99,19 @@ out: | |||
99 | static inline int llc_fixup_skb(struct sk_buff *skb) | 99 | static inline int llc_fixup_skb(struct sk_buff *skb) |
100 | { | 100 | { |
101 | u8 llc_len = 2; | 101 | u8 llc_len = 2; |
102 | struct llc_pdu_sn *pdu; | 102 | struct llc_pdu_un *pdu; |
103 | 103 | ||
104 | if (!pskb_may_pull(skb, sizeof(*pdu))) | 104 | if (unlikely(!pskb_may_pull(skb, sizeof(*pdu)))) |
105 | return 0; | 105 | return 0; |
106 | 106 | ||
107 | pdu = (struct llc_pdu_sn *)skb->data; | 107 | pdu = (struct llc_pdu_un *)skb->data; |
108 | if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) == LLC_PDU_TYPE_U) | 108 | if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) == LLC_PDU_TYPE_U) |
109 | llc_len = 1; | 109 | llc_len = 1; |
110 | llc_len += 2; | 110 | llc_len += 2; |
111 | |||
112 | if (unlikely(!pskb_may_pull(skb, llc_len))) | ||
113 | return 0; | ||
114 | |||
111 | skb->h.raw += llc_len; | 115 | skb->h.raw += llc_len; |
112 | skb_pull(skb, llc_len); | 116 | skb_pull(skb, llc_len); |
113 | if (skb->protocol == htons(ETH_P_802_2)) { | 117 | if (skb->protocol == htons(ETH_P_802_2)) { |
@@ -166,17 +170,22 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, | |||
166 | */ | 170 | */ |
167 | if (sap->rcv_func) { | 171 | if (sap->rcv_func) { |
168 | sap->rcv_func(skb, dev, pt, orig_dev); | 172 | sap->rcv_func(skb, dev, pt, orig_dev); |
169 | goto out; | 173 | goto out_put; |
170 | } | 174 | } |
171 | dest = llc_pdu_type(skb); | 175 | dest = llc_pdu_type(skb); |
172 | if (unlikely(!dest || !llc_type_handlers[dest - 1])) | 176 | if (unlikely(!dest || !llc_type_handlers[dest - 1])) |
173 | goto drop; | 177 | goto drop_put; |
174 | llc_type_handlers[dest - 1](sap, skb); | 178 | llc_type_handlers[dest - 1](sap, skb); |
179 | out_put: | ||
180 | llc_sap_put(sap); | ||
175 | out: | 181 | out: |
176 | return 0; | 182 | return 0; |
177 | drop: | 183 | drop: |
178 | kfree_skb(skb); | 184 | kfree_skb(skb); |
179 | goto out; | 185 | goto out; |
186 | drop_put: | ||
187 | kfree_skb(skb); | ||
188 | goto out_put; | ||
180 | handle_station: | 189 | handle_station: |
181 | if (!llc_station_handler) | 190 | if (!llc_station_handler) |
182 | goto drop; | 191 | goto drop; |
diff --git a/net/llc/llc_output.c b/net/llc/llc_output.c index ab5784cf163e..b4d55b6abb67 100644 --- a/net/llc/llc_output.c +++ b/net/llc/llc_output.c | |||
@@ -98,7 +98,7 @@ int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb, | |||
98 | dsap, LLC_PDU_CMD); | 98 | dsap, LLC_PDU_CMD); |
99 | llc_pdu_init_as_ui_cmd(skb); | 99 | llc_pdu_init_as_ui_cmd(skb); |
100 | rc = llc_mac_hdr_init(skb, skb->dev->dev_addr, dmac); | 100 | rc = llc_mac_hdr_init(skb, skb->dev->dev_addr, dmac); |
101 | if (!rc) | 101 | if (likely(!rc)) |
102 | rc = dev_queue_xmit(skb); | 102 | rc = dev_queue_xmit(skb); |
103 | return rc; | 103 | return rc; |
104 | } | 104 | } |
diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c index 36e8db3fa1a2..bd531cb235a7 100644 --- a/net/llc/llc_proc.c +++ b/net/llc/llc_proc.c | |||
@@ -134,7 +134,7 @@ static int llc_seq_socket_show(struct seq_file *seq, void *v) | |||
134 | llc_ui_format_mac(seq, llc->daddr.mac); | 134 | llc_ui_format_mac(seq, llc->daddr.mac); |
135 | seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap, | 135 | seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap, |
136 | atomic_read(&sk->sk_wmem_alloc), | 136 | atomic_read(&sk->sk_wmem_alloc), |
137 | atomic_read(&sk->sk_rmem_alloc), | 137 | atomic_read(&sk->sk_rmem_alloc) - llc->copied_seq, |
138 | sk->sk_state, | 138 | sk->sk_state, |
139 | sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : -1, | 139 | sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : -1, |
140 | llc->link); | 140 | llc->link); |
diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c index ed8ba7de6122..bb3580fb8cfe 100644 --- a/net/llc/llc_s_ac.c +++ b/net/llc/llc_s_ac.c | |||
@@ -58,7 +58,7 @@ int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb) | |||
58 | ev->daddr.lsap, LLC_PDU_CMD); | 58 | ev->daddr.lsap, LLC_PDU_CMD); |
59 | llc_pdu_init_as_ui_cmd(skb); | 59 | llc_pdu_init_as_ui_cmd(skb); |
60 | rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); | 60 | rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); |
61 | if (!rc) | 61 | if (likely(!rc)) |
62 | rc = dev_queue_xmit(skb); | 62 | rc = dev_queue_xmit(skb); |
63 | return rc; | 63 | return rc; |
64 | } | 64 | } |
@@ -81,7 +81,7 @@ int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb) | |||
81 | ev->daddr.lsap, LLC_PDU_CMD); | 81 | ev->daddr.lsap, LLC_PDU_CMD); |
82 | llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0); | 82 | llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0); |
83 | rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); | 83 | rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); |
84 | if (!rc) | 84 | if (likely(!rc)) |
85 | rc = dev_queue_xmit(skb); | 85 | rc = dev_queue_xmit(skb); |
86 | return rc; | 86 | return rc; |
87 | } | 87 | } |
@@ -103,15 +103,14 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb) | |||
103 | llc_pdu_decode_sa(skb, mac_da); | 103 | llc_pdu_decode_sa(skb, mac_da); |
104 | llc_pdu_decode_da(skb, mac_sa); | 104 | llc_pdu_decode_da(skb, mac_sa); |
105 | llc_pdu_decode_ssap(skb, &dsap); | 105 | llc_pdu_decode_ssap(skb, &dsap); |
106 | nskb = llc_alloc_frame(); | 106 | nskb = llc_alloc_frame(NULL, skb->dev); |
107 | if (!nskb) | 107 | if (!nskb) |
108 | goto out; | 108 | goto out; |
109 | nskb->dev = skb->dev; | ||
110 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, | 109 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, |
111 | LLC_PDU_RSP); | 110 | LLC_PDU_RSP); |
112 | llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 0); | 111 | llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 0); |
113 | rc = llc_mac_hdr_init(nskb, mac_sa, mac_da); | 112 | rc = llc_mac_hdr_init(nskb, mac_sa, mac_da); |
114 | if (!rc) | 113 | if (likely(!rc)) |
115 | rc = dev_queue_xmit(nskb); | 114 | rc = dev_queue_xmit(nskb); |
116 | out: | 115 | out: |
117 | return rc; | 116 | return rc; |
@@ -135,7 +134,7 @@ int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb) | |||
135 | ev->daddr.lsap, LLC_PDU_CMD); | 134 | ev->daddr.lsap, LLC_PDU_CMD); |
136 | llc_pdu_init_as_test_cmd(skb); | 135 | llc_pdu_init_as_test_cmd(skb); |
137 | rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); | 136 | rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); |
138 | if (!rc) | 137 | if (likely(!rc)) |
139 | rc = dev_queue_xmit(skb); | 138 | rc = dev_queue_xmit(skb); |
140 | return rc; | 139 | return rc; |
141 | } | 140 | } |
@@ -149,15 +148,14 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb) | |||
149 | llc_pdu_decode_sa(skb, mac_da); | 148 | llc_pdu_decode_sa(skb, mac_da); |
150 | llc_pdu_decode_da(skb, mac_sa); | 149 | llc_pdu_decode_da(skb, mac_sa); |
151 | llc_pdu_decode_ssap(skb, &dsap); | 150 | llc_pdu_decode_ssap(skb, &dsap); |
152 | nskb = llc_alloc_frame(); | 151 | nskb = llc_alloc_frame(NULL, skb->dev); |
153 | if (!nskb) | 152 | if (!nskb) |
154 | goto out; | 153 | goto out; |
155 | nskb->dev = skb->dev; | ||
156 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, | 154 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, |
157 | LLC_PDU_RSP); | 155 | LLC_PDU_RSP); |
158 | llc_pdu_init_as_test_rsp(nskb, skb); | 156 | llc_pdu_init_as_test_rsp(nskb, skb); |
159 | rc = llc_mac_hdr_init(nskb, mac_sa, mac_da); | 157 | rc = llc_mac_hdr_init(nskb, mac_sa, mac_da); |
160 | if (!rc) | 158 | if (likely(!rc)) |
161 | rc = dev_queue_xmit(nskb); | 159 | rc = dev_queue_xmit(nskb); |
162 | out: | 160 | out: |
163 | return rc; | 161 | return rc; |
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index 34228ef14985..4029ceee9b91 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c | |||
@@ -26,11 +26,12 @@ | |||
26 | 26 | ||
27 | /** | 27 | /** |
28 | * llc_alloc_frame - allocates sk_buff for frame | 28 | * llc_alloc_frame - allocates sk_buff for frame |
29 | * @dev: network device this skb will be sent over | ||
29 | * | 30 | * |
30 | * Allocates an sk_buff for frame and initializes sk_buff fields. | 31 | * Allocates an sk_buff for frame and initializes sk_buff fields. |
31 | * Returns allocated skb or %NULL when out of memory. | 32 | * Returns allocated skb or %NULL when out of memory. |
32 | */ | 33 | */ |
33 | struct sk_buff *llc_alloc_frame(void) | 34 | struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev) |
34 | { | 35 | { |
35 | struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC); | 36 | struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC); |
36 | 37 | ||
@@ -38,18 +39,23 @@ struct sk_buff *llc_alloc_frame(void) | |||
38 | skb_reserve(skb, 50); | 39 | skb_reserve(skb, 50); |
39 | skb->nh.raw = skb->h.raw = skb->data; | 40 | skb->nh.raw = skb->h.raw = skb->data; |
40 | skb->protocol = htons(ETH_P_802_2); | 41 | skb->protocol = htons(ETH_P_802_2); |
41 | skb->dev = dev_base->next; | 42 | skb->dev = dev; |
42 | skb->mac.raw = skb->head; | 43 | skb->mac.raw = skb->head; |
44 | if (sk != NULL) | ||
45 | skb_set_owner_w(skb, sk); | ||
43 | } | 46 | } |
44 | return skb; | 47 | return skb; |
45 | } | 48 | } |
46 | 49 | ||
47 | void llc_save_primitive(struct sk_buff* skb, u8 prim) | 50 | void llc_save_primitive(struct sock *sk, struct sk_buff* skb, u8 prim) |
48 | { | 51 | { |
49 | struct sockaddr_llc *addr = llc_ui_skb_cb(skb); | 52 | struct sockaddr_llc *addr; |
50 | 53 | ||
54 | if (skb->sk->sk_type == SOCK_STREAM) /* See UNIX98 */ | ||
55 | return; | ||
51 | /* save primitive for use by the user. */ | 56 | /* save primitive for use by the user. */ |
52 | addr->sllc_family = skb->sk->sk_family; | 57 | addr = llc_ui_skb_cb(skb); |
58 | addr->sllc_family = sk->sk_family; | ||
53 | addr->sllc_arphrd = skb->dev->type; | 59 | addr->sllc_arphrd = skb->dev->type; |
54 | addr->sllc_test = prim == LLC_TEST_PRIM; | 60 | addr->sllc_test = prim == LLC_TEST_PRIM; |
55 | addr->sllc_xid = prim == LLC_XID_PRIM; | 61 | addr->sllc_xid = prim == LLC_XID_PRIM; |
@@ -189,7 +195,7 @@ static void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb) | |||
189 | if (skb->sk->sk_state == TCP_LISTEN) | 195 | if (skb->sk->sk_state == TCP_LISTEN) |
190 | kfree_skb(skb); | 196 | kfree_skb(skb); |
191 | else { | 197 | else { |
192 | llc_save_primitive(skb, ev->prim); | 198 | llc_save_primitive(skb->sk, skb, ev->prim); |
193 | 199 | ||
194 | /* queue skb to the user. */ | 200 | /* queue skb to the user. */ |
195 | if (sock_queue_rcv_skb(skb->sk, skb)) | 201 | if (sock_queue_rcv_skb(skb->sk, skb)) |
@@ -308,7 +314,7 @@ void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb) | |||
308 | 314 | ||
309 | sk = llc_lookup_dgram(sap, &laddr); | 315 | sk = llc_lookup_dgram(sap, &laddr); |
310 | if (sk) { | 316 | if (sk) { |
311 | skb->sk = sk; | 317 | skb_set_owner_r(skb, sk); |
312 | llc_sap_rcv(sap, skb); | 318 | llc_sap_rcv(sap, skb); |
313 | sock_put(sk); | 319 | sock_put(sk); |
314 | } else | 320 | } else |
diff --git a/net/llc/llc_station.c b/net/llc/llc_station.c index 8fe48a24bad5..f37dbf8ef126 100644 --- a/net/llc/llc_station.c +++ b/net/llc/llc_station.c | |||
@@ -50,6 +50,10 @@ struct llc_station { | |||
50 | struct sk_buff_head mac_pdu_q; | 50 | struct sk_buff_head mac_pdu_q; |
51 | }; | 51 | }; |
52 | 52 | ||
53 | #define LLC_STATION_ACK_TIME (3 * HZ) | ||
54 | |||
55 | int sysctl_llc_station_ack_timeout = LLC_STATION_ACK_TIME; | ||
56 | |||
53 | /* Types of events (possible values in 'ev->type') */ | 57 | /* Types of events (possible values in 'ev->type') */ |
54 | #define LLC_STATION_EV_TYPE_SIMPLE 1 | 58 | #define LLC_STATION_EV_TYPE_SIMPLE 1 |
55 | #define LLC_STATION_EV_TYPE_CONDITION 2 | 59 | #define LLC_STATION_EV_TYPE_CONDITION 2 |
@@ -218,7 +222,8 @@ static void llc_station_send_pdu(struct sk_buff *skb) | |||
218 | 222 | ||
219 | static int llc_station_ac_start_ack_timer(struct sk_buff *skb) | 223 | static int llc_station_ac_start_ack_timer(struct sk_buff *skb) |
220 | { | 224 | { |
221 | mod_timer(&llc_main_station.ack_timer, jiffies + LLC_ACK_TIME * HZ); | 225 | mod_timer(&llc_main_station.ack_timer, |
226 | jiffies + sysctl_llc_station_ack_timeout); | ||
222 | return 0; | 227 | return 0; |
223 | } | 228 | } |
224 | 229 | ||
@@ -249,14 +254,14 @@ static int llc_station_ac_inc_xid_r_cnt_by_1(struct sk_buff *skb) | |||
249 | static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb) | 254 | static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb) |
250 | { | 255 | { |
251 | int rc = 1; | 256 | int rc = 1; |
252 | struct sk_buff *nskb = llc_alloc_frame(); | 257 | struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev); |
253 | 258 | ||
254 | if (!nskb) | 259 | if (!nskb) |
255 | goto out; | 260 | goto out; |
256 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD); | 261 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD); |
257 | llc_pdu_init_as_xid_cmd(nskb, LLC_XID_NULL_CLASS_2, 127); | 262 | llc_pdu_init_as_xid_cmd(nskb, LLC_XID_NULL_CLASS_2, 127); |
258 | rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, llc_station_mac_sa); | 263 | rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, llc_station_mac_sa); |
259 | if (rc) | 264 | if (unlikely(rc)) |
260 | goto free; | 265 | goto free; |
261 | llc_station_send_pdu(nskb); | 266 | llc_station_send_pdu(nskb); |
262 | out: | 267 | out: |
@@ -270,18 +275,17 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb) | |||
270 | { | 275 | { |
271 | u8 mac_da[ETH_ALEN], dsap; | 276 | u8 mac_da[ETH_ALEN], dsap; |
272 | int rc = 1; | 277 | int rc = 1; |
273 | struct sk_buff* nskb = llc_alloc_frame(); | 278 | struct sk_buff* nskb = llc_alloc_frame(NULL, skb->dev); |
274 | 279 | ||
275 | if (!nskb) | 280 | if (!nskb) |
276 | goto out; | 281 | goto out; |
277 | rc = 0; | 282 | rc = 0; |
278 | nskb->dev = skb->dev; | ||
279 | llc_pdu_decode_sa(skb, mac_da); | 283 | llc_pdu_decode_sa(skb, mac_da); |
280 | llc_pdu_decode_ssap(skb, &dsap); | 284 | llc_pdu_decode_ssap(skb, &dsap); |
281 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP); | 285 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP); |
282 | llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127); | 286 | llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127); |
283 | rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da); | 287 | rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da); |
284 | if (rc) | 288 | if (unlikely(rc)) |
285 | goto free; | 289 | goto free; |
286 | llc_station_send_pdu(nskb); | 290 | llc_station_send_pdu(nskb); |
287 | out: | 291 | out: |
@@ -295,18 +299,17 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb) | |||
295 | { | 299 | { |
296 | u8 mac_da[ETH_ALEN], dsap; | 300 | u8 mac_da[ETH_ALEN], dsap; |
297 | int rc = 1; | 301 | int rc = 1; |
298 | struct sk_buff *nskb = llc_alloc_frame(); | 302 | struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev); |
299 | 303 | ||
300 | if (!nskb) | 304 | if (!nskb) |
301 | goto out; | 305 | goto out; |
302 | rc = 0; | 306 | rc = 0; |
303 | nskb->dev = skb->dev; | ||
304 | llc_pdu_decode_sa(skb, mac_da); | 307 | llc_pdu_decode_sa(skb, mac_da); |
305 | llc_pdu_decode_ssap(skb, &dsap); | 308 | llc_pdu_decode_ssap(skb, &dsap); |
306 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP); | 309 | llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP); |
307 | llc_pdu_init_as_test_rsp(nskb, skb); | 310 | llc_pdu_init_as_test_rsp(nskb, skb); |
308 | rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da); | 311 | rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da); |
309 | if (rc) | 312 | if (unlikely(rc)) |
310 | goto free; | 313 | goto free; |
311 | llc_station_send_pdu(nskb); | 314 | llc_station_send_pdu(nskb); |
312 | out: | 315 | out: |
@@ -689,7 +692,8 @@ int __init llc_station_init(void) | |||
689 | init_timer(&llc_main_station.ack_timer); | 692 | init_timer(&llc_main_station.ack_timer); |
690 | llc_main_station.ack_timer.data = (unsigned long)&llc_main_station; | 693 | llc_main_station.ack_timer.data = (unsigned long)&llc_main_station; |
691 | llc_main_station.ack_timer.function = llc_station_ack_tmr_cb; | 694 | llc_main_station.ack_timer.function = llc_station_ack_tmr_cb; |
692 | 695 | llc_main_station.ack_timer.expires = jiffies + | |
696 | sysctl_llc_station_ack_timeout; | ||
693 | skb = alloc_skb(0, GFP_ATOMIC); | 697 | skb = alloc_skb(0, GFP_ATOMIC); |
694 | if (!skb) | 698 | if (!skb) |
695 | goto out; | 699 | goto out; |
@@ -697,7 +701,6 @@ int __init llc_station_init(void) | |||
697 | llc_set_station_handler(llc_station_rcv); | 701 | llc_set_station_handler(llc_station_rcv); |
698 | ev = llc_station_ev(skb); | 702 | ev = llc_station_ev(skb); |
699 | memset(ev, 0, sizeof(*ev)); | 703 | memset(ev, 0, sizeof(*ev)); |
700 | llc_main_station.ack_timer.expires = jiffies + 3 * HZ; | ||
701 | llc_main_station.maximum_retry = 1; | 704 | llc_main_station.maximum_retry = 1; |
702 | llc_main_station.state = LLC_STATION_STATE_DOWN; | 705 | llc_main_station.state = LLC_STATION_STATE_DOWN; |
703 | ev->type = LLC_STATION_EV_TYPE_SIMPLE; | 706 | ev->type = LLC_STATION_EV_TYPE_SIMPLE; |
diff --git a/net/llc/sysctl_net_llc.c b/net/llc/sysctl_net_llc.c new file mode 100644 index 000000000000..d1eaddb13633 --- /dev/null +++ b/net/llc/sysctl_net_llc.c | |||
@@ -0,0 +1,131 @@ | |||
1 | /* | ||
2 | * sysctl_net_llc.c: sysctl interface to LLC net subsystem. | ||
3 | * | ||
4 | * Arnaldo Carvalho de Melo <acme@conectiva.com.br> | ||
5 | */ | ||
6 | |||
7 | #include <linux/config.h> | ||
8 | #include <linux/mm.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/sysctl.h> | ||
11 | #include <net/llc.h> | ||
12 | |||
13 | #ifndef CONFIG_SYSCTL | ||
14 | #error This file should not be compiled without CONFIG_SYSCTL defined | ||
15 | #endif | ||
16 | |||
17 | static struct ctl_table llc2_timeout_table[] = { | ||
18 | { | ||
19 | .ctl_name = NET_LLC2_ACK_TIMEOUT, | ||
20 | .procname = "ack", | ||
21 | .data = &sysctl_llc2_ack_timeout, | ||
22 | .maxlen = sizeof(long), | ||
23 | .mode = 0644, | ||
24 | .proc_handler = &proc_dointvec_jiffies, | ||
25 | .strategy = &sysctl_jiffies, | ||
26 | }, | ||
27 | { | ||
28 | .ctl_name = NET_LLC2_BUSY_TIMEOUT, | ||
29 | .procname = "busy", | ||
30 | .data = &sysctl_llc2_busy_timeout, | ||
31 | .maxlen = sizeof(long), | ||
32 | .mode = 0644, | ||
33 | .proc_handler = &proc_dointvec_jiffies, | ||
34 | .strategy = &sysctl_jiffies, | ||
35 | }, | ||
36 | { | ||
37 | .ctl_name = NET_LLC2_P_TIMEOUT, | ||
38 | .procname = "p", | ||
39 | .data = &sysctl_llc2_p_timeout, | ||
40 | .maxlen = sizeof(long), | ||
41 | .mode = 0644, | ||
42 | .proc_handler = &proc_dointvec_jiffies, | ||
43 | .strategy = &sysctl_jiffies, | ||
44 | }, | ||
45 | { | ||
46 | .ctl_name = NET_LLC2_REJ_TIMEOUT, | ||
47 | .procname = "rej", | ||
48 | .data = &sysctl_llc2_rej_timeout, | ||
49 | .maxlen = sizeof(long), | ||
50 | .mode = 0644, | ||
51 | .proc_handler = &proc_dointvec_jiffies, | ||
52 | .strategy = &sysctl_jiffies, | ||
53 | }, | ||
54 | { 0 }, | ||
55 | }; | ||
56 | |||
57 | static struct ctl_table llc_station_table[] = { | ||
58 | { | ||
59 | .ctl_name = NET_LLC_STATION_ACK_TIMEOUT, | ||
60 | .procname = "ack_timeout", | ||
61 | .data = &sysctl_llc_station_ack_timeout, | ||
62 | .maxlen = sizeof(long), | ||
63 | .mode = 0644, | ||
64 | .proc_handler = &proc_dointvec_jiffies, | ||
65 | .strategy = &sysctl_jiffies, | ||
66 | }, | ||
67 | { 0 }, | ||
68 | }; | ||
69 | |||
70 | static struct ctl_table llc2_dir_timeout_table[] = { | ||
71 | { | ||
72 | .ctl_name = NET_LLC2, | ||
73 | .procname = "timeout", | ||
74 | .mode = 0555, | ||
75 | .child = llc2_timeout_table, | ||
76 | }, | ||
77 | { 0 }, | ||
78 | }; | ||
79 | |||
80 | static struct ctl_table llc_table[] = { | ||
81 | { | ||
82 | .ctl_name = NET_LLC2, | ||
83 | .procname = "llc2", | ||
84 | .mode = 0555, | ||
85 | .child = llc2_dir_timeout_table, | ||
86 | }, | ||
87 | { | ||
88 | .ctl_name = NET_LLC_STATION, | ||
89 | .procname = "station", | ||
90 | .mode = 0555, | ||
91 | .child = llc_station_table, | ||
92 | }, | ||
93 | { 0 }, | ||
94 | }; | ||
95 | |||
96 | static struct ctl_table llc_dir_table[] = { | ||
97 | { | ||
98 | .ctl_name = NET_LLC, | ||
99 | .procname = "llc", | ||
100 | .mode = 0555, | ||
101 | .child = llc_table, | ||
102 | }, | ||
103 | { 0 }, | ||
104 | }; | ||
105 | |||
106 | static struct ctl_table llc_root_table[] = { | ||
107 | { | ||
108 | .ctl_name = CTL_NET, | ||
109 | .procname = "net", | ||
110 | .mode = 0555, | ||
111 | .child = llc_dir_table, | ||
112 | }, | ||
113 | { 0 }, | ||
114 | }; | ||
115 | |||
116 | static struct ctl_table_header *llc_table_header; | ||
117 | |||
118 | int __init llc_sysctl_init(void) | ||
119 | { | ||
120 | llc_table_header = register_sysctl_table(llc_root_table, 1); | ||
121 | |||
122 | return llc_table_header ? 0 : -ENOMEM; | ||
123 | } | ||
124 | |||
125 | void llc_sysctl_exit(void) | ||
126 | { | ||
127 | if (llc_table_header) { | ||
128 | unregister_sysctl_table(llc_table_header); | ||
129 | llc_table_header = NULL; | ||
130 | } | ||
131 | } | ||
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index ee865d88183b..6a67a87384cc 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -761,12 +761,6 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
761 | if (dev->hard_header) { | 761 | if (dev->hard_header) { |
762 | int res; | 762 | int res; |
763 | err = -EINVAL; | 763 | err = -EINVAL; |
764 | if (saddr) { | ||
765 | if (saddr->sll_halen != dev->addr_len) | ||
766 | goto out_free; | ||
767 | if (saddr->sll_hatype != dev->type) | ||
768 | goto out_free; | ||
769 | } | ||
770 | res = dev->hard_header(skb, dev, ntohs(proto), addr, NULL, len); | 764 | res = dev->hard_header(skb, dev, ntohs(proto), addr, NULL, len); |
771 | if (sock->type != SOCK_DGRAM) { | 765 | if (sock->type != SOCK_DGRAM) { |
772 | skb->tail = skb->data; | 766 | skb->tail = skb->data; |
diff --git a/net/socket.c b/net/socket.c index f9264472377f..dbd1a6851edd 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -1700,7 +1700,9 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) | |||
1700 | struct socket *sock; | 1700 | struct socket *sock; |
1701 | char address[MAX_SOCK_ADDR]; | 1701 | char address[MAX_SOCK_ADDR]; |
1702 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; | 1702 | struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; |
1703 | unsigned char ctl[sizeof(struct cmsghdr) + 20]; /* 20 is size of ipv6_pktinfo */ | 1703 | unsigned char ctl[sizeof(struct cmsghdr) + 20] |
1704 | __attribute__ ((aligned (sizeof(__kernel_size_t)))); | ||
1705 | /* 20 is size of ipv6_pktinfo */ | ||
1704 | unsigned char *ctl_buf = ctl; | 1706 | unsigned char *ctl_buf = ctl; |
1705 | struct msghdr msg_sys; | 1707 | struct msghdr msg_sys; |
1706 | int err, ctl_len, iov_size, total_len; | 1708 | int err, ctl_len, iov_size, total_len; |
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index d8ee38aede26..f2ee673329a7 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
@@ -295,11 +295,13 @@ static int do_pcmcia_entry(const char *filename, | |||
295 | { | 295 | { |
296 | unsigned int i; | 296 | unsigned int i; |
297 | 297 | ||
298 | id->match_flags = TO_NATIVE(id->match_flags); | ||
298 | id->manf_id = TO_NATIVE(id->manf_id); | 299 | id->manf_id = TO_NATIVE(id->manf_id); |
299 | id->card_id = TO_NATIVE(id->card_id); | 300 | id->card_id = TO_NATIVE(id->card_id); |
300 | id->func_id = TO_NATIVE(id->func_id); | 301 | id->func_id = TO_NATIVE(id->func_id); |
301 | id->function = TO_NATIVE(id->function); | 302 | id->function = TO_NATIVE(id->function); |
302 | id->device_no = TO_NATIVE(id->device_no); | 303 | id->device_no = TO_NATIVE(id->device_no); |
304 | |||
303 | for (i=0; i<4; i++) { | 305 | for (i=0; i<4; i++) { |
304 | id->prod_id_hash[i] = TO_NATIVE(id->prod_id_hash[i]); | 306 | id->prod_id_hash[i] = TO_NATIVE(id->prod_id_hash[i]); |
305 | } | 307 | } |
diff --git a/security/keys/internal.h b/security/keys/internal.h index 46c8602661c9..db99ed434f3a 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h | |||
@@ -71,26 +71,26 @@ extern void keyring_publish_name(struct key *keyring); | |||
71 | 71 | ||
72 | extern int __key_link(struct key *keyring, struct key *key); | 72 | extern int __key_link(struct key *keyring, struct key *key); |
73 | 73 | ||
74 | extern struct key *__keyring_search_one(struct key *keyring, | 74 | extern key_ref_t __keyring_search_one(key_ref_t keyring_ref, |
75 | const struct key_type *type, | 75 | const struct key_type *type, |
76 | const char *description, | 76 | const char *description, |
77 | key_perm_t perm); | 77 | key_perm_t perm); |
78 | 78 | ||
79 | extern struct key *keyring_search_instkey(struct key *keyring, | 79 | extern struct key *keyring_search_instkey(struct key *keyring, |
80 | key_serial_t target_id); | 80 | key_serial_t target_id); |
81 | 81 | ||
82 | typedef int (*key_match_func_t)(const struct key *, const void *); | 82 | typedef int (*key_match_func_t)(const struct key *, const void *); |
83 | 83 | ||
84 | extern struct key *keyring_search_aux(struct key *keyring, | 84 | extern key_ref_t keyring_search_aux(key_ref_t keyring_ref, |
85 | struct task_struct *tsk, | 85 | struct task_struct *tsk, |
86 | struct key_type *type, | 86 | struct key_type *type, |
87 | const void *description, | 87 | const void *description, |
88 | key_match_func_t match); | 88 | key_match_func_t match); |
89 | 89 | ||
90 | extern struct key *search_process_keyrings(struct key_type *type, | 90 | extern key_ref_t search_process_keyrings(struct key_type *type, |
91 | const void *description, | 91 | const void *description, |
92 | key_match_func_t match, | 92 | key_match_func_t match, |
93 | struct task_struct *tsk); | 93 | struct task_struct *tsk); |
94 | 94 | ||
95 | extern struct key *find_keyring_by_name(const char *name, key_serial_t bound); | 95 | extern struct key *find_keyring_by_name(const char *name, key_serial_t bound); |
96 | 96 | ||
diff --git a/security/keys/key.c b/security/keys/key.c index fb89f9844465..2182be9e9309 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
@@ -693,14 +693,15 @@ void key_type_put(struct key_type *ktype) | |||
693 | * - the key has an incremented refcount | 693 | * - the key has an incremented refcount |
694 | * - we need to put the key if we get an error | 694 | * - we need to put the key if we get an error |
695 | */ | 695 | */ |
696 | static inline struct key *__key_update(struct key *key, const void *payload, | 696 | static inline key_ref_t __key_update(key_ref_t key_ref, |
697 | size_t plen) | 697 | const void *payload, size_t plen) |
698 | { | 698 | { |
699 | struct key *key = key_ref_to_ptr(key_ref); | ||
699 | int ret; | 700 | int ret; |
700 | 701 | ||
701 | /* need write permission on the key to update it */ | 702 | /* need write permission on the key to update it */ |
702 | ret = -EACCES; | 703 | ret = -EACCES; |
703 | if (!key_permission(key, KEY_WRITE)) | 704 | if (!key_permission(key_ref, KEY_WRITE)) |
704 | goto error; | 705 | goto error; |
705 | 706 | ||
706 | ret = -EEXIST; | 707 | ret = -EEXIST; |
@@ -719,12 +720,12 @@ static inline struct key *__key_update(struct key *key, const void *payload, | |||
719 | 720 | ||
720 | if (ret < 0) | 721 | if (ret < 0) |
721 | goto error; | 722 | goto error; |
722 | out: | 723 | out: |
723 | return key; | 724 | return key_ref; |
724 | 725 | ||
725 | error: | 726 | error: |
726 | key_put(key); | 727 | key_put(key); |
727 | key = ERR_PTR(ret); | 728 | key_ref = ERR_PTR(ret); |
728 | goto out; | 729 | goto out; |
729 | 730 | ||
730 | } /* end __key_update() */ | 731 | } /* end __key_update() */ |
@@ -734,52 +735,56 @@ static inline struct key *__key_update(struct key *key, const void *payload, | |||
734 | * search the specified keyring for a key of the same description; if one is | 735 | * search the specified keyring for a key of the same description; if one is |
735 | * found, update it, otherwise add a new one | 736 | * found, update it, otherwise add a new one |
736 | */ | 737 | */ |
737 | struct key *key_create_or_update(struct key *keyring, | 738 | key_ref_t key_create_or_update(key_ref_t keyring_ref, |
738 | const char *type, | 739 | const char *type, |
739 | const char *description, | 740 | const char *description, |
740 | const void *payload, | 741 | const void *payload, |
741 | size_t plen, | 742 | size_t plen, |
742 | int not_in_quota) | 743 | int not_in_quota) |
743 | { | 744 | { |
744 | struct key_type *ktype; | 745 | struct key_type *ktype; |
745 | struct key *key = NULL; | 746 | struct key *keyring, *key = NULL; |
746 | key_perm_t perm; | 747 | key_perm_t perm; |
748 | key_ref_t key_ref; | ||
747 | int ret; | 749 | int ret; |
748 | 750 | ||
749 | key_check(keyring); | ||
750 | |||
751 | /* look up the key type to see if it's one of the registered kernel | 751 | /* look up the key type to see if it's one of the registered kernel |
752 | * types */ | 752 | * types */ |
753 | ktype = key_type_lookup(type); | 753 | ktype = key_type_lookup(type); |
754 | if (IS_ERR(ktype)) { | 754 | if (IS_ERR(ktype)) { |
755 | key = ERR_PTR(-ENODEV); | 755 | key_ref = ERR_PTR(-ENODEV); |
756 | goto error; | 756 | goto error; |
757 | } | 757 | } |
758 | 758 | ||
759 | ret = -EINVAL; | 759 | key_ref = ERR_PTR(-EINVAL); |
760 | if (!ktype->match || !ktype->instantiate) | 760 | if (!ktype->match || !ktype->instantiate) |
761 | goto error_2; | 761 | goto error_2; |
762 | 762 | ||
763 | keyring = key_ref_to_ptr(keyring_ref); | ||
764 | |||
765 | key_check(keyring); | ||
766 | |||
767 | down_write(&keyring->sem); | ||
768 | |||
769 | /* if we're going to allocate a new key, we're going to have | ||
770 | * to modify the keyring */ | ||
771 | key_ref = ERR_PTR(-EACCES); | ||
772 | if (!key_permission(keyring_ref, KEY_WRITE)) | ||
773 | goto error_3; | ||
774 | |||
763 | /* search for an existing key of the same type and description in the | 775 | /* search for an existing key of the same type and description in the |
764 | * destination keyring | 776 | * destination keyring |
765 | */ | 777 | */ |
766 | down_write(&keyring->sem); | 778 | key_ref = __keyring_search_one(keyring_ref, ktype, description, 0); |
767 | 779 | if (!IS_ERR(key_ref)) | |
768 | key = __keyring_search_one(keyring, ktype, description, 0); | ||
769 | if (!IS_ERR(key)) | ||
770 | goto found_matching_key; | 780 | goto found_matching_key; |
771 | 781 | ||
772 | /* if we're going to allocate a new key, we're going to have to modify | ||
773 | * the keyring */ | ||
774 | ret = -EACCES; | ||
775 | if (!key_permission(keyring, KEY_WRITE)) | ||
776 | goto error_3; | ||
777 | |||
778 | /* decide on the permissions we want */ | 782 | /* decide on the permissions we want */ |
779 | perm = KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK; | 783 | perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK; |
784 | perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK; | ||
780 | 785 | ||
781 | if (ktype->read) | 786 | if (ktype->read) |
782 | perm |= KEY_USR_READ; | 787 | perm |= KEY_POS_READ | KEY_USR_READ; |
783 | 788 | ||
784 | if (ktype == &key_type_keyring || ktype->update) | 789 | if (ktype == &key_type_keyring || ktype->update) |
785 | perm |= KEY_USR_WRITE; | 790 | perm |= KEY_USR_WRITE; |
@@ -788,7 +793,7 @@ struct key *key_create_or_update(struct key *keyring, | |||
788 | key = key_alloc(ktype, description, current->fsuid, current->fsgid, | 793 | key = key_alloc(ktype, description, current->fsuid, current->fsgid, |
789 | perm, not_in_quota); | 794 | perm, not_in_quota); |
790 | if (IS_ERR(key)) { | 795 | if (IS_ERR(key)) { |
791 | ret = PTR_ERR(key); | 796 | key_ref = ERR_PTR(PTR_ERR(key)); |
792 | goto error_3; | 797 | goto error_3; |
793 | } | 798 | } |
794 | 799 | ||
@@ -796,15 +801,18 @@ struct key *key_create_or_update(struct key *keyring, | |||
796 | ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL); | 801 | ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL); |
797 | if (ret < 0) { | 802 | if (ret < 0) { |
798 | key_put(key); | 803 | key_put(key); |
799 | key = ERR_PTR(ret); | 804 | key_ref = ERR_PTR(ret); |
805 | goto error_3; | ||
800 | } | 806 | } |
801 | 807 | ||
808 | key_ref = make_key_ref(key, is_key_possessed(keyring_ref)); | ||
809 | |||
802 | error_3: | 810 | error_3: |
803 | up_write(&keyring->sem); | 811 | up_write(&keyring->sem); |
804 | error_2: | 812 | error_2: |
805 | key_type_put(ktype); | 813 | key_type_put(ktype); |
806 | error: | 814 | error: |
807 | return key; | 815 | return key_ref; |
808 | 816 | ||
809 | found_matching_key: | 817 | found_matching_key: |
810 | /* we found a matching key, so we're going to try to update it | 818 | /* we found a matching key, so we're going to try to update it |
@@ -813,7 +821,7 @@ struct key *key_create_or_update(struct key *keyring, | |||
813 | up_write(&keyring->sem); | 821 | up_write(&keyring->sem); |
814 | key_type_put(ktype); | 822 | key_type_put(ktype); |
815 | 823 | ||
816 | key = __key_update(key, payload, plen); | 824 | key_ref = __key_update(key_ref, payload, plen); |
817 | goto error; | 825 | goto error; |
818 | 826 | ||
819 | } /* end key_create_or_update() */ | 827 | } /* end key_create_or_update() */ |
@@ -824,15 +832,16 @@ EXPORT_SYMBOL(key_create_or_update); | |||
824 | /* | 832 | /* |
825 | * update a key | 833 | * update a key |
826 | */ | 834 | */ |
827 | int key_update(struct key *key, const void *payload, size_t plen) | 835 | int key_update(key_ref_t key_ref, const void *payload, size_t plen) |
828 | { | 836 | { |
837 | struct key *key = key_ref_to_ptr(key_ref); | ||
829 | int ret; | 838 | int ret; |
830 | 839 | ||
831 | key_check(key); | 840 | key_check(key); |
832 | 841 | ||
833 | /* the key must be writable */ | 842 | /* the key must be writable */ |
834 | ret = -EACCES; | 843 | ret = -EACCES; |
835 | if (!key_permission(key, KEY_WRITE)) | 844 | if (!key_permission(key_ref, KEY_WRITE)) |
836 | goto error; | 845 | goto error; |
837 | 846 | ||
838 | /* attempt to update it if supported */ | 847 | /* attempt to update it if supported */ |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index a6516a64b297..4c670ee6acf9 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -34,7 +34,7 @@ asmlinkage long sys_add_key(const char __user *_type, | |||
34 | size_t plen, | 34 | size_t plen, |
35 | key_serial_t ringid) | 35 | key_serial_t ringid) |
36 | { | 36 | { |
37 | struct key *keyring, *key; | 37 | key_ref_t keyring_ref, key_ref; |
38 | char type[32], *description; | 38 | char type[32], *description; |
39 | void *payload; | 39 | void *payload; |
40 | long dlen, ret; | 40 | long dlen, ret; |
@@ -86,25 +86,25 @@ asmlinkage long sys_add_key(const char __user *_type, | |||
86 | } | 86 | } |
87 | 87 | ||
88 | /* find the target keyring (which must be writable) */ | 88 | /* find the target keyring (which must be writable) */ |
89 | keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); | 89 | keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); |
90 | if (IS_ERR(keyring)) { | 90 | if (IS_ERR(keyring_ref)) { |
91 | ret = PTR_ERR(keyring); | 91 | ret = PTR_ERR(keyring_ref); |
92 | goto error3; | 92 | goto error3; |
93 | } | 93 | } |
94 | 94 | ||
95 | /* create or update the requested key and add it to the target | 95 | /* create or update the requested key and add it to the target |
96 | * keyring */ | 96 | * keyring */ |
97 | key = key_create_or_update(keyring, type, description, | 97 | key_ref = key_create_or_update(keyring_ref, type, description, |
98 | payload, plen, 0); | 98 | payload, plen, 0); |
99 | if (!IS_ERR(key)) { | 99 | if (!IS_ERR(key_ref)) { |
100 | ret = key->serial; | 100 | ret = key_ref_to_ptr(key_ref)->serial; |
101 | key_put(key); | 101 | key_ref_put(key_ref); |
102 | } | 102 | } |
103 | else { | 103 | else { |
104 | ret = PTR_ERR(key); | 104 | ret = PTR_ERR(key_ref); |
105 | } | 105 | } |
106 | 106 | ||
107 | key_put(keyring); | 107 | key_ref_put(keyring_ref); |
108 | error3: | 108 | error3: |
109 | kfree(payload); | 109 | kfree(payload); |
110 | error2: | 110 | error2: |
@@ -131,7 +131,8 @@ asmlinkage long sys_request_key(const char __user *_type, | |||
131 | key_serial_t destringid) | 131 | key_serial_t destringid) |
132 | { | 132 | { |
133 | struct key_type *ktype; | 133 | struct key_type *ktype; |
134 | struct key *key, *dest; | 134 | struct key *key; |
135 | key_ref_t dest_ref; | ||
135 | char type[32], *description, *callout_info; | 136 | char type[32], *description, *callout_info; |
136 | long dlen, ret; | 137 | long dlen, ret; |
137 | 138 | ||
@@ -187,11 +188,11 @@ asmlinkage long sys_request_key(const char __user *_type, | |||
187 | } | 188 | } |
188 | 189 | ||
189 | /* get the destination keyring if specified */ | 190 | /* get the destination keyring if specified */ |
190 | dest = NULL; | 191 | dest_ref = NULL; |
191 | if (destringid) { | 192 | if (destringid) { |
192 | dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE); | 193 | dest_ref = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE); |
193 | if (IS_ERR(dest)) { | 194 | if (IS_ERR(dest_ref)) { |
194 | ret = PTR_ERR(dest); | 195 | ret = PTR_ERR(dest_ref); |
195 | goto error3; | 196 | goto error3; |
196 | } | 197 | } |
197 | } | 198 | } |
@@ -204,7 +205,8 @@ asmlinkage long sys_request_key(const char __user *_type, | |||
204 | } | 205 | } |
205 | 206 | ||
206 | /* do the search */ | 207 | /* do the search */ |
207 | key = request_key_and_link(ktype, description, callout_info, dest); | 208 | key = request_key_and_link(ktype, description, callout_info, |
209 | key_ref_to_ptr(dest_ref)); | ||
208 | if (IS_ERR(key)) { | 210 | if (IS_ERR(key)) { |
209 | ret = PTR_ERR(key); | 211 | ret = PTR_ERR(key); |
210 | goto error5; | 212 | goto error5; |
@@ -216,7 +218,7 @@ asmlinkage long sys_request_key(const char __user *_type, | |||
216 | error5: | 218 | error5: |
217 | key_type_put(ktype); | 219 | key_type_put(ktype); |
218 | error4: | 220 | error4: |
219 | key_put(dest); | 221 | key_ref_put(dest_ref); |
220 | error3: | 222 | error3: |
221 | kfree(callout_info); | 223 | kfree(callout_info); |
222 | error2: | 224 | error2: |
@@ -234,17 +236,17 @@ asmlinkage long sys_request_key(const char __user *_type, | |||
234 | */ | 236 | */ |
235 | long keyctl_get_keyring_ID(key_serial_t id, int create) | 237 | long keyctl_get_keyring_ID(key_serial_t id, int create) |
236 | { | 238 | { |
237 | struct key *key; | 239 | key_ref_t key_ref; |
238 | long ret; | 240 | long ret; |
239 | 241 | ||
240 | key = lookup_user_key(NULL, id, create, 0, KEY_SEARCH); | 242 | key_ref = lookup_user_key(NULL, id, create, 0, KEY_SEARCH); |
241 | if (IS_ERR(key)) { | 243 | if (IS_ERR(key_ref)) { |
242 | ret = PTR_ERR(key); | 244 | ret = PTR_ERR(key_ref); |
243 | goto error; | 245 | goto error; |
244 | } | 246 | } |
245 | 247 | ||
246 | ret = key->serial; | 248 | ret = key_ref_to_ptr(key_ref)->serial; |
247 | key_put(key); | 249 | key_ref_put(key_ref); |
248 | error: | 250 | error: |
249 | return ret; | 251 | return ret; |
250 | 252 | ||
@@ -302,7 +304,7 @@ long keyctl_update_key(key_serial_t id, | |||
302 | const void __user *_payload, | 304 | const void __user *_payload, |
303 | size_t plen) | 305 | size_t plen) |
304 | { | 306 | { |
305 | struct key *key; | 307 | key_ref_t key_ref; |
306 | void *payload; | 308 | void *payload; |
307 | long ret; | 309 | long ret; |
308 | 310 | ||
@@ -324,16 +326,16 @@ long keyctl_update_key(key_serial_t id, | |||
324 | } | 326 | } |
325 | 327 | ||
326 | /* find the target key (which must be writable) */ | 328 | /* find the target key (which must be writable) */ |
327 | key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE); | 329 | key_ref = lookup_user_key(NULL, id, 0, 0, KEY_WRITE); |
328 | if (IS_ERR(key)) { | 330 | if (IS_ERR(key_ref)) { |
329 | ret = PTR_ERR(key); | 331 | ret = PTR_ERR(key_ref); |
330 | goto error2; | 332 | goto error2; |
331 | } | 333 | } |
332 | 334 | ||
333 | /* update the key */ | 335 | /* update the key */ |
334 | ret = key_update(key, payload, plen); | 336 | ret = key_update(key_ref, payload, plen); |
335 | 337 | ||
336 | key_put(key); | 338 | key_ref_put(key_ref); |
337 | error2: | 339 | error2: |
338 | kfree(payload); | 340 | kfree(payload); |
339 | error: | 341 | error: |
@@ -349,19 +351,19 @@ long keyctl_update_key(key_serial_t id, | |||
349 | */ | 351 | */ |
350 | long keyctl_revoke_key(key_serial_t id) | 352 | long keyctl_revoke_key(key_serial_t id) |
351 | { | 353 | { |
352 | struct key *key; | 354 | key_ref_t key_ref; |
353 | long ret; | 355 | long ret; |
354 | 356 | ||
355 | key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE); | 357 | key_ref = lookup_user_key(NULL, id, 0, 0, KEY_WRITE); |
356 | if (IS_ERR(key)) { | 358 | if (IS_ERR(key_ref)) { |
357 | ret = PTR_ERR(key); | 359 | ret = PTR_ERR(key_ref); |
358 | goto error; | 360 | goto error; |
359 | } | 361 | } |
360 | 362 | ||
361 | key_revoke(key); | 363 | key_revoke(key_ref_to_ptr(key_ref)); |
362 | ret = 0; | 364 | ret = 0; |
363 | 365 | ||
364 | key_put(key); | 366 | key_ref_put(key_ref); |
365 | error: | 367 | error: |
366 | return ret; | 368 | return ret; |
367 | 369 | ||
@@ -375,18 +377,18 @@ long keyctl_revoke_key(key_serial_t id) | |||
375 | */ | 377 | */ |
376 | long keyctl_keyring_clear(key_serial_t ringid) | 378 | long keyctl_keyring_clear(key_serial_t ringid) |
377 | { | 379 | { |
378 | struct key *keyring; | 380 | key_ref_t keyring_ref; |
379 | long ret; | 381 | long ret; |
380 | 382 | ||
381 | keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); | 383 | keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); |
382 | if (IS_ERR(keyring)) { | 384 | if (IS_ERR(keyring_ref)) { |
383 | ret = PTR_ERR(keyring); | 385 | ret = PTR_ERR(keyring_ref); |
384 | goto error; | 386 | goto error; |
385 | } | 387 | } |
386 | 388 | ||
387 | ret = keyring_clear(keyring); | 389 | ret = keyring_clear(key_ref_to_ptr(keyring_ref)); |
388 | 390 | ||
389 | key_put(keyring); | 391 | key_ref_put(keyring_ref); |
390 | error: | 392 | error: |
391 | return ret; | 393 | return ret; |
392 | 394 | ||
@@ -401,26 +403,26 @@ long keyctl_keyring_clear(key_serial_t ringid) | |||
401 | */ | 403 | */ |
402 | long keyctl_keyring_link(key_serial_t id, key_serial_t ringid) | 404 | long keyctl_keyring_link(key_serial_t id, key_serial_t ringid) |
403 | { | 405 | { |
404 | struct key *keyring, *key; | 406 | key_ref_t keyring_ref, key_ref; |
405 | long ret; | 407 | long ret; |
406 | 408 | ||
407 | keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); | 409 | keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); |
408 | if (IS_ERR(keyring)) { | 410 | if (IS_ERR(keyring_ref)) { |
409 | ret = PTR_ERR(keyring); | 411 | ret = PTR_ERR(keyring_ref); |
410 | goto error; | 412 | goto error; |
411 | } | 413 | } |
412 | 414 | ||
413 | key = lookup_user_key(NULL, id, 1, 0, KEY_LINK); | 415 | key_ref = lookup_user_key(NULL, id, 1, 0, KEY_LINK); |
414 | if (IS_ERR(key)) { | 416 | if (IS_ERR(key_ref)) { |
415 | ret = PTR_ERR(key); | 417 | ret = PTR_ERR(key_ref); |
416 | goto error2; | 418 | goto error2; |
417 | } | 419 | } |
418 | 420 | ||
419 | ret = key_link(keyring, key); | 421 | ret = key_link(key_ref_to_ptr(keyring_ref), key_ref_to_ptr(key_ref)); |
420 | 422 | ||
421 | key_put(key); | 423 | key_ref_put(key_ref); |
422 | error2: | 424 | error2: |
423 | key_put(keyring); | 425 | key_ref_put(keyring_ref); |
424 | error: | 426 | error: |
425 | return ret; | 427 | return ret; |
426 | 428 | ||
@@ -435,26 +437,26 @@ long keyctl_keyring_link(key_serial_t id, key_serial_t ringid) | |||
435 | */ | 437 | */ |
436 | long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid) | 438 | long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid) |
437 | { | 439 | { |
438 | struct key *keyring, *key; | 440 | key_ref_t keyring_ref, key_ref; |
439 | long ret; | 441 | long ret; |
440 | 442 | ||
441 | keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_WRITE); | 443 | keyring_ref = lookup_user_key(NULL, ringid, 0, 0, KEY_WRITE); |
442 | if (IS_ERR(keyring)) { | 444 | if (IS_ERR(keyring_ref)) { |
443 | ret = PTR_ERR(keyring); | 445 | ret = PTR_ERR(keyring_ref); |
444 | goto error; | 446 | goto error; |
445 | } | 447 | } |
446 | 448 | ||
447 | key = lookup_user_key(NULL, id, 0, 0, 0); | 449 | key_ref = lookup_user_key(NULL, id, 0, 0, 0); |
448 | if (IS_ERR(key)) { | 450 | if (IS_ERR(key_ref)) { |
449 | ret = PTR_ERR(key); | 451 | ret = PTR_ERR(key_ref); |
450 | goto error2; | 452 | goto error2; |
451 | } | 453 | } |
452 | 454 | ||
453 | ret = key_unlink(keyring, key); | 455 | ret = key_unlink(key_ref_to_ptr(keyring_ref), key_ref_to_ptr(key_ref)); |
454 | 456 | ||
455 | key_put(key); | 457 | key_ref_put(key_ref); |
456 | error2: | 458 | error2: |
457 | key_put(keyring); | 459 | key_ref_put(keyring_ref); |
458 | error: | 460 | error: |
459 | return ret; | 461 | return ret; |
460 | 462 | ||
@@ -476,24 +478,26 @@ long keyctl_describe_key(key_serial_t keyid, | |||
476 | size_t buflen) | 478 | size_t buflen) |
477 | { | 479 | { |
478 | struct key *key, *instkey; | 480 | struct key *key, *instkey; |
481 | key_ref_t key_ref; | ||
479 | char *tmpbuf; | 482 | char *tmpbuf; |
480 | long ret; | 483 | long ret; |
481 | 484 | ||
482 | key = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW); | 485 | key_ref = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW); |
483 | if (IS_ERR(key)) { | 486 | if (IS_ERR(key_ref)) { |
484 | /* viewing a key under construction is permitted if we have the | 487 | /* viewing a key under construction is permitted if we have the |
485 | * authorisation token handy */ | 488 | * authorisation token handy */ |
486 | if (PTR_ERR(key) == -EACCES) { | 489 | if (PTR_ERR(key_ref) == -EACCES) { |
487 | instkey = key_get_instantiation_authkey(keyid); | 490 | instkey = key_get_instantiation_authkey(keyid); |
488 | if (!IS_ERR(instkey)) { | 491 | if (!IS_ERR(instkey)) { |
489 | key_put(instkey); | 492 | key_put(instkey); |
490 | key = lookup_user_key(NULL, keyid, 0, 1, 0); | 493 | key_ref = lookup_user_key(NULL, keyid, |
491 | if (!IS_ERR(key)) | 494 | 0, 1, 0); |
495 | if (!IS_ERR(key_ref)) | ||
492 | goto okay; | 496 | goto okay; |
493 | } | 497 | } |
494 | } | 498 | } |
495 | 499 | ||
496 | ret = PTR_ERR(key); | 500 | ret = PTR_ERR(key_ref); |
497 | goto error; | 501 | goto error; |
498 | } | 502 | } |
499 | 503 | ||
@@ -504,13 +508,16 @@ okay: | |||
504 | if (!tmpbuf) | 508 | if (!tmpbuf) |
505 | goto error2; | 509 | goto error2; |
506 | 510 | ||
511 | key = key_ref_to_ptr(key_ref); | ||
512 | |||
507 | ret = snprintf(tmpbuf, PAGE_SIZE - 1, | 513 | ret = snprintf(tmpbuf, PAGE_SIZE - 1, |
508 | "%s;%d;%d;%06x;%s", | 514 | "%s;%d;%d;%08x;%s", |
509 | key->type->name, | 515 | key_ref_to_ptr(key_ref)->type->name, |
510 | key->uid, | 516 | key_ref_to_ptr(key_ref)->uid, |
511 | key->gid, | 517 | key_ref_to_ptr(key_ref)->gid, |
512 | key->perm, | 518 | key_ref_to_ptr(key_ref)->perm, |
513 | key->description ? key->description :"" | 519 | key_ref_to_ptr(key_ref)->description ? |
520 | key_ref_to_ptr(key_ref)->description : "" | ||
514 | ); | 521 | ); |
515 | 522 | ||
516 | /* include a NUL char at the end of the data */ | 523 | /* include a NUL char at the end of the data */ |
@@ -530,7 +537,7 @@ okay: | |||
530 | 537 | ||
531 | kfree(tmpbuf); | 538 | kfree(tmpbuf); |
532 | error2: | 539 | error2: |
533 | key_put(key); | 540 | key_ref_put(key_ref); |
534 | error: | 541 | error: |
535 | return ret; | 542 | return ret; |
536 | 543 | ||
@@ -552,7 +559,7 @@ long keyctl_keyring_search(key_serial_t ringid, | |||
552 | key_serial_t destringid) | 559 | key_serial_t destringid) |
553 | { | 560 | { |
554 | struct key_type *ktype; | 561 | struct key_type *ktype; |
555 | struct key *keyring, *key, *dest; | 562 | key_ref_t keyring_ref, key_ref, dest_ref; |
556 | char type[32], *description; | 563 | char type[32], *description; |
557 | long dlen, ret; | 564 | long dlen, ret; |
558 | 565 | ||
@@ -581,18 +588,18 @@ long keyctl_keyring_search(key_serial_t ringid, | |||
581 | goto error2; | 588 | goto error2; |
582 | 589 | ||
583 | /* get the keyring at which to begin the search */ | 590 | /* get the keyring at which to begin the search */ |
584 | keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_SEARCH); | 591 | keyring_ref = lookup_user_key(NULL, ringid, 0, 0, KEY_SEARCH); |
585 | if (IS_ERR(keyring)) { | 592 | if (IS_ERR(keyring_ref)) { |
586 | ret = PTR_ERR(keyring); | 593 | ret = PTR_ERR(keyring_ref); |
587 | goto error2; | 594 | goto error2; |
588 | } | 595 | } |
589 | 596 | ||
590 | /* get the destination keyring if specified */ | 597 | /* get the destination keyring if specified */ |
591 | dest = NULL; | 598 | dest_ref = NULL; |
592 | if (destringid) { | 599 | if (destringid) { |
593 | dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE); | 600 | dest_ref = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE); |
594 | if (IS_ERR(dest)) { | 601 | if (IS_ERR(dest_ref)) { |
595 | ret = PTR_ERR(dest); | 602 | ret = PTR_ERR(dest_ref); |
596 | goto error3; | 603 | goto error3; |
597 | } | 604 | } |
598 | } | 605 | } |
@@ -605,9 +612,9 @@ long keyctl_keyring_search(key_serial_t ringid, | |||
605 | } | 612 | } |
606 | 613 | ||
607 | /* do the search */ | 614 | /* do the search */ |
608 | key = keyring_search(keyring, ktype, description); | 615 | key_ref = keyring_search(keyring_ref, ktype, description); |
609 | if (IS_ERR(key)) { | 616 | if (IS_ERR(key_ref)) { |
610 | ret = PTR_ERR(key); | 617 | ret = PTR_ERR(key_ref); |
611 | 618 | ||
612 | /* treat lack or presence of a negative key the same */ | 619 | /* treat lack or presence of a negative key the same */ |
613 | if (ret == -EAGAIN) | 620 | if (ret == -EAGAIN) |
@@ -616,26 +623,26 @@ long keyctl_keyring_search(key_serial_t ringid, | |||
616 | } | 623 | } |
617 | 624 | ||
618 | /* link the resulting key to the destination keyring if we can */ | 625 | /* link the resulting key to the destination keyring if we can */ |
619 | if (dest) { | 626 | if (dest_ref) { |
620 | ret = -EACCES; | 627 | ret = -EACCES; |
621 | if (!key_permission(key, KEY_LINK)) | 628 | if (!key_permission(key_ref, KEY_LINK)) |
622 | goto error6; | 629 | goto error6; |
623 | 630 | ||
624 | ret = key_link(dest, key); | 631 | ret = key_link(key_ref_to_ptr(dest_ref), key_ref_to_ptr(key_ref)); |
625 | if (ret < 0) | 632 | if (ret < 0) |
626 | goto error6; | 633 | goto error6; |
627 | } | 634 | } |
628 | 635 | ||
629 | ret = key->serial; | 636 | ret = key_ref_to_ptr(key_ref)->serial; |
630 | 637 | ||
631 | error6: | 638 | error6: |
632 | key_put(key); | 639 | key_ref_put(key_ref); |
633 | error5: | 640 | error5: |
634 | key_type_put(ktype); | 641 | key_type_put(ktype); |
635 | error4: | 642 | error4: |
636 | key_put(dest); | 643 | key_ref_put(dest_ref); |
637 | error3: | 644 | error3: |
638 | key_put(keyring); | 645 | key_ref_put(keyring_ref); |
639 | error2: | 646 | error2: |
640 | kfree(description); | 647 | kfree(description); |
641 | error: | 648 | error: |
@@ -645,16 +652,6 @@ long keyctl_keyring_search(key_serial_t ringid, | |||
645 | 652 | ||
646 | /*****************************************************************************/ | 653 | /*****************************************************************************/ |
647 | /* | 654 | /* |
648 | * see if the key we're looking at is the target key | ||
649 | */ | ||
650 | static int keyctl_read_key_same(const struct key *key, const void *target) | ||
651 | { | ||
652 | return key == target; | ||
653 | |||
654 | } /* end keyctl_read_key_same() */ | ||
655 | |||
656 | /*****************************************************************************/ | ||
657 | /* | ||
658 | * read a user key's payload | 655 | * read a user key's payload |
659 | * - the keyring must be readable or the key must be searchable from the | 656 | * - the keyring must be readable or the key must be searchable from the |
660 | * process's keyrings | 657 | * process's keyrings |
@@ -665,38 +662,33 @@ static int keyctl_read_key_same(const struct key *key, const void *target) | |||
665 | */ | 662 | */ |
666 | long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) | 663 | long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) |
667 | { | 664 | { |
668 | struct key *key, *skey; | 665 | struct key *key; |
666 | key_ref_t key_ref; | ||
669 | long ret; | 667 | long ret; |
670 | 668 | ||
671 | /* find the key first */ | 669 | /* find the key first */ |
672 | key = lookup_user_key(NULL, keyid, 0, 0, 0); | 670 | key_ref = lookup_user_key(NULL, keyid, 0, 0, 0); |
673 | if (!IS_ERR(key)) { | 671 | if (IS_ERR(key_ref)) { |
674 | /* see if we can read it directly */ | 672 | ret = -ENOKEY; |
675 | if (key_permission(key, KEY_READ)) | 673 | goto error; |
676 | goto can_read_key; | ||
677 | |||
678 | /* we can't; see if it's searchable from this process's | ||
679 | * keyrings | ||
680 | * - we automatically take account of the fact that it may be | ||
681 | * dangling off an instantiation key | ||
682 | */ | ||
683 | skey = search_process_keyrings(key->type, key, | ||
684 | keyctl_read_key_same, current); | ||
685 | if (!IS_ERR(skey)) | ||
686 | goto can_read_key2; | ||
687 | |||
688 | ret = PTR_ERR(skey); | ||
689 | if (ret == -EAGAIN) | ||
690 | ret = -EACCES; | ||
691 | goto error2; | ||
692 | } | 674 | } |
693 | 675 | ||
694 | ret = -ENOKEY; | 676 | key = key_ref_to_ptr(key_ref); |
695 | goto error; | 677 | |
678 | /* see if we can read it directly */ | ||
679 | if (key_permission(key_ref, KEY_READ)) | ||
680 | goto can_read_key; | ||
681 | |||
682 | /* we can't; see if it's searchable from this process's keyrings | ||
683 | * - we automatically take account of the fact that it may be | ||
684 | * dangling off an instantiation key | ||
685 | */ | ||
686 | if (!is_key_possessed(key_ref)) { | ||
687 | ret = -EACCES; | ||
688 | goto error2; | ||
689 | } | ||
696 | 690 | ||
697 | /* the key is probably readable - now try to read it */ | 691 | /* the key is probably readable - now try to read it */ |
698 | can_read_key2: | ||
699 | key_put(skey); | ||
700 | can_read_key: | 692 | can_read_key: |
701 | ret = key_validate(key); | 693 | ret = key_validate(key); |
702 | if (ret == 0) { | 694 | if (ret == 0) { |
@@ -727,18 +719,21 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) | |||
727 | long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) | 719 | long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) |
728 | { | 720 | { |
729 | struct key *key; | 721 | struct key *key; |
722 | key_ref_t key_ref; | ||
730 | long ret; | 723 | long ret; |
731 | 724 | ||
732 | ret = 0; | 725 | ret = 0; |
733 | if (uid == (uid_t) -1 && gid == (gid_t) -1) | 726 | if (uid == (uid_t) -1 && gid == (gid_t) -1) |
734 | goto error; | 727 | goto error; |
735 | 728 | ||
736 | key = lookup_user_key(NULL, id, 1, 1, 0); | 729 | key_ref = lookup_user_key(NULL, id, 1, 1, 0); |
737 | if (IS_ERR(key)) { | 730 | if (IS_ERR(key_ref)) { |
738 | ret = PTR_ERR(key); | 731 | ret = PTR_ERR(key_ref); |
739 | goto error; | 732 | goto error; |
740 | } | 733 | } |
741 | 734 | ||
735 | key = key_ref_to_ptr(key_ref); | ||
736 | |||
742 | /* make the changes with the locks held to prevent chown/chown races */ | 737 | /* make the changes with the locks held to prevent chown/chown races */ |
743 | ret = -EACCES; | 738 | ret = -EACCES; |
744 | down_write(&key->sem); | 739 | down_write(&key->sem); |
@@ -784,18 +779,21 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) | |||
784 | long keyctl_setperm_key(key_serial_t id, key_perm_t perm) | 779 | long keyctl_setperm_key(key_serial_t id, key_perm_t perm) |
785 | { | 780 | { |
786 | struct key *key; | 781 | struct key *key; |
782 | key_ref_t key_ref; | ||
787 | long ret; | 783 | long ret; |
788 | 784 | ||
789 | ret = -EINVAL; | 785 | ret = -EINVAL; |
790 | if (perm & ~(KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)) | 786 | if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)) |
791 | goto error; | 787 | goto error; |
792 | 788 | ||
793 | key = lookup_user_key(NULL, id, 1, 1, 0); | 789 | key_ref = lookup_user_key(NULL, id, 1, 1, 0); |
794 | if (IS_ERR(key)) { | 790 | if (IS_ERR(key_ref)) { |
795 | ret = PTR_ERR(key); | 791 | ret = PTR_ERR(key_ref); |
796 | goto error; | 792 | goto error; |
797 | } | 793 | } |
798 | 794 | ||
795 | key = key_ref_to_ptr(key_ref); | ||
796 | |||
799 | /* make the changes with the locks held to prevent chown/chmod races */ | 797 | /* make the changes with the locks held to prevent chown/chmod races */ |
800 | ret = -EACCES; | 798 | ret = -EACCES; |
801 | down_write(&key->sem); | 799 | down_write(&key->sem); |
@@ -824,7 +822,8 @@ long keyctl_instantiate_key(key_serial_t id, | |||
824 | key_serial_t ringid) | 822 | key_serial_t ringid) |
825 | { | 823 | { |
826 | struct request_key_auth *rka; | 824 | struct request_key_auth *rka; |
827 | struct key *instkey, *keyring; | 825 | struct key *instkey; |
826 | key_ref_t keyring_ref; | ||
828 | void *payload; | 827 | void *payload; |
829 | long ret; | 828 | long ret; |
830 | 829 | ||
@@ -857,21 +856,21 @@ long keyctl_instantiate_key(key_serial_t id, | |||
857 | 856 | ||
858 | /* find the destination keyring amongst those belonging to the | 857 | /* find the destination keyring amongst those belonging to the |
859 | * requesting task */ | 858 | * requesting task */ |
860 | keyring = NULL; | 859 | keyring_ref = NULL; |
861 | if (ringid) { | 860 | if (ringid) { |
862 | keyring = lookup_user_key(rka->context, ringid, 1, 0, | 861 | keyring_ref = lookup_user_key(rka->context, ringid, 1, 0, |
863 | KEY_WRITE); | 862 | KEY_WRITE); |
864 | if (IS_ERR(keyring)) { | 863 | if (IS_ERR(keyring_ref)) { |
865 | ret = PTR_ERR(keyring); | 864 | ret = PTR_ERR(keyring_ref); |
866 | goto error3; | 865 | goto error3; |
867 | } | 866 | } |
868 | } | 867 | } |
869 | 868 | ||
870 | /* instantiate the key and link it into a keyring */ | 869 | /* instantiate the key and link it into a keyring */ |
871 | ret = key_instantiate_and_link(rka->target_key, payload, plen, | 870 | ret = key_instantiate_and_link(rka->target_key, payload, plen, |
872 | keyring, instkey); | 871 | key_ref_to_ptr(keyring_ref), instkey); |
873 | 872 | ||
874 | key_put(keyring); | 873 | key_ref_put(keyring_ref); |
875 | error3: | 874 | error3: |
876 | key_put(instkey); | 875 | key_put(instkey); |
877 | error2: | 876 | error2: |
@@ -889,7 +888,8 @@ long keyctl_instantiate_key(key_serial_t id, | |||
889 | long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) | 888 | long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) |
890 | { | 889 | { |
891 | struct request_key_auth *rka; | 890 | struct request_key_auth *rka; |
892 | struct key *instkey, *keyring; | 891 | struct key *instkey; |
892 | key_ref_t keyring_ref; | ||
893 | long ret; | 893 | long ret; |
894 | 894 | ||
895 | /* find the instantiation authorisation key */ | 895 | /* find the instantiation authorisation key */ |
@@ -903,19 +903,20 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) | |||
903 | 903 | ||
904 | /* find the destination keyring if present (which must also be | 904 | /* find the destination keyring if present (which must also be |
905 | * writable) */ | 905 | * writable) */ |
906 | keyring = NULL; | 906 | keyring_ref = NULL; |
907 | if (ringid) { | 907 | if (ringid) { |
908 | keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); | 908 | keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); |
909 | if (IS_ERR(keyring)) { | 909 | if (IS_ERR(keyring_ref)) { |
910 | ret = PTR_ERR(keyring); | 910 | ret = PTR_ERR(keyring_ref); |
911 | goto error2; | 911 | goto error2; |
912 | } | 912 | } |
913 | } | 913 | } |
914 | 914 | ||
915 | /* instantiate the key and link it into a keyring */ | 915 | /* instantiate the key and link it into a keyring */ |
916 | ret = key_negate_and_link(rka->target_key, timeout, keyring, instkey); | 916 | ret = key_negate_and_link(rka->target_key, timeout, |
917 | key_ref_to_ptr(keyring_ref), instkey); | ||
917 | 918 | ||
918 | key_put(keyring); | 919 | key_ref_put(keyring_ref); |
919 | error2: | 920 | error2: |
920 | key_put(instkey); | 921 | key_put(instkey); |
921 | error: | 922 | error: |
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 9c208c756df8..0639396dd441 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -309,7 +309,7 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, | |||
309 | int ret; | 309 | int ret; |
310 | 310 | ||
311 | keyring = key_alloc(&key_type_keyring, description, | 311 | keyring = key_alloc(&key_type_keyring, description, |
312 | uid, gid, KEY_USR_ALL, not_in_quota); | 312 | uid, gid, KEY_POS_ALL | KEY_USR_ALL, not_in_quota); |
313 | 313 | ||
314 | if (!IS_ERR(keyring)) { | 314 | if (!IS_ERR(keyring)) { |
315 | ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL); | 315 | ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL); |
@@ -333,12 +333,13 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, | |||
333 | * - we rely on RCU to prevent the keyring lists from disappearing on us | 333 | * - we rely on RCU to prevent the keyring lists from disappearing on us |
334 | * - we return -EAGAIN if we didn't find any matching key | 334 | * - we return -EAGAIN if we didn't find any matching key |
335 | * - we return -ENOKEY if we only found negative matching keys | 335 | * - we return -ENOKEY if we only found negative matching keys |
336 | * - we propagate the possession attribute from the keyring ref to the key ref | ||
336 | */ | 337 | */ |
337 | struct key *keyring_search_aux(struct key *keyring, | 338 | key_ref_t keyring_search_aux(key_ref_t keyring_ref, |
338 | struct task_struct *context, | 339 | struct task_struct *context, |
339 | struct key_type *type, | 340 | struct key_type *type, |
340 | const void *description, | 341 | const void *description, |
341 | key_match_func_t match) | 342 | key_match_func_t match) |
342 | { | 343 | { |
343 | struct { | 344 | struct { |
344 | struct keyring_list *keylist; | 345 | struct keyring_list *keylist; |
@@ -347,29 +348,33 @@ struct key *keyring_search_aux(struct key *keyring, | |||
347 | 348 | ||
348 | struct keyring_list *keylist; | 349 | struct keyring_list *keylist; |
349 | struct timespec now; | 350 | struct timespec now; |
350 | struct key *key; | 351 | unsigned long possessed; |
352 | struct key *keyring, *key; | ||
353 | key_ref_t key_ref; | ||
351 | long err; | 354 | long err; |
352 | int sp, kix; | 355 | int sp, kix; |
353 | 356 | ||
357 | keyring = key_ref_to_ptr(keyring_ref); | ||
358 | possessed = is_key_possessed(keyring_ref); | ||
354 | key_check(keyring); | 359 | key_check(keyring); |
355 | 360 | ||
356 | rcu_read_lock(); | ||
357 | |||
358 | /* top keyring must have search permission to begin the search */ | 361 | /* top keyring must have search permission to begin the search */ |
359 | key = ERR_PTR(-EACCES); | 362 | key_ref = ERR_PTR(-EACCES); |
360 | if (!key_task_permission(keyring, context, KEY_SEARCH)) | 363 | if (!key_task_permission(keyring_ref, context, KEY_SEARCH)) |
361 | goto error; | 364 | goto error; |
362 | 365 | ||
363 | key = ERR_PTR(-ENOTDIR); | 366 | key_ref = ERR_PTR(-ENOTDIR); |
364 | if (keyring->type != &key_type_keyring) | 367 | if (keyring->type != &key_type_keyring) |
365 | goto error; | 368 | goto error; |
366 | 369 | ||
370 | rcu_read_lock(); | ||
371 | |||
367 | now = current_kernel_time(); | 372 | now = current_kernel_time(); |
368 | err = -EAGAIN; | 373 | err = -EAGAIN; |
369 | sp = 0; | 374 | sp = 0; |
370 | 375 | ||
371 | /* start processing a new keyring */ | 376 | /* start processing a new keyring */ |
372 | descend: | 377 | descend: |
373 | if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) | 378 | if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) |
374 | goto not_this_keyring; | 379 | goto not_this_keyring; |
375 | 380 | ||
@@ -397,7 +402,8 @@ struct key *keyring_search_aux(struct key *keyring, | |||
397 | continue; | 402 | continue; |
398 | 403 | ||
399 | /* key must have search permissions */ | 404 | /* key must have search permissions */ |
400 | if (!key_task_permission(key, context, KEY_SEARCH)) | 405 | if (!key_task_permission(make_key_ref(key, possessed), |
406 | context, KEY_SEARCH)) | ||
401 | continue; | 407 | continue; |
402 | 408 | ||
403 | /* we set a different error code if we find a negative key */ | 409 | /* we set a different error code if we find a negative key */ |
@@ -411,7 +417,7 @@ struct key *keyring_search_aux(struct key *keyring, | |||
411 | 417 | ||
412 | /* search through the keyrings nested in this one */ | 418 | /* search through the keyrings nested in this one */ |
413 | kix = 0; | 419 | kix = 0; |
414 | ascend: | 420 | ascend: |
415 | for (; kix < keylist->nkeys; kix++) { | 421 | for (; kix < keylist->nkeys; kix++) { |
416 | key = keylist->keys[kix]; | 422 | key = keylist->keys[kix]; |
417 | if (key->type != &key_type_keyring) | 423 | if (key->type != &key_type_keyring) |
@@ -423,7 +429,8 @@ struct key *keyring_search_aux(struct key *keyring, | |||
423 | if (sp >= KEYRING_SEARCH_MAX_DEPTH) | 429 | if (sp >= KEYRING_SEARCH_MAX_DEPTH) |
424 | continue; | 430 | continue; |
425 | 431 | ||
426 | if (!key_task_permission(key, context, KEY_SEARCH)) | 432 | if (!key_task_permission(make_key_ref(key, possessed), |
433 | context, KEY_SEARCH)) | ||
427 | continue; | 434 | continue; |
428 | 435 | ||
429 | /* stack the current position */ | 436 | /* stack the current position */ |
@@ -438,7 +445,7 @@ struct key *keyring_search_aux(struct key *keyring, | |||
438 | 445 | ||
439 | /* the keyring we're looking at was disqualified or didn't contain a | 446 | /* the keyring we're looking at was disqualified or didn't contain a |
440 | * matching key */ | 447 | * matching key */ |
441 | not_this_keyring: | 448 | not_this_keyring: |
442 | if (sp > 0) { | 449 | if (sp > 0) { |
443 | /* resume the processing of a keyring higher up in the tree */ | 450 | /* resume the processing of a keyring higher up in the tree */ |
444 | sp--; | 451 | sp--; |
@@ -447,16 +454,18 @@ struct key *keyring_search_aux(struct key *keyring, | |||
447 | goto ascend; | 454 | goto ascend; |
448 | } | 455 | } |
449 | 456 | ||
450 | key = ERR_PTR(err); | 457 | key_ref = ERR_PTR(err); |
451 | goto error; | 458 | goto error_2; |
452 | 459 | ||
453 | /* we found a viable match */ | 460 | /* we found a viable match */ |
454 | found: | 461 | found: |
455 | atomic_inc(&key->usage); | 462 | atomic_inc(&key->usage); |
456 | key_check(key); | 463 | key_check(key); |
457 | error: | 464 | key_ref = make_key_ref(key, possessed); |
465 | error_2: | ||
458 | rcu_read_unlock(); | 466 | rcu_read_unlock(); |
459 | return key; | 467 | error: |
468 | return key_ref; | ||
460 | 469 | ||
461 | } /* end keyring_search_aux() */ | 470 | } /* end keyring_search_aux() */ |
462 | 471 | ||
@@ -469,9 +478,9 @@ struct key *keyring_search_aux(struct key *keyring, | |||
469 | * - we return -EAGAIN if we didn't find any matching key | 478 | * - we return -EAGAIN if we didn't find any matching key |
470 | * - we return -ENOKEY if we only found negative matching keys | 479 | * - we return -ENOKEY if we only found negative matching keys |
471 | */ | 480 | */ |
472 | struct key *keyring_search(struct key *keyring, | 481 | key_ref_t keyring_search(key_ref_t keyring, |
473 | struct key_type *type, | 482 | struct key_type *type, |
474 | const char *description) | 483 | const char *description) |
475 | { | 484 | { |
476 | if (!type->match) | 485 | if (!type->match) |
477 | return ERR_PTR(-ENOKEY); | 486 | return ERR_PTR(-ENOKEY); |
@@ -488,15 +497,19 @@ EXPORT_SYMBOL(keyring_search); | |||
488 | * search the given keyring only (no recursion) | 497 | * search the given keyring only (no recursion) |
489 | * - keyring must be locked by caller | 498 | * - keyring must be locked by caller |
490 | */ | 499 | */ |
491 | struct key *__keyring_search_one(struct key *keyring, | 500 | key_ref_t __keyring_search_one(key_ref_t keyring_ref, |
492 | const struct key_type *ktype, | 501 | const struct key_type *ktype, |
493 | const char *description, | 502 | const char *description, |
494 | key_perm_t perm) | 503 | key_perm_t perm) |
495 | { | 504 | { |
496 | struct keyring_list *klist; | 505 | struct keyring_list *klist; |
497 | struct key *key; | 506 | unsigned long possessed; |
507 | struct key *keyring, *key; | ||
498 | int loop; | 508 | int loop; |
499 | 509 | ||
510 | keyring = key_ref_to_ptr(keyring_ref); | ||
511 | possessed = is_key_possessed(keyring_ref); | ||
512 | |||
500 | rcu_read_lock(); | 513 | rcu_read_lock(); |
501 | 514 | ||
502 | klist = rcu_dereference(keyring->payload.subscriptions); | 515 | klist = rcu_dereference(keyring->payload.subscriptions); |
@@ -507,21 +520,21 @@ struct key *__keyring_search_one(struct key *keyring, | |||
507 | if (key->type == ktype && | 520 | if (key->type == ktype && |
508 | (!key->type->match || | 521 | (!key->type->match || |
509 | key->type->match(key, description)) && | 522 | key->type->match(key, description)) && |
510 | key_permission(key, perm) && | 523 | key_permission(make_key_ref(key, possessed), |
524 | perm) && | ||
511 | !test_bit(KEY_FLAG_REVOKED, &key->flags) | 525 | !test_bit(KEY_FLAG_REVOKED, &key->flags) |
512 | ) | 526 | ) |
513 | goto found; | 527 | goto found; |
514 | } | 528 | } |
515 | } | 529 | } |
516 | 530 | ||
517 | key = ERR_PTR(-ENOKEY); | 531 | rcu_read_unlock(); |
518 | goto error; | 532 | return ERR_PTR(-ENOKEY); |
519 | 533 | ||
520 | found: | 534 | found: |
521 | atomic_inc(&key->usage); | 535 | atomic_inc(&key->usage); |
522 | error: | ||
523 | rcu_read_unlock(); | 536 | rcu_read_unlock(); |
524 | return key; | 537 | return make_key_ref(key, possessed); |
525 | 538 | ||
526 | } /* end __keyring_search_one() */ | 539 | } /* end __keyring_search_one() */ |
527 | 540 | ||
@@ -603,7 +616,8 @@ struct key *find_keyring_by_name(const char *name, key_serial_t bound) | |||
603 | if (strcmp(keyring->description, name) != 0) | 616 | if (strcmp(keyring->description, name) != 0) |
604 | continue; | 617 | continue; |
605 | 618 | ||
606 | if (!key_permission(keyring, KEY_SEARCH)) | 619 | if (!key_permission(make_key_ref(keyring, 0), |
620 | KEY_SEARCH)) | ||
607 | continue; | 621 | continue; |
608 | 622 | ||
609 | /* found a potential candidate, but we still need to | 623 | /* found a potential candidate, but we still need to |
diff --git a/security/keys/proc.c b/security/keys/proc.c index c55cf1fd0826..12b750e51fbf 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c | |||
@@ -167,7 +167,7 @@ static int proc_keys_show(struct seq_file *m, void *v) | |||
167 | #define showflag(KEY, LETTER, FLAG) \ | 167 | #define showflag(KEY, LETTER, FLAG) \ |
168 | (test_bit(FLAG, &(KEY)->flags) ? LETTER : '-') | 168 | (test_bit(FLAG, &(KEY)->flags) ? LETTER : '-') |
169 | 169 | ||
170 | seq_printf(m, "%08x %c%c%c%c%c%c %5d %4s %06x %5d %5d %-9.9s ", | 170 | seq_printf(m, "%08x %c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ", |
171 | key->serial, | 171 | key->serial, |
172 | showflag(key, 'I', KEY_FLAG_INSTANTIATED), | 172 | showflag(key, 'I', KEY_FLAG_INSTANTIATED), |
173 | showflag(key, 'R', KEY_FLAG_REVOKED), | 173 | showflag(key, 'R', KEY_FLAG_REVOKED), |
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index c089f78fb94e..d42d2158ce13 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -39,7 +39,7 @@ struct key root_user_keyring = { | |||
39 | .type = &key_type_keyring, | 39 | .type = &key_type_keyring, |
40 | .user = &root_key_user, | 40 | .user = &root_key_user, |
41 | .sem = __RWSEM_INITIALIZER(root_user_keyring.sem), | 41 | .sem = __RWSEM_INITIALIZER(root_user_keyring.sem), |
42 | .perm = KEY_USR_ALL, | 42 | .perm = KEY_POS_ALL | KEY_USR_ALL, |
43 | .flags = 1 << KEY_FLAG_INSTANTIATED, | 43 | .flags = 1 << KEY_FLAG_INSTANTIATED, |
44 | .description = "_uid.0", | 44 | .description = "_uid.0", |
45 | #ifdef KEY_DEBUGGING | 45 | #ifdef KEY_DEBUGGING |
@@ -54,7 +54,7 @@ struct key root_session_keyring = { | |||
54 | .type = &key_type_keyring, | 54 | .type = &key_type_keyring, |
55 | .user = &root_key_user, | 55 | .user = &root_key_user, |
56 | .sem = __RWSEM_INITIALIZER(root_session_keyring.sem), | 56 | .sem = __RWSEM_INITIALIZER(root_session_keyring.sem), |
57 | .perm = KEY_USR_ALL, | 57 | .perm = KEY_POS_ALL | KEY_USR_ALL, |
58 | .flags = 1 << KEY_FLAG_INSTANTIATED, | 58 | .flags = 1 << KEY_FLAG_INSTANTIATED, |
59 | .description = "_uid_ses.0", | 59 | .description = "_uid_ses.0", |
60 | #ifdef KEY_DEBUGGING | 60 | #ifdef KEY_DEBUGGING |
@@ -98,7 +98,7 @@ int alloc_uid_keyring(struct user_struct *user) | |||
98 | user->session_keyring = session_keyring; | 98 | user->session_keyring = session_keyring; |
99 | ret = 0; | 99 | ret = 0; |
100 | 100 | ||
101 | error: | 101 | error: |
102 | return ret; | 102 | return ret; |
103 | 103 | ||
104 | } /* end alloc_uid_keyring() */ | 104 | } /* end alloc_uid_keyring() */ |
@@ -156,7 +156,7 @@ int install_thread_keyring(struct task_struct *tsk) | |||
156 | ret = 0; | 156 | ret = 0; |
157 | 157 | ||
158 | key_put(old); | 158 | key_put(old); |
159 | error: | 159 | error: |
160 | return ret; | 160 | return ret; |
161 | 161 | ||
162 | } /* end install_thread_keyring() */ | 162 | } /* end install_thread_keyring() */ |
@@ -193,7 +193,7 @@ int install_process_keyring(struct task_struct *tsk) | |||
193 | } | 193 | } |
194 | 194 | ||
195 | ret = 0; | 195 | ret = 0; |
196 | error: | 196 | error: |
197 | return ret; | 197 | return ret; |
198 | 198 | ||
199 | } /* end install_process_keyring() */ | 199 | } /* end install_process_keyring() */ |
@@ -236,7 +236,7 @@ static int install_session_keyring(struct task_struct *tsk, | |||
236 | /* we're using RCU on the pointer */ | 236 | /* we're using RCU on the pointer */ |
237 | synchronize_rcu(); | 237 | synchronize_rcu(); |
238 | key_put(old); | 238 | key_put(old); |
239 | error: | 239 | error: |
240 | return ret; | 240 | return ret; |
241 | 241 | ||
242 | } /* end install_session_keyring() */ | 242 | } /* end install_session_keyring() */ |
@@ -376,13 +376,13 @@ void key_fsgid_changed(struct task_struct *tsk) | |||
376 | * - we return -EAGAIN if we didn't find any matching key | 376 | * - we return -EAGAIN if we didn't find any matching key |
377 | * - we return -ENOKEY if we found only negative matching keys | 377 | * - we return -ENOKEY if we found only negative matching keys |
378 | */ | 378 | */ |
379 | struct key *search_process_keyrings(struct key_type *type, | 379 | key_ref_t search_process_keyrings(struct key_type *type, |
380 | const void *description, | 380 | const void *description, |
381 | key_match_func_t match, | 381 | key_match_func_t match, |
382 | struct task_struct *context) | 382 | struct task_struct *context) |
383 | { | 383 | { |
384 | struct request_key_auth *rka; | 384 | struct request_key_auth *rka; |
385 | struct key *key, *ret, *err, *instkey; | 385 | key_ref_t key_ref, ret, err, instkey_ref; |
386 | 386 | ||
387 | /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were | 387 | /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were |
388 | * searchable, but we failed to find a key or we found a negative key; | 388 | * searchable, but we failed to find a key or we found a negative key; |
@@ -391,46 +391,48 @@ struct key *search_process_keyrings(struct key_type *type, | |||
391 | * | 391 | * |
392 | * in terms of priority: success > -ENOKEY > -EAGAIN > other error | 392 | * in terms of priority: success > -ENOKEY > -EAGAIN > other error |
393 | */ | 393 | */ |
394 | key = NULL; | 394 | key_ref = NULL; |
395 | ret = NULL; | 395 | ret = NULL; |
396 | err = ERR_PTR(-EAGAIN); | 396 | err = ERR_PTR(-EAGAIN); |
397 | 397 | ||
398 | /* search the thread keyring first */ | 398 | /* search the thread keyring first */ |
399 | if (context->thread_keyring) { | 399 | if (context->thread_keyring) { |
400 | key = keyring_search_aux(context->thread_keyring, | 400 | key_ref = keyring_search_aux( |
401 | context, type, description, match); | 401 | make_key_ref(context->thread_keyring, 1), |
402 | if (!IS_ERR(key)) | 402 | context, type, description, match); |
403 | if (!IS_ERR(key_ref)) | ||
403 | goto found; | 404 | goto found; |
404 | 405 | ||
405 | switch (PTR_ERR(key)) { | 406 | switch (PTR_ERR(key_ref)) { |
406 | case -EAGAIN: /* no key */ | 407 | case -EAGAIN: /* no key */ |
407 | if (ret) | 408 | if (ret) |
408 | break; | 409 | break; |
409 | case -ENOKEY: /* negative key */ | 410 | case -ENOKEY: /* negative key */ |
410 | ret = key; | 411 | ret = key_ref; |
411 | break; | 412 | break; |
412 | default: | 413 | default: |
413 | err = key; | 414 | err = key_ref; |
414 | break; | 415 | break; |
415 | } | 416 | } |
416 | } | 417 | } |
417 | 418 | ||
418 | /* search the process keyring second */ | 419 | /* search the process keyring second */ |
419 | if (context->signal->process_keyring) { | 420 | if (context->signal->process_keyring) { |
420 | key = keyring_search_aux(context->signal->process_keyring, | 421 | key_ref = keyring_search_aux( |
421 | context, type, description, match); | 422 | make_key_ref(context->signal->process_keyring, 1), |
422 | if (!IS_ERR(key)) | 423 | context, type, description, match); |
424 | if (!IS_ERR(key_ref)) | ||
423 | goto found; | 425 | goto found; |
424 | 426 | ||
425 | switch (PTR_ERR(key)) { | 427 | switch (PTR_ERR(key_ref)) { |
426 | case -EAGAIN: /* no key */ | 428 | case -EAGAIN: /* no key */ |
427 | if (ret) | 429 | if (ret) |
428 | break; | 430 | break; |
429 | case -ENOKEY: /* negative key */ | 431 | case -ENOKEY: /* negative key */ |
430 | ret = key; | 432 | ret = key_ref; |
431 | break; | 433 | break; |
432 | default: | 434 | default: |
433 | err = key; | 435 | err = key_ref; |
434 | break; | 436 | break; |
435 | } | 437 | } |
436 | } | 438 | } |
@@ -438,23 +440,25 @@ struct key *search_process_keyrings(struct key_type *type, | |||
438 | /* search the session keyring */ | 440 | /* search the session keyring */ |
439 | if (context->signal->session_keyring) { | 441 | if (context->signal->session_keyring) { |
440 | rcu_read_lock(); | 442 | rcu_read_lock(); |
441 | key = keyring_search_aux( | 443 | key_ref = keyring_search_aux( |
442 | rcu_dereference(context->signal->session_keyring), | 444 | make_key_ref(rcu_dereference( |
445 | context->signal->session_keyring), | ||
446 | 1), | ||
443 | context, type, description, match); | 447 | context, type, description, match); |
444 | rcu_read_unlock(); | 448 | rcu_read_unlock(); |
445 | 449 | ||
446 | if (!IS_ERR(key)) | 450 | if (!IS_ERR(key_ref)) |
447 | goto found; | 451 | goto found; |
448 | 452 | ||
449 | switch (PTR_ERR(key)) { | 453 | switch (PTR_ERR(key_ref)) { |
450 | case -EAGAIN: /* no key */ | 454 | case -EAGAIN: /* no key */ |
451 | if (ret) | 455 | if (ret) |
452 | break; | 456 | break; |
453 | case -ENOKEY: /* negative key */ | 457 | case -ENOKEY: /* negative key */ |
454 | ret = key; | 458 | ret = key_ref; |
455 | break; | 459 | break; |
456 | default: | 460 | default: |
457 | err = key; | 461 | err = key_ref; |
458 | break; | 462 | break; |
459 | } | 463 | } |
460 | 464 | ||
@@ -465,51 +469,54 @@ struct key *search_process_keyrings(struct key_type *type, | |||
465 | goto no_key; | 469 | goto no_key; |
466 | 470 | ||
467 | rcu_read_lock(); | 471 | rcu_read_lock(); |
468 | instkey = __keyring_search_one( | 472 | instkey_ref = __keyring_search_one( |
469 | rcu_dereference(context->signal->session_keyring), | 473 | make_key_ref(rcu_dereference( |
474 | context->signal->session_keyring), | ||
475 | 1), | ||
470 | &key_type_request_key_auth, NULL, 0); | 476 | &key_type_request_key_auth, NULL, 0); |
471 | rcu_read_unlock(); | 477 | rcu_read_unlock(); |
472 | 478 | ||
473 | if (IS_ERR(instkey)) | 479 | if (IS_ERR(instkey_ref)) |
474 | goto no_key; | 480 | goto no_key; |
475 | 481 | ||
476 | rka = instkey->payload.data; | 482 | rka = key_ref_to_ptr(instkey_ref)->payload.data; |
477 | 483 | ||
478 | key = search_process_keyrings(type, description, match, | 484 | key_ref = search_process_keyrings(type, description, match, |
479 | rka->context); | 485 | rka->context); |
480 | key_put(instkey); | 486 | key_ref_put(instkey_ref); |
481 | 487 | ||
482 | if (!IS_ERR(key)) | 488 | if (!IS_ERR(key_ref)) |
483 | goto found; | 489 | goto found; |
484 | 490 | ||
485 | switch (PTR_ERR(key)) { | 491 | switch (PTR_ERR(key_ref)) { |
486 | case -EAGAIN: /* no key */ | 492 | case -EAGAIN: /* no key */ |
487 | if (ret) | 493 | if (ret) |
488 | break; | 494 | break; |
489 | case -ENOKEY: /* negative key */ | 495 | case -ENOKEY: /* negative key */ |
490 | ret = key; | 496 | ret = key_ref; |
491 | break; | 497 | break; |
492 | default: | 498 | default: |
493 | err = key; | 499 | err = key_ref; |
494 | break; | 500 | break; |
495 | } | 501 | } |
496 | } | 502 | } |
497 | /* or search the user-session keyring */ | 503 | /* or search the user-session keyring */ |
498 | else { | 504 | else { |
499 | key = keyring_search_aux(context->user->session_keyring, | 505 | key_ref = keyring_search_aux( |
500 | context, type, description, match); | 506 | make_key_ref(context->user->session_keyring, 1), |
501 | if (!IS_ERR(key)) | 507 | context, type, description, match); |
508 | if (!IS_ERR(key_ref)) | ||
502 | goto found; | 509 | goto found; |
503 | 510 | ||
504 | switch (PTR_ERR(key)) { | 511 | switch (PTR_ERR(key_ref)) { |
505 | case -EAGAIN: /* no key */ | 512 | case -EAGAIN: /* no key */ |
506 | if (ret) | 513 | if (ret) |
507 | break; | 514 | break; |
508 | case -ENOKEY: /* negative key */ | 515 | case -ENOKEY: /* negative key */ |
509 | ret = key; | 516 | ret = key_ref; |
510 | break; | 517 | break; |
511 | default: | 518 | default: |
512 | err = key; | 519 | err = key_ref; |
513 | break; | 520 | break; |
514 | } | 521 | } |
515 | } | 522 | } |
@@ -517,29 +524,40 @@ struct key *search_process_keyrings(struct key_type *type, | |||
517 | 524 | ||
518 | no_key: | 525 | no_key: |
519 | /* no key - decide on the error we're going to go for */ | 526 | /* no key - decide on the error we're going to go for */ |
520 | key = ret ? ret : err; | 527 | key_ref = ret ? ret : err; |
521 | 528 | ||
522 | found: | 529 | found: |
523 | return key; | 530 | return key_ref; |
524 | 531 | ||
525 | } /* end search_process_keyrings() */ | 532 | } /* end search_process_keyrings() */ |
526 | 533 | ||
527 | /*****************************************************************************/ | 534 | /*****************************************************************************/ |
528 | /* | 535 | /* |
536 | * see if the key we're looking at is the target key | ||
537 | */ | ||
538 | static int lookup_user_key_possessed(const struct key *key, const void *target) | ||
539 | { | ||
540 | return key == target; | ||
541 | |||
542 | } /* end lookup_user_key_possessed() */ | ||
543 | |||
544 | /*****************************************************************************/ | ||
545 | /* | ||
529 | * lookup a key given a key ID from userspace with a given permissions mask | 546 | * lookup a key given a key ID from userspace with a given permissions mask |
530 | * - don't create special keyrings unless so requested | 547 | * - don't create special keyrings unless so requested |
531 | * - partially constructed keys aren't found unless requested | 548 | * - partially constructed keys aren't found unless requested |
532 | */ | 549 | */ |
533 | struct key *lookup_user_key(struct task_struct *context, key_serial_t id, | 550 | key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id, |
534 | int create, int partial, key_perm_t perm) | 551 | int create, int partial, key_perm_t perm) |
535 | { | 552 | { |
553 | key_ref_t key_ref, skey_ref; | ||
536 | struct key *key; | 554 | struct key *key; |
537 | int ret; | 555 | int ret; |
538 | 556 | ||
539 | if (!context) | 557 | if (!context) |
540 | context = current; | 558 | context = current; |
541 | 559 | ||
542 | key = ERR_PTR(-ENOKEY); | 560 | key_ref = ERR_PTR(-ENOKEY); |
543 | 561 | ||
544 | switch (id) { | 562 | switch (id) { |
545 | case KEY_SPEC_THREAD_KEYRING: | 563 | case KEY_SPEC_THREAD_KEYRING: |
@@ -556,6 +574,7 @@ struct key *lookup_user_key(struct task_struct *context, key_serial_t id, | |||
556 | 574 | ||
557 | key = context->thread_keyring; | 575 | key = context->thread_keyring; |
558 | atomic_inc(&key->usage); | 576 | atomic_inc(&key->usage); |
577 | key_ref = make_key_ref(key, 1); | ||
559 | break; | 578 | break; |
560 | 579 | ||
561 | case KEY_SPEC_PROCESS_KEYRING: | 580 | case KEY_SPEC_PROCESS_KEYRING: |
@@ -572,6 +591,7 @@ struct key *lookup_user_key(struct task_struct *context, key_serial_t id, | |||
572 | 591 | ||
573 | key = context->signal->process_keyring; | 592 | key = context->signal->process_keyring; |
574 | atomic_inc(&key->usage); | 593 | atomic_inc(&key->usage); |
594 | key_ref = make_key_ref(key, 1); | ||
575 | break; | 595 | break; |
576 | 596 | ||
577 | case KEY_SPEC_SESSION_KEYRING: | 597 | case KEY_SPEC_SESSION_KEYRING: |
@@ -579,7 +599,7 @@ struct key *lookup_user_key(struct task_struct *context, key_serial_t id, | |||
579 | /* always install a session keyring upon access if one | 599 | /* always install a session keyring upon access if one |
580 | * doesn't exist yet */ | 600 | * doesn't exist yet */ |
581 | ret = install_session_keyring( | 601 | ret = install_session_keyring( |
582 | context, context->user->session_keyring); | 602 | context, context->user->session_keyring); |
583 | if (ret < 0) | 603 | if (ret < 0) |
584 | goto error; | 604 | goto error; |
585 | } | 605 | } |
@@ -588,16 +608,19 @@ struct key *lookup_user_key(struct task_struct *context, key_serial_t id, | |||
588 | key = rcu_dereference(context->signal->session_keyring); | 608 | key = rcu_dereference(context->signal->session_keyring); |
589 | atomic_inc(&key->usage); | 609 | atomic_inc(&key->usage); |
590 | rcu_read_unlock(); | 610 | rcu_read_unlock(); |
611 | key_ref = make_key_ref(key, 1); | ||
591 | break; | 612 | break; |
592 | 613 | ||
593 | case KEY_SPEC_USER_KEYRING: | 614 | case KEY_SPEC_USER_KEYRING: |
594 | key = context->user->uid_keyring; | 615 | key = context->user->uid_keyring; |
595 | atomic_inc(&key->usage); | 616 | atomic_inc(&key->usage); |
617 | key_ref = make_key_ref(key, 1); | ||
596 | break; | 618 | break; |
597 | 619 | ||
598 | case KEY_SPEC_USER_SESSION_KEYRING: | 620 | case KEY_SPEC_USER_SESSION_KEYRING: |
599 | key = context->user->session_keyring; | 621 | key = context->user->session_keyring; |
600 | atomic_inc(&key->usage); | 622 | atomic_inc(&key->usage); |
623 | key_ref = make_key_ref(key, 1); | ||
601 | break; | 624 | break; |
602 | 625 | ||
603 | case KEY_SPEC_GROUP_KEYRING: | 626 | case KEY_SPEC_GROUP_KEYRING: |
@@ -606,13 +629,28 @@ struct key *lookup_user_key(struct task_struct *context, key_serial_t id, | |||
606 | goto error; | 629 | goto error; |
607 | 630 | ||
608 | default: | 631 | default: |
609 | key = ERR_PTR(-EINVAL); | 632 | key_ref = ERR_PTR(-EINVAL); |
610 | if (id < 1) | 633 | if (id < 1) |
611 | goto error; | 634 | goto error; |
612 | 635 | ||
613 | key = key_lookup(id); | 636 | key = key_lookup(id); |
614 | if (IS_ERR(key)) | 637 | if (IS_ERR(key)) { |
638 | key_ref = ERR_PTR(PTR_ERR(key)); | ||
615 | goto error; | 639 | goto error; |
640 | } | ||
641 | |||
642 | key_ref = make_key_ref(key, 0); | ||
643 | |||
644 | /* check to see if we possess the key */ | ||
645 | skey_ref = search_process_keyrings(key->type, key, | ||
646 | lookup_user_key_possessed, | ||
647 | current); | ||
648 | |||
649 | if (!IS_ERR(skey_ref)) { | ||
650 | key_put(key); | ||
651 | key_ref = skey_ref; | ||
652 | } | ||
653 | |||
616 | break; | 654 | break; |
617 | } | 655 | } |
618 | 656 | ||
@@ -630,15 +668,15 @@ struct key *lookup_user_key(struct task_struct *context, key_serial_t id, | |||
630 | /* check the permissions */ | 668 | /* check the permissions */ |
631 | ret = -EACCES; | 669 | ret = -EACCES; |
632 | 670 | ||
633 | if (!key_task_permission(key, context, perm)) | 671 | if (!key_task_permission(key_ref, context, perm)) |
634 | goto invalid_key; | 672 | goto invalid_key; |
635 | 673 | ||
636 | error: | 674 | error: |
637 | return key; | 675 | return key_ref; |
638 | 676 | ||
639 | invalid_key: | 677 | invalid_key: |
640 | key_put(key); | 678 | key_ref_put(key_ref); |
641 | key = ERR_PTR(ret); | 679 | key_ref = ERR_PTR(ret); |
642 | goto error; | 680 | goto error; |
643 | 681 | ||
644 | } /* end lookup_user_key() */ | 682 | } /* end lookup_user_key() */ |
@@ -694,9 +732,9 @@ long join_session_keyring(const char *name) | |||
694 | ret = keyring->serial; | 732 | ret = keyring->serial; |
695 | key_put(keyring); | 733 | key_put(keyring); |
696 | 734 | ||
697 | error2: | 735 | error2: |
698 | up(&key_session_sem); | 736 | up(&key_session_sem); |
699 | error: | 737 | error: |
700 | return ret; | 738 | return ret; |
701 | 739 | ||
702 | } /* end join_session_keyring() */ | 740 | } /* end join_session_keyring() */ |
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 90c1506d007c..e6dd366d43a3 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -129,7 +129,7 @@ static struct key *__request_key_construction(struct key_type *type, | |||
129 | 129 | ||
130 | /* create a key and add it to the queue */ | 130 | /* create a key and add it to the queue */ |
131 | key = key_alloc(type, description, | 131 | key = key_alloc(type, description, |
132 | current->fsuid, current->fsgid, KEY_USR_ALL, 0); | 132 | current->fsuid, current->fsgid, KEY_POS_ALL, 0); |
133 | if (IS_ERR(key)) | 133 | if (IS_ERR(key)) |
134 | goto alloc_failed; | 134 | goto alloc_failed; |
135 | 135 | ||
@@ -365,14 +365,24 @@ struct key *request_key_and_link(struct key_type *type, | |||
365 | { | 365 | { |
366 | struct key_user *user; | 366 | struct key_user *user; |
367 | struct key *key; | 367 | struct key *key; |
368 | key_ref_t key_ref; | ||
368 | 369 | ||
369 | kenter("%s,%s,%s,%p", | 370 | kenter("%s,%s,%s,%p", |
370 | type->name, description, callout_info, dest_keyring); | 371 | type->name, description, callout_info, dest_keyring); |
371 | 372 | ||
372 | /* search all the process keyrings for a key */ | 373 | /* search all the process keyrings for a key */ |
373 | key = search_process_keyrings(type, description, type->match, current); | 374 | key_ref = search_process_keyrings(type, description, type->match, |
375 | current); | ||
374 | 376 | ||
375 | if (PTR_ERR(key) == -EAGAIN) { | 377 | kdebug("search 1: %p", key_ref); |
378 | |||
379 | if (!IS_ERR(key_ref)) { | ||
380 | key = key_ref_to_ptr(key_ref); | ||
381 | } | ||
382 | else if (PTR_ERR(key_ref) != -EAGAIN) { | ||
383 | key = ERR_PTR(PTR_ERR(key_ref)); | ||
384 | } | ||
385 | else { | ||
376 | /* the search failed, but the keyrings were searchable, so we | 386 | /* the search failed, but the keyrings were searchable, so we |
377 | * should consult userspace if we can */ | 387 | * should consult userspace if we can */ |
378 | key = ERR_PTR(-ENOKEY); | 388 | key = ERR_PTR(-ENOKEY); |
@@ -384,7 +394,7 @@ struct key *request_key_and_link(struct key_type *type, | |||
384 | if (!user) | 394 | if (!user) |
385 | goto nomem; | 395 | goto nomem; |
386 | 396 | ||
387 | do { | 397 | for (;;) { |
388 | if (signal_pending(current)) | 398 | if (signal_pending(current)) |
389 | goto interrupted; | 399 | goto interrupted; |
390 | 400 | ||
@@ -397,10 +407,22 @@ struct key *request_key_and_link(struct key_type *type, | |||
397 | 407 | ||
398 | /* someone else made the key we want, so we need to | 408 | /* someone else made the key we want, so we need to |
399 | * search again as it might now be available to us */ | 409 | * search again as it might now be available to us */ |
400 | key = search_process_keyrings(type, description, | 410 | key_ref = search_process_keyrings(type, description, |
401 | type->match, current); | 411 | type->match, |
412 | current); | ||
413 | |||
414 | kdebug("search 2: %p", key_ref); | ||
402 | 415 | ||
403 | } while (PTR_ERR(key) == -EAGAIN); | 416 | if (!IS_ERR(key_ref)) { |
417 | key = key_ref_to_ptr(key_ref); | ||
418 | break; | ||
419 | } | ||
420 | |||
421 | if (PTR_ERR(key_ref) != -EAGAIN) { | ||
422 | key = ERR_PTR(PTR_ERR(key_ref)); | ||
423 | break; | ||
424 | } | ||
425 | } | ||
404 | 426 | ||
405 | key_user_put(user); | 427 | key_user_put(user); |
406 | 428 | ||
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index f22264632229..1ecd3d3fa9f8 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c | |||
@@ -126,7 +126,7 @@ struct key *request_key_auth_new(struct key *target, struct key **_rkakey) | |||
126 | 126 | ||
127 | rkakey = key_alloc(&key_type_request_key_auth, desc, | 127 | rkakey = key_alloc(&key_type_request_key_auth, desc, |
128 | current->fsuid, current->fsgid, | 128 | current->fsuid, current->fsgid, |
129 | KEY_USR_VIEW, 1); | 129 | KEY_POS_VIEW | KEY_USR_VIEW, 1); |
130 | if (IS_ERR(rkakey)) { | 130 | if (IS_ERR(rkakey)) { |
131 | key_put(keyring); | 131 | key_put(keyring); |
132 | kleave("= %ld", PTR_ERR(rkakey)); | 132 | kleave("= %ld", PTR_ERR(rkakey)); |