diff options
643 files changed, 15098 insertions, 5955 deletions
diff --git a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl index 15ce0f21e5e0..320af25de3a2 100644 --- a/Documentation/DocBook/usb.tmpl +++ b/Documentation/DocBook/usb.tmpl | |||
@@ -253,6 +253,7 @@ | |||
253 | !Edrivers/usb/core/urb.c | 253 | !Edrivers/usb/core/urb.c |
254 | !Edrivers/usb/core/message.c | 254 | !Edrivers/usb/core/message.c |
255 | !Edrivers/usb/core/file.c | 255 | !Edrivers/usb/core/file.c |
256 | !Edrivers/usb/core/driver.c | ||
256 | !Edrivers/usb/core/usb.c | 257 | !Edrivers/usb/core/usb.c |
257 | !Edrivers/usb/core/hub.c | 258 | !Edrivers/usb/core/hub.c |
258 | </chapter> | 259 | </chapter> |
diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt index 933fae74c337..f4b8dc4237e6 100644 --- a/Documentation/cpu-freq/governors.txt +++ b/Documentation/cpu-freq/governors.txt | |||
@@ -27,6 +27,7 @@ Contents: | |||
27 | 2.2 Powersave | 27 | 2.2 Powersave |
28 | 2.3 Userspace | 28 | 2.3 Userspace |
29 | 2.4 Ondemand | 29 | 2.4 Ondemand |
30 | 2.5 Conservative | ||
30 | 31 | ||
31 | 3. The Governor Interface in the CPUfreq Core | 32 | 3. The Governor Interface in the CPUfreq Core |
32 | 33 | ||
@@ -110,9 +111,64 @@ directory. | |||
110 | 111 | ||
111 | The CPUfreq govenor "ondemand" sets the CPU depending on the | 112 | The CPUfreq govenor "ondemand" sets the CPU depending on the |
112 | current usage. To do this the CPU must have the capability to | 113 | current usage. To do this the CPU must have the capability to |
113 | switch the frequency very fast. | 114 | switch the frequency very quickly. There are a number of sysfs file |
114 | 115 | accessible parameters: | |
115 | 116 | ||
117 | sampling_rate: measured in uS (10^-6 seconds), this is how often you | ||
118 | want the kernel to look at the CPU usage and to make decisions on | ||
119 | what to do about the frequency. Typically this is set to values of | ||
120 | around '10000' or more. | ||
121 | |||
122 | show_sampling_rate_(min|max): the minimum and maximum sampling rates | ||
123 | available that you may set 'sampling_rate' to. | ||
124 | |||
125 | up_threshold: defines what the average CPU usaged between the samplings | ||
126 | of 'sampling_rate' needs to be for the kernel to make a decision on | ||
127 | whether it should increase the frequency. For example when it is set | ||
128 | to its default value of '80' it means that between the checking | ||
129 | intervals the CPU needs to be on average more than 80% in use to then | ||
130 | decide that the CPU frequency needs to be increased. | ||
131 | |||
132 | sampling_down_factor: this parameter controls the rate that the CPU | ||
133 | makes a decision on when to decrease the frequency. When set to its | ||
134 | default value of '5' it means that at 1/5 the sampling_rate the kernel | ||
135 | makes a decision to lower the frequency. Five "lower rate" decisions | ||
136 | have to be made in a row before the CPU frequency is actually lower. | ||
137 | If set to '1' then the frequency decreases as quickly as it increases, | ||
138 | if set to '2' it decreases at half the rate of the increase. | ||
139 | |||
140 | ignore_nice_load: this parameter takes a value of '0' or '1', when set | ||
141 | to '0' (its default) then all processes are counted towards towards the | ||
142 | 'cpu utilisation' value. When set to '1' then processes that are | ||
143 | run with a 'nice' value will not count (and thus be ignored) in the | ||
144 | overal usage calculation. This is useful if you are running a CPU | ||
145 | intensive calculation on your laptop that you do not care how long it | ||
146 | takes to complete as you can 'nice' it and prevent it from taking part | ||
147 | in the deciding process of whether to increase your CPU frequency. | ||
148 | |||
149 | |||
150 | 2.5 Conservative | ||
151 | ---------------- | ||
152 | |||
153 | The CPUfreq governor "conservative", much like the "ondemand" | ||
154 | governor, sets the CPU depending on the current usage. It differs in | ||
155 | behaviour in that it gracefully increases and decreases the CPU speed | ||
156 | rather than jumping to max speed the moment there is any load on the | ||
157 | CPU. This behaviour more suitable in a battery powered environment. | ||
158 | The governor is tweaked in the same manner as the "ondemand" governor | ||
159 | through sysfs with the addition of: | ||
160 | |||
161 | freq_step: this describes what percentage steps the cpu freq should be | ||
162 | increased and decreased smoothly by. By default the cpu frequency will | ||
163 | increase in 5% chunks of your maximum cpu frequency. You can change this | ||
164 | value to anywhere between 0 and 100 where '0' will effectively lock your | ||
165 | CPU at a speed regardless of its load whilst '100' will, in theory, make | ||
166 | it behave identically to the "ondemand" governor. | ||
167 | |||
168 | down_threshold: same as the 'up_threshold' found for the "ondemand" | ||
169 | governor but for the opposite direction. For example when set to its | ||
170 | default value of '20' it means that if the CPU usage needs to be below | ||
171 | 20% between samples to have the frequency decreased. | ||
116 | 172 | ||
117 | 3. The Governor Interface in the CPUfreq Core | 173 | 3. The Governor Interface in the CPUfreq Core |
118 | ============================================= | 174 | ============================================= |
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index ebc09a159f62..2b7cf19a06ad 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
@@ -46,6 +46,29 @@ ipfrag_secret_interval - INTEGER | |||
46 | for the hash secret) for IP fragments. | 46 | for the hash secret) for IP fragments. |
47 | Default: 600 | 47 | Default: 600 |
48 | 48 | ||
49 | ipfrag_max_dist - INTEGER | ||
50 | ipfrag_max_dist is a non-negative integer value which defines the | ||
51 | maximum "disorder" which is allowed among fragments which share a | ||
52 | common IP source address. Note that reordering of packets is | ||
53 | not unusual, but if a large number of fragments arrive from a source | ||
54 | IP address while a particular fragment queue remains incomplete, it | ||
55 | probably indicates that one or more fragments belonging to that queue | ||
56 | have been lost. When ipfrag_max_dist is positive, an additional check | ||
57 | is done on fragments before they are added to a reassembly queue - if | ||
58 | ipfrag_max_dist (or more) fragments have arrived from a particular IP | ||
59 | address between additions to any IP fragment queue using that source | ||
60 | address, it's presumed that one or more fragments in the queue are | ||
61 | lost. The existing fragment queue will be dropped, and a new one | ||
62 | started. An ipfrag_max_dist value of zero disables this check. | ||
63 | |||
64 | Using a very small value, e.g. 1 or 2, for ipfrag_max_dist can | ||
65 | result in unnecessarily dropping fragment queues when normal | ||
66 | reordering of packets occurs, which could lead to poor application | ||
67 | performance. Using a very large value, e.g. 50000, increases the | ||
68 | likelihood of incorrectly reassembling IP fragments that originate | ||
69 | from different IP datagrams, which could result in data corruption. | ||
70 | Default: 64 | ||
71 | |||
49 | INET peer storage: | 72 | INET peer storage: |
50 | 73 | ||
51 | inet_peer_threshold - INTEGER | 74 | inet_peer_threshold - INTEGER |
diff --git a/MAINTAINERS b/MAINTAINERS index da6973adacda..3fd7687a6ad9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -536,7 +536,7 @@ P: Mauro Carvalho Chehab | |||
536 | M: mchehab@brturbo.com.br | 536 | M: mchehab@brturbo.com.br |
537 | L: video4linux-list@redhat.com | 537 | L: video4linux-list@redhat.com |
538 | W: http://linuxtv.org | 538 | W: http://linuxtv.org |
539 | T: quilt http://www.linuxtv.org/download/quilt/ | 539 | T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git |
540 | S: Maintained | 540 | S: Maintained |
541 | 541 | ||
542 | BUSLOGIC SCSI DRIVER | 542 | BUSLOGIC SCSI DRIVER |
@@ -834,7 +834,7 @@ P: LinuxTV.org Project | |||
834 | M: linux-dvb-maintainer@linuxtv.org | 834 | M: linux-dvb-maintainer@linuxtv.org |
835 | L: linux-dvb@linuxtv.org (subscription required) | 835 | L: linux-dvb@linuxtv.org (subscription required) |
836 | W: http://linuxtv.org/ | 836 | W: http://linuxtv.org/ |
837 | T: quilt http://www.linuxtv.org/download/quilt/ | 837 | T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git |
838 | S: Supported | 838 | S: Supported |
839 | 839 | ||
840 | EATA-DMA SCSI DRIVER | 840 | EATA-DMA SCSI DRIVER |
@@ -2640,6 +2640,12 @@ L: linux-usb-users@lists.sourceforge.net | |||
2640 | L: linux-usb-devel@lists.sourceforge.net | 2640 | L: linux-usb-devel@lists.sourceforge.net |
2641 | S: Maintained | 2641 | S: Maintained |
2642 | 2642 | ||
2643 | USB ISP116X DRIVER | ||
2644 | P: Olav Kongas | ||
2645 | M: ok@artecdesign.ee | ||
2646 | L: linux-usb-devel@lists.sourceforge.net | ||
2647 | S: Maintained | ||
2648 | |||
2643 | USB KAWASAKI LSI DRIVER | 2649 | USB KAWASAKI LSI DRIVER |
2644 | P: Oliver Neukum | 2650 | P: Oliver Neukum |
2645 | M: oliver@neukum.name | 2651 | M: oliver@neukum.name |
@@ -2651,7 +2657,7 @@ USB MASS STORAGE DRIVER | |||
2651 | P: Matthew Dharm | 2657 | P: Matthew Dharm |
2652 | M: mdharm-usb@one-eyed-alien.net | 2658 | M: mdharm-usb@one-eyed-alien.net |
2653 | L: linux-usb-users@lists.sourceforge.net | 2659 | L: linux-usb-users@lists.sourceforge.net |
2654 | L: linux-usb-devel@lists.sourceforge.net | 2660 | L: usb-storage@lists.one-eyed-alien.net |
2655 | S: Maintained | 2661 | S: Maintained |
2656 | W: http://www.one-eyed-alien.net/~mdharm/linux-usb/ | 2662 | W: http://www.one-eyed-alien.net/~mdharm/linux-usb/ |
2657 | 2663 | ||
@@ -2896,7 +2902,7 @@ P: Mauro Carvalho Chehab | |||
2896 | M: mchehab@brturbo.com.br | 2902 | M: mchehab@brturbo.com.br |
2897 | L: video4linux-list@redhat.com | 2903 | L: video4linux-list@redhat.com |
2898 | W: http://linuxtv.org | 2904 | W: http://linuxtv.org |
2899 | T: quilt http://www.linuxtv.org/download/quilt/ | 2905 | T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git |
2900 | S: Maintained | 2906 | S: Maintained |
2901 | 2907 | ||
2902 | W1 DALLAS'S 1-WIRE BUS | 2908 | W1 DALLAS'S 1-WIRE BUS |
@@ -1,8 +1,8 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 15 | 3 | SUBLEVEL = 15 |
4 | EXTRAVERSION =-rc5 | 4 | EXTRAVERSION = |
5 | NAME=Affluent Albatross | 5 | NAME=Sliding Snow Leopard |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
8 | # To see a list of typical targets execute "make help" | 8 | # To see a list of typical targets execute "make help" |
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 2ad4aa2a1536..55076a75e5bf 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
@@ -131,7 +131,7 @@ __syscall_start: | |||
131 | .long sys_wait4 | 131 | .long sys_wait4 |
132 | /* 115 */ .long sys_swapoff | 132 | /* 115 */ .long sys_swapoff |
133 | .long sys_sysinfo | 133 | .long sys_sysinfo |
134 | .long sys_ipc_wrapper | 134 | .long sys_ipc |
135 | .long sys_fsync | 135 | .long sys_fsync |
136 | .long sys_sigreturn_wrapper | 136 | .long sys_sigreturn_wrapper |
137 | /* 120 */ .long sys_clone_wrapper | 137 | /* 120 */ .long sys_clone_wrapper |
@@ -254,7 +254,7 @@ __syscall_start: | |||
254 | .long sys_fremovexattr | 254 | .long sys_fremovexattr |
255 | .long sys_tkill | 255 | .long sys_tkill |
256 | .long sys_sendfile64 | 256 | .long sys_sendfile64 |
257 | /* 240 */ .long sys_futex_wrapper | 257 | /* 240 */ .long sys_futex |
258 | .long sys_sched_setaffinity | 258 | .long sys_sched_setaffinity |
259 | .long sys_sched_getaffinity | 259 | .long sys_sched_getaffinity |
260 | .long sys_io_setup | 260 | .long sys_io_setup |
@@ -284,7 +284,7 @@ __syscall_start: | |||
284 | .long sys_fstatfs64 | 284 | .long sys_fstatfs64 |
285 | .long sys_tgkill | 285 | .long sys_tgkill |
286 | .long sys_utimes | 286 | .long sys_utimes |
287 | /* 270 */ .long sys_arm_fadvise64_64_wrapper | 287 | /* 270 */ .long sys_arm_fadvise64_64 |
288 | .long sys_pciconfig_iobase | 288 | .long sys_pciconfig_iobase |
289 | .long sys_pciconfig_read | 289 | .long sys_pciconfig_read |
290 | .long sys_pciconfig_write | 290 | .long sys_pciconfig_write |
@@ -333,7 +333,7 @@ __syscall_start: | |||
333 | .long sys_inotify_init | 333 | .long sys_inotify_init |
334 | .long sys_inotify_add_watch | 334 | .long sys_inotify_add_watch |
335 | .long sys_inotify_rm_watch | 335 | .long sys_inotify_rm_watch |
336 | .long sys_mbind_wrapper | 336 | .long sys_mbind |
337 | /* 320 */ .long sys_get_mempolicy | 337 | /* 320 */ .long sys_get_mempolicy |
338 | .long sys_set_mempolicy | 338 | .long sys_set_mempolicy |
339 | __syscall_end: | 339 | __syscall_end: |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index d9fb819bf7cc..2a8d27e18fa7 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -614,6 +614,47 @@ __kuser_helper_start: | |||
614 | /* | 614 | /* |
615 | * Reference prototype: | 615 | * Reference prototype: |
616 | * | 616 | * |
617 | * void __kernel_memory_barrier(void) | ||
618 | * | ||
619 | * Input: | ||
620 | * | ||
621 | * lr = return address | ||
622 | * | ||
623 | * Output: | ||
624 | * | ||
625 | * none | ||
626 | * | ||
627 | * Clobbered: | ||
628 | * | ||
629 | * the Z flag might be lost | ||
630 | * | ||
631 | * Definition and user space usage example: | ||
632 | * | ||
633 | * typedef void (__kernel_dmb_t)(void); | ||
634 | * #define __kernel_dmb (*(__kernel_dmb_t *)0xffff0fa0) | ||
635 | * | ||
636 | * Apply any needed memory barrier to preserve consistency with data modified | ||
637 | * manually and __kuser_cmpxchg usage. | ||
638 | * | ||
639 | * This could be used as follows: | ||
640 | * | ||
641 | * #define __kernel_dmb() \ | ||
642 | * asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \ | ||
643 | * : : : "lr","cc" ) | ||
644 | */ | ||
645 | |||
646 | __kuser_memory_barrier: @ 0xffff0fa0 | ||
647 | |||
648 | #if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_SMP) | ||
649 | mcr p15, 0, r0, c7, c10, 5 @ dmb | ||
650 | #endif | ||
651 | mov pc, lr | ||
652 | |||
653 | .align 5 | ||
654 | |||
655 | /* | ||
656 | * Reference prototype: | ||
657 | * | ||
617 | * int __kernel_cmpxchg(int oldval, int newval, int *ptr) | 658 | * int __kernel_cmpxchg(int oldval, int newval, int *ptr) |
618 | * | 659 | * |
619 | * Input: | 660 | * Input: |
@@ -642,6 +683,8 @@ __kuser_helper_start: | |||
642 | * The C flag is also set if *ptr was changed to allow for assembly | 683 | * The C flag is also set if *ptr was changed to allow for assembly |
643 | * optimization in the calling code. | 684 | * optimization in the calling code. |
644 | * | 685 | * |
686 | * Note: this routine already includes memory barriers as needed. | ||
687 | * | ||
645 | * For example, a user space atomic_add implementation could look like this: | 688 | * For example, a user space atomic_add implementation could look like this: |
646 | * | 689 | * |
647 | * #define atomic_add(ptr, val) \ | 690 | * #define atomic_add(ptr, val) \ |
@@ -698,10 +741,16 @@ __kuser_cmpxchg: @ 0xffff0fc0 | |||
698 | 741 | ||
699 | #else | 742 | #else |
700 | 743 | ||
744 | #ifdef CONFIG_SMP | ||
745 | mcr p15, 0, r0, c7, c10, 5 @ dmb | ||
746 | #endif | ||
701 | ldrex r3, [r2] | 747 | ldrex r3, [r2] |
702 | subs r3, r3, r0 | 748 | subs r3, r3, r0 |
703 | strexeq r3, r1, [r2] | 749 | strexeq r3, r1, [r2] |
704 | rsbs r0, r3, #0 | 750 | rsbs r0, r3, #0 |
751 | #ifdef CONFIG_SMP | ||
752 | mcr p15, 0, r0, c7, c10, 5 @ dmb | ||
753 | #endif | ||
705 | mov pc, lr | 754 | mov pc, lr |
706 | 755 | ||
707 | #endif | 756 | #endif |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index f7f183075237..e2b42997ad33 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -145,7 +145,7 @@ ENTRY(vector_swi) | |||
145 | #endif | 145 | #endif |
146 | enable_irq | 146 | enable_irq |
147 | 147 | ||
148 | str r4, [sp, #-S_OFF]! @ push fifth arg | 148 | stmdb sp!, {r4, r5} @ push fifth and sixth args |
149 | 149 | ||
150 | get_thread_info tsk | 150 | get_thread_info tsk |
151 | ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing | 151 | ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing |
@@ -204,7 +204,7 @@ ENTRY(sys_call_table) | |||
204 | * Special system call wrappers | 204 | * Special system call wrappers |
205 | */ | 205 | */ |
206 | @ r0 = syscall number | 206 | @ r0 = syscall number |
207 | @ r5 = syscall table | 207 | @ r8 = syscall table |
208 | .type sys_syscall, #function | 208 | .type sys_syscall, #function |
209 | sys_syscall: | 209 | sys_syscall: |
210 | eor scno, r0, #__NR_SYSCALL_BASE | 210 | eor scno, r0, #__NR_SYSCALL_BASE |
@@ -255,22 +255,6 @@ sys_sigaltstack_wrapper: | |||
255 | ldr r2, [sp, #S_OFF + S_SP] | 255 | ldr r2, [sp, #S_OFF + S_SP] |
256 | b do_sigaltstack | 256 | b do_sigaltstack |
257 | 257 | ||
258 | sys_futex_wrapper: | ||
259 | str r5, [sp, #4] @ push sixth arg | ||
260 | b sys_futex | ||
261 | |||
262 | sys_arm_fadvise64_64_wrapper: | ||
263 | str r5, [sp, #4] @ push r5 to stack | ||
264 | b sys_arm_fadvise64_64 | ||
265 | |||
266 | sys_mbind_wrapper: | ||
267 | str r5, [sp, #4] | ||
268 | b sys_mbind | ||
269 | |||
270 | sys_ipc_wrapper: | ||
271 | str r5, [sp, #4] @ push sixth arg | ||
272 | b sys_ipc | ||
273 | |||
274 | /* | 258 | /* |
275 | * Note: off_4k (r5) is always units of 4K. If we can't do the requested | 259 | * Note: off_4k (r5) is always units of 4K. If we can't do the requested |
276 | * offset, we return EINVAL. | 260 | * offset, we return EINVAL. |
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 07892f4012d8..277498ae5b6c 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <asm/arch/pxafb.h> | 43 | #include <asm/arch/pxafb.h> |
44 | #include <asm/arch/mmc.h> | 44 | #include <asm/arch/mmc.h> |
45 | #include <asm/arch/irda.h> | 45 | #include <asm/arch/irda.h> |
46 | #include <asm/arch/ohci.h> | ||
46 | 47 | ||
47 | #include "generic.h" | 48 | #include "generic.h" |
48 | 49 | ||
@@ -393,6 +394,25 @@ static struct platform_device *platform_devices[] __initdata = { | |||
393 | &mst_flash_device[1], | 394 | &mst_flash_device[1], |
394 | }; | 395 | }; |
395 | 396 | ||
397 | static int mainstone_ohci_init(struct device *dev) | ||
398 | { | ||
399 | /* setup Port1 GPIO pin. */ | ||
400 | pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */ | ||
401 | pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */ | ||
402 | |||
403 | /* Set the Power Control Polarity Low and Power Sense | ||
404 | Polarity Low to active low. */ | ||
405 | UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) & | ||
406 | ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); | ||
407 | |||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | static struct pxaohci_platform_data mainstone_ohci_platform_data = { | ||
412 | .port_mode = PMM_PERPORT_MODE, | ||
413 | .init = mainstone_ohci_init, | ||
414 | }; | ||
415 | |||
396 | static void __init mainstone_init(void) | 416 | static void __init mainstone_init(void) |
397 | { | 417 | { |
398 | int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */ | 418 | int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */ |
@@ -424,6 +444,7 @@ static void __init mainstone_init(void) | |||
424 | 444 | ||
425 | pxa_set_mci_info(&mainstone_mci_platform_data); | 445 | pxa_set_mci_info(&mainstone_mci_platform_data); |
426 | pxa_set_ficp_info(&mainstone_ficp_platform_data); | 446 | pxa_set_ficp_info(&mainstone_ficp_platform_data); |
447 | pxa_set_ohci_info(&mainstone_ohci_platform_data); | ||
427 | } | 448 | } |
428 | 449 | ||
429 | 450 | ||
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index c722a9a91fcc..b41b1efaa2cf 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/hardware.h> | 21 | #include <asm/hardware.h> |
22 | #include <asm/irq.h> | 22 | #include <asm/irq.h> |
23 | #include <asm/arch/pxa-regs.h> | 23 | #include <asm/arch/pxa-regs.h> |
24 | #include <asm/arch/ohci.h> | ||
24 | 25 | ||
25 | #include "generic.h" | 26 | #include "generic.h" |
26 | 27 | ||
@@ -194,6 +195,11 @@ static struct platform_device ohci_device = { | |||
194 | .resource = pxa27x_ohci_resources, | 195 | .resource = pxa27x_ohci_resources, |
195 | }; | 196 | }; |
196 | 197 | ||
198 | void __init pxa_set_ohci_info(struct pxaohci_platform_data *info) | ||
199 | { | ||
200 | ohci_device.dev.platform_data = info; | ||
201 | } | ||
202 | |||
197 | static struct platform_device *devices[] __initdata = { | 203 | static struct platform_device *devices[] __initdata = { |
198 | &ohci_device, | 204 | &ohci_device, |
199 | }; | 205 | }; |
diff --git a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c index 04a405345203..2b62dee35c6c 100644 --- a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c +++ b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c | |||
@@ -177,9 +177,10 @@ static unsigned int nforce2_fsb_read(int bootfsb) | |||
177 | */ | 177 | */ |
178 | static int nforce2_set_fsb(unsigned int fsb) | 178 | static int nforce2_set_fsb(unsigned int fsb) |
179 | { | 179 | { |
180 | u32 pll, temp = 0; | 180 | u32 temp = 0; |
181 | unsigned int tfsb; | 181 | unsigned int tfsb; |
182 | int diff; | 182 | int diff; |
183 | int pll = 0; | ||
183 | 184 | ||
184 | if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) { | 185 | if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) { |
185 | printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb); | 186 | printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb); |
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 68a1fc87f4ca..0fbbd4c1072e 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -45,7 +45,7 @@ | |||
45 | 45 | ||
46 | #define PFX "powernow-k8: " | 46 | #define PFX "powernow-k8: " |
47 | #define BFX PFX "BIOS error: " | 47 | #define BFX PFX "BIOS error: " |
48 | #define VERSION "version 1.50.4" | 48 | #define VERSION "version 1.60.0" |
49 | #include "powernow-k8.h" | 49 | #include "powernow-k8.h" |
50 | 50 | ||
51 | /* serialize freq changes */ | 51 | /* serialize freq changes */ |
@@ -216,10 +216,10 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid) | |||
216 | 216 | ||
217 | do { | 217 | do { |
218 | wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS); | 218 | wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS); |
219 | if (i++ > 100) { | 219 | if (i++ > 100) { |
220 | printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n"); | 220 | printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n"); |
221 | return 1; | 221 | return 1; |
222 | } | 222 | } |
223 | } while (query_current_values_with_pending_wait(data)); | 223 | } while (query_current_values_with_pending_wait(data)); |
224 | 224 | ||
225 | if (savefid != data->currfid) { | 225 | if (savefid != data->currfid) { |
@@ -336,7 +336,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid | |||
336 | /* Phase 2 - core frequency transition */ | 336 | /* Phase 2 - core frequency transition */ |
337 | static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) | 337 | static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) |
338 | { | 338 | { |
339 | u32 vcoreqfid, vcocurrfid, vcofiddiff, savevid = data->currvid; | 339 | u32 vcoreqfid, vcocurrfid, vcofiddiff, fid_interval, savevid = data->currvid; |
340 | 340 | ||
341 | if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) { | 341 | if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) { |
342 | printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n", | 342 | printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n", |
@@ -359,9 +359,11 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) | |||
359 | : vcoreqfid - vcocurrfid; | 359 | : vcoreqfid - vcocurrfid; |
360 | 360 | ||
361 | while (vcofiddiff > 2) { | 361 | while (vcofiddiff > 2) { |
362 | (data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2); | ||
363 | |||
362 | if (reqfid > data->currfid) { | 364 | if (reqfid > data->currfid) { |
363 | if (data->currfid > LO_FID_TABLE_TOP) { | 365 | if (data->currfid > LO_FID_TABLE_TOP) { |
364 | if (write_new_fid(data, data->currfid + 2)) { | 366 | if (write_new_fid(data, data->currfid + fid_interval)) { |
365 | return 1; | 367 | return 1; |
366 | } | 368 | } |
367 | } else { | 369 | } else { |
@@ -371,7 +373,7 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) | |||
371 | } | 373 | } |
372 | } | 374 | } |
373 | } else { | 375 | } else { |
374 | if (write_new_fid(data, data->currfid - 2)) | 376 | if (write_new_fid(data, data->currfid - fid_interval)) |
375 | return 1; | 377 | return 1; |
376 | } | 378 | } |
377 | 379 | ||
@@ -464,7 +466,7 @@ static int check_supported_cpu(unsigned int cpu) | |||
464 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 466 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); |
465 | 467 | ||
466 | if (smp_processor_id() != cpu) { | 468 | if (smp_processor_id() != cpu) { |
467 | printk(KERN_ERR "limiting to cpu %u failed\n", cpu); | 469 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", cpu); |
468 | goto out; | 470 | goto out; |
469 | } | 471 | } |
470 | 472 | ||
@@ -474,7 +476,7 @@ static int check_supported_cpu(unsigned int cpu) | |||
474 | eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); | 476 | eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); |
475 | if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || | 477 | if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || |
476 | ((eax & CPUID_XFAM) != CPUID_XFAM_K8) || | 478 | ((eax & CPUID_XFAM) != CPUID_XFAM_K8) || |
477 | ((eax & CPUID_XMOD) > CPUID_XMOD_REV_F)) { | 479 | ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) { |
478 | printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); | 480 | printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); |
479 | goto out; | 481 | goto out; |
480 | } | 482 | } |
@@ -517,22 +519,24 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8 | |||
517 | printk(KERN_ERR BFX "maxvid exceeded with pstate %d\n", j); | 519 | printk(KERN_ERR BFX "maxvid exceeded with pstate %d\n", j); |
518 | return -ENODEV; | 520 | return -ENODEV; |
519 | } | 521 | } |
520 | if ((pst[j].fid > MAX_FID) | 522 | if (pst[j].fid > MAX_FID) { |
521 | || (pst[j].fid & 1) | 523 | printk(KERN_ERR BFX "maxfid exceeded with pstate %d\n", j); |
522 | || (j && (pst[j].fid < HI_FID_TABLE_BOTTOM))) { | 524 | return -ENODEV; |
525 | } | ||
526 | if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) { | ||
523 | /* Only first fid is allowed to be in "low" range */ | 527 | /* Only first fid is allowed to be in "low" range */ |
524 | printk(KERN_ERR PFX "two low fids - %d : 0x%x\n", j, pst[j].fid); | 528 | printk(KERN_ERR BFX "two low fids - %d : 0x%x\n", j, pst[j].fid); |
525 | return -EINVAL; | 529 | return -EINVAL; |
526 | } | 530 | } |
527 | if (pst[j].fid < lastfid) | 531 | if (pst[j].fid < lastfid) |
528 | lastfid = pst[j].fid; | 532 | lastfid = pst[j].fid; |
529 | } | 533 | } |
530 | if (lastfid & 1) { | 534 | if (lastfid & 1) { |
531 | printk(KERN_ERR PFX "lastfid invalid\n"); | 535 | printk(KERN_ERR BFX "lastfid invalid\n"); |
532 | return -EINVAL; | 536 | return -EINVAL; |
533 | } | 537 | } |
534 | if (lastfid > LO_FID_TABLE_TOP) | 538 | if (lastfid > LO_FID_TABLE_TOP) |
535 | printk(KERN_INFO PFX "first fid not from lo freq table\n"); | 539 | printk(KERN_INFO BFX "first fid not from lo freq table\n"); |
536 | 540 | ||
537 | return 0; | 541 | return 0; |
538 | } | 542 | } |
@@ -631,7 +635,7 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
631 | 635 | ||
632 | dprintk("table vers: 0x%x\n", psb->tableversion); | 636 | dprintk("table vers: 0x%x\n", psb->tableversion); |
633 | if (psb->tableversion != PSB_VERSION_1_4) { | 637 | if (psb->tableversion != PSB_VERSION_1_4) { |
634 | printk(KERN_INFO BFX "PSB table is not v1.4\n"); | 638 | printk(KERN_ERR BFX "PSB table is not v1.4\n"); |
635 | return -ENODEV; | 639 | return -ENODEV; |
636 | } | 640 | } |
637 | 641 | ||
@@ -689,7 +693,7 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
689 | * BIOS and Kernel Developer's Guide, which is available on | 693 | * BIOS and Kernel Developer's Guide, which is available on |
690 | * www.amd.com | 694 | * www.amd.com |
691 | */ | 695 | */ |
692 | printk(KERN_INFO PFX "BIOS error - no PSB or ACPI _PSS objects\n"); | 696 | printk(KERN_ERR PFX "BIOS error - no PSB or ACPI _PSS objects\n"); |
693 | return -ENODEV; | 697 | return -ENODEV; |
694 | } | 698 | } |
695 | 699 | ||
@@ -912,7 +916,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
912 | set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); | 916 | set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); |
913 | 917 | ||
914 | if (smp_processor_id() != pol->cpu) { | 918 | if (smp_processor_id() != pol->cpu) { |
915 | printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu); | 919 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); |
916 | goto err_out; | 920 | goto err_out; |
917 | } | 921 | } |
918 | 922 | ||
@@ -982,6 +986,9 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
982 | cpumask_t oldmask = CPU_MASK_ALL; | 986 | cpumask_t oldmask = CPU_MASK_ALL; |
983 | int rc, i; | 987 | int rc, i; |
984 | 988 | ||
989 | if (!cpu_online(pol->cpu)) | ||
990 | return -ENODEV; | ||
991 | |||
985 | if (!check_supported_cpu(pol->cpu)) | 992 | if (!check_supported_cpu(pol->cpu)) |
986 | return -ENODEV; | 993 | return -ENODEV; |
987 | 994 | ||
@@ -1021,7 +1028,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1021 | set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); | 1028 | set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); |
1022 | 1029 | ||
1023 | if (smp_processor_id() != pol->cpu) { | 1030 | if (smp_processor_id() != pol->cpu) { |
1024 | printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu); | 1031 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); |
1025 | goto err_out; | 1032 | goto err_out; |
1026 | } | 1033 | } |
1027 | 1034 | ||
@@ -1162,10 +1169,9 @@ static void __exit powernowk8_exit(void) | |||
1162 | cpufreq_unregister_driver(&cpufreq_amd64_driver); | 1169 | cpufreq_unregister_driver(&cpufreq_amd64_driver); |
1163 | } | 1170 | } |
1164 | 1171 | ||
1165 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com."); | 1172 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com>"); |
1166 | MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); | 1173 | MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); |
1167 | MODULE_LICENSE("GPL"); | 1174 | MODULE_LICENSE("GPL"); |
1168 | 1175 | ||
1169 | late_initcall(powernowk8_init); | 1176 | late_initcall(powernowk8_init); |
1170 | module_exit(powernowk8_exit); | 1177 | module_exit(powernowk8_exit); |
1171 | |||
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h index b1e85bb36396..d0de37d58e9a 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h | |||
@@ -42,7 +42,7 @@ struct powernow_k8_data { | |||
42 | #define CPUID_XFAM 0x0ff00000 /* extended family */ | 42 | #define CPUID_XFAM 0x0ff00000 /* extended family */ |
43 | #define CPUID_XFAM_K8 0 | 43 | #define CPUID_XFAM_K8 0 |
44 | #define CPUID_XMOD 0x000f0000 /* extended model */ | 44 | #define CPUID_XMOD 0x000f0000 /* extended model */ |
45 | #define CPUID_XMOD_REV_F 0x00040000 | 45 | #define CPUID_XMOD_REV_G 0x00060000 |
46 | #define CPUID_USE_XFAM_XMOD 0x00000f00 | 46 | #define CPUID_USE_XFAM_XMOD 0x00000f00 |
47 | #define CPUID_GET_MAX_CAPABILITIES 0x80000000 | 47 | #define CPUID_GET_MAX_CAPABILITIES 0x80000000 |
48 | #define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007 | 48 | #define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007 |
@@ -86,13 +86,14 @@ struct powernow_k8_data { | |||
86 | * low fid table | 86 | * low fid table |
87 | * - lowest entry in the high fid table must be a <= 200MHz + 2 * the entry | 87 | * - lowest entry in the high fid table must be a <= 200MHz + 2 * the entry |
88 | * in the low fid table | 88 | * in the low fid table |
89 | * - the parts can only step at 200 MHz intervals, so 1.9 GHz is never valid | 89 | * - the parts can only step at <= 200 MHz intervals, odd fid values are |
90 | * supported in revision G and later revisions. | ||
90 | * - lowest frequency must be >= interprocessor hypertransport link speed | 91 | * - lowest frequency must be >= interprocessor hypertransport link speed |
91 | * (only applies to MP systems obviously) | 92 | * (only applies to MP systems obviously) |
92 | */ | 93 | */ |
93 | 94 | ||
94 | /* fids (frequency identifiers) are arranged in 2 tables - lo and hi */ | 95 | /* fids (frequency identifiers) are arranged in 2 tables - lo and hi */ |
95 | #define LO_FID_TABLE_TOP 6 /* fid values marking the boundary */ | 96 | #define LO_FID_TABLE_TOP 7 /* fid values marking the boundary */ |
96 | #define HI_FID_TABLE_BOTTOM 8 /* between the low and high tables */ | 97 | #define HI_FID_TABLE_BOTTOM 8 /* between the low and high tables */ |
97 | 98 | ||
98 | #define LO_VCOFREQ_TABLE_TOP 1400 /* corresponding vco frequency values */ | 99 | #define LO_VCOFREQ_TABLE_TOP 1400 /* corresponding vco frequency values */ |
@@ -106,7 +107,7 @@ struct powernow_k8_data { | |||
106 | #define MIN_FREQ 800 /* Min and max freqs, per spec */ | 107 | #define MIN_FREQ 800 /* Min and max freqs, per spec */ |
107 | #define MAX_FREQ 5000 | 108 | #define MAX_FREQ 5000 |
108 | 109 | ||
109 | #define INVALID_FID_MASK 0xffffffc1 /* not a valid fid if these bits are set */ | 110 | #define INVALID_FID_MASK 0xffffffc0 /* not a valid fid if these bits are set */ |
110 | #define INVALID_VID_MASK 0xffffffc0 /* not a valid vid if these bits are set */ | 111 | #define INVALID_VID_MASK 0xffffffc0 /* not a valid vid if these bits are set */ |
111 | 112 | ||
112 | #define VID_OFF 0x3f | 113 | #define VID_OFF 0x3f |
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c index 5b7d18a06afa..b425cd3d1838 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c | |||
@@ -40,6 +40,7 @@ static struct pci_dev *speedstep_chipset_dev; | |||
40 | */ | 40 | */ |
41 | static unsigned int speedstep_processor = 0; | 41 | static unsigned int speedstep_processor = 0; |
42 | 42 | ||
43 | static u32 pmbase; | ||
43 | 44 | ||
44 | /* | 45 | /* |
45 | * There are only two frequency states for each processor. Values | 46 | * There are only two frequency states for each processor. Values |
@@ -56,34 +57,47 @@ static struct cpufreq_frequency_table speedstep_freqs[] = { | |||
56 | 57 | ||
57 | 58 | ||
58 | /** | 59 | /** |
59 | * speedstep_set_state - set the SpeedStep state | 60 | * speedstep_find_register - read the PMBASE address |
60 | * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) | ||
61 | * | 61 | * |
62 | * Tries to change the SpeedStep state. | 62 | * Returns: -ENODEV if no register could be found |
63 | */ | 63 | */ |
64 | static void speedstep_set_state (unsigned int state) | 64 | static int speedstep_find_register (void) |
65 | { | 65 | { |
66 | u32 pmbase; | 66 | if (!speedstep_chipset_dev) |
67 | u8 pm2_blk; | 67 | return -ENODEV; |
68 | u8 value; | ||
69 | unsigned long flags; | ||
70 | |||
71 | if (!speedstep_chipset_dev || (state > 0x1)) | ||
72 | return; | ||
73 | 68 | ||
74 | /* get PMBASE */ | 69 | /* get PMBASE */ |
75 | pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase); | 70 | pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase); |
76 | if (!(pmbase & 0x01)) { | 71 | if (!(pmbase & 0x01)) { |
77 | printk(KERN_ERR "speedstep-ich: could not find speedstep register\n"); | 72 | printk(KERN_ERR "speedstep-ich: could not find speedstep register\n"); |
78 | return; | 73 | return -ENODEV; |
79 | } | 74 | } |
80 | 75 | ||
81 | pmbase &= 0xFFFFFFFE; | 76 | pmbase &= 0xFFFFFFFE; |
82 | if (!pmbase) { | 77 | if (!pmbase) { |
83 | printk(KERN_ERR "speedstep-ich: could not find speedstep register\n"); | 78 | printk(KERN_ERR "speedstep-ich: could not find speedstep register\n"); |
84 | return; | 79 | return -ENODEV; |
85 | } | 80 | } |
86 | 81 | ||
82 | dprintk("pmbase is 0x%x\n", pmbase); | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * speedstep_set_state - set the SpeedStep state | ||
88 | * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) | ||
89 | * | ||
90 | * Tries to change the SpeedStep state. | ||
91 | */ | ||
92 | static void speedstep_set_state (unsigned int state) | ||
93 | { | ||
94 | u8 pm2_blk; | ||
95 | u8 value; | ||
96 | unsigned long flags; | ||
97 | |||
98 | if (state > 0x1) | ||
99 | return; | ||
100 | |||
87 | /* Disable IRQs */ | 101 | /* Disable IRQs */ |
88 | local_irq_save(flags); | 102 | local_irq_save(flags); |
89 | 103 | ||
@@ -315,10 +329,11 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) | |||
315 | cpus_allowed = current->cpus_allowed; | 329 | cpus_allowed = current->cpus_allowed; |
316 | set_cpus_allowed(current, policy->cpus); | 330 | set_cpus_allowed(current, policy->cpus); |
317 | 331 | ||
318 | /* detect low and high frequency */ | 332 | /* detect low and high frequency and transition latency */ |
319 | result = speedstep_get_freqs(speedstep_processor, | 333 | result = speedstep_get_freqs(speedstep_processor, |
320 | &speedstep_freqs[SPEEDSTEP_LOW].frequency, | 334 | &speedstep_freqs[SPEEDSTEP_LOW].frequency, |
321 | &speedstep_freqs[SPEEDSTEP_HIGH].frequency, | 335 | &speedstep_freqs[SPEEDSTEP_HIGH].frequency, |
336 | &policy->cpuinfo.transition_latency, | ||
322 | &speedstep_set_state); | 337 | &speedstep_set_state); |
323 | set_cpus_allowed(current, cpus_allowed); | 338 | set_cpus_allowed(current, cpus_allowed); |
324 | if (result) | 339 | if (result) |
@@ -335,7 +350,6 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) | |||
335 | 350 | ||
336 | /* cpuinfo and default policy values */ | 351 | /* cpuinfo and default policy values */ |
337 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | 352 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; |
338 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | ||
339 | policy->cur = speed; | 353 | policy->cur = speed; |
340 | 354 | ||
341 | result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); | 355 | result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); |
@@ -400,6 +414,9 @@ static int __init speedstep_init(void) | |||
400 | return -EINVAL; | 414 | return -EINVAL; |
401 | } | 415 | } |
402 | 416 | ||
417 | if (speedstep_find_register()) | ||
418 | return -ENODEV; | ||
419 | |||
403 | return cpufreq_register_driver(&speedstep_driver); | 420 | return cpufreq_register_driver(&speedstep_driver); |
404 | } | 421 | } |
405 | 422 | ||
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c index d368b3f5fce8..7c47005a1805 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c | |||
@@ -320,11 +320,13 @@ EXPORT_SYMBOL_GPL(speedstep_detect_processor); | |||
320 | unsigned int speedstep_get_freqs(unsigned int processor, | 320 | unsigned int speedstep_get_freqs(unsigned int processor, |
321 | unsigned int *low_speed, | 321 | unsigned int *low_speed, |
322 | unsigned int *high_speed, | 322 | unsigned int *high_speed, |
323 | unsigned int *transition_latency, | ||
323 | void (*set_state) (unsigned int state)) | 324 | void (*set_state) (unsigned int state)) |
324 | { | 325 | { |
325 | unsigned int prev_speed; | 326 | unsigned int prev_speed; |
326 | unsigned int ret = 0; | 327 | unsigned int ret = 0; |
327 | unsigned long flags; | 328 | unsigned long flags; |
329 | struct timeval tv1, tv2; | ||
328 | 330 | ||
329 | if ((!processor) || (!low_speed) || (!high_speed) || (!set_state)) | 331 | if ((!processor) || (!low_speed) || (!high_speed) || (!set_state)) |
330 | return -EINVAL; | 332 | return -EINVAL; |
@@ -337,7 +339,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
337 | return -EIO; | 339 | return -EIO; |
338 | 340 | ||
339 | dprintk("previous speed is %u\n", prev_speed); | 341 | dprintk("previous speed is %u\n", prev_speed); |
340 | 342 | ||
341 | local_irq_save(flags); | 343 | local_irq_save(flags); |
342 | 344 | ||
343 | /* switch to low state */ | 345 | /* switch to low state */ |
@@ -350,8 +352,17 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
350 | 352 | ||
351 | dprintk("low speed is %u\n", *low_speed); | 353 | dprintk("low speed is %u\n", *low_speed); |
352 | 354 | ||
355 | /* start latency measurement */ | ||
356 | if (transition_latency) | ||
357 | do_gettimeofday(&tv1); | ||
358 | |||
353 | /* switch to high state */ | 359 | /* switch to high state */ |
354 | set_state(SPEEDSTEP_HIGH); | 360 | set_state(SPEEDSTEP_HIGH); |
361 | |||
362 | /* end latency measurement */ | ||
363 | if (transition_latency) | ||
364 | do_gettimeofday(&tv2); | ||
365 | |||
355 | *high_speed = speedstep_get_processor_frequency(processor); | 366 | *high_speed = speedstep_get_processor_frequency(processor); |
356 | if (!*high_speed) { | 367 | if (!*high_speed) { |
357 | ret = -EIO; | 368 | ret = -EIO; |
@@ -369,6 +380,25 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
369 | if (*high_speed != prev_speed) | 380 | if (*high_speed != prev_speed) |
370 | set_state(SPEEDSTEP_LOW); | 381 | set_state(SPEEDSTEP_LOW); |
371 | 382 | ||
383 | if (transition_latency) { | ||
384 | *transition_latency = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC + | ||
385 | tv2.tv_usec - tv1.tv_usec; | ||
386 | dprintk("transition latency is %u uSec\n", *transition_latency); | ||
387 | |||
388 | /* convert uSec to nSec and add 20% for safety reasons */ | ||
389 | *transition_latency *= 1200; | ||
390 | |||
391 | /* check if the latency measurement is too high or too low | ||
392 | * and set it to a safe value (500uSec) in that case | ||
393 | */ | ||
394 | if (*transition_latency > 10000000 || *transition_latency < 50000) { | ||
395 | printk (KERN_WARNING "speedstep: frequency transition measured seems out of " | ||
396 | "range (%u nSec), falling back to a safe one of %u nSec.\n", | ||
397 | *transition_latency, 500000); | ||
398 | *transition_latency = 500000; | ||
399 | } | ||
400 | } | ||
401 | |||
372 | out: | 402 | out: |
373 | local_irq_restore(flags); | 403 | local_irq_restore(flags); |
374 | return (ret); | 404 | return (ret); |
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h index 261a2c9b7f6b..6a727fd3a77e 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h | |||
@@ -44,4 +44,5 @@ extern unsigned int speedstep_get_processor_frequency(unsigned int processor); | |||
44 | extern unsigned int speedstep_get_freqs(unsigned int processor, | 44 | extern unsigned int speedstep_get_freqs(unsigned int processor, |
45 | unsigned int *low_speed, | 45 | unsigned int *low_speed, |
46 | unsigned int *high_speed, | 46 | unsigned int *high_speed, |
47 | unsigned int *transition_latency, | ||
47 | void (*set_state) (unsigned int state)); | 48 | void (*set_state) (unsigned int state)); |
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c index 2718fb6f6aba..28cc5d524afc 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c | |||
@@ -269,6 +269,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) | |||
269 | result = speedstep_get_freqs(speedstep_processor, | 269 | result = speedstep_get_freqs(speedstep_processor, |
270 | &speedstep_freqs[SPEEDSTEP_LOW].frequency, | 270 | &speedstep_freqs[SPEEDSTEP_LOW].frequency, |
271 | &speedstep_freqs[SPEEDSTEP_HIGH].frequency, | 271 | &speedstep_freqs[SPEEDSTEP_HIGH].frequency, |
272 | NULL, | ||
272 | &speedstep_set_state); | 273 | &speedstep_set_state); |
273 | 274 | ||
274 | if (result) { | 275 | if (result) { |
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c index e7921315ae9d..6d91b274589c 100644 --- a/arch/i386/kernel/cpu/proc.c +++ b/arch/i386/kernel/cpu/proc.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/string.h> | 3 | #include <linux/string.h> |
4 | #include <asm/semaphore.h> | 4 | #include <asm/semaphore.h> |
5 | #include <linux/seq_file.h> | 5 | #include <linux/seq_file.h> |
6 | #include <linux/cpufreq.h> | ||
6 | 7 | ||
7 | /* | 8 | /* |
8 | * Get CPU information for use by the procfs. | 9 | * Get CPU information for use by the procfs. |
@@ -86,8 +87,11 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
86 | seq_printf(m, "stepping\t: unknown\n"); | 87 | seq_printf(m, "stepping\t: unknown\n"); |
87 | 88 | ||
88 | if ( cpu_has(c, X86_FEATURE_TSC) ) { | 89 | if ( cpu_has(c, X86_FEATURE_TSC) ) { |
90 | unsigned int freq = cpufreq_quick_get(n); | ||
91 | if (!freq) | ||
92 | freq = cpu_khz; | ||
89 | seq_printf(m, "cpu MHz\t\t: %u.%03u\n", | 93 | seq_printf(m, "cpu MHz\t\t: %u.%03u\n", |
90 | cpu_khz / 1000, (cpu_khz % 1000)); | 94 | freq / 1000, (freq % 1000)); |
91 | } | 95 | } |
92 | 96 | ||
93 | /* Cache size */ | 97 | /* Cache size */ |
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index df6c2bcde067..2333aead0563 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c | |||
@@ -554,7 +554,9 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) | |||
554 | struct pt_regs ptregs; | 554 | struct pt_regs ptregs; |
555 | 555 | ||
556 | ptregs = *(struct pt_regs *) | 556 | ptregs = *(struct pt_regs *) |
557 | ((unsigned long)tsk->thread_info+THREAD_SIZE - sizeof(ptregs)); | 557 | ((unsigned long)tsk->thread_info + |
558 | /* see comments in copy_thread() about -8 */ | ||
559 | THREAD_SIZE - sizeof(ptregs) - 8); | ||
558 | ptregs.xcs &= 0xffff; | 560 | ptregs.xcs &= 0xffff; |
559 | ptregs.xds &= 0xffff; | 561 | ptregs.xds &= 0xffff; |
560 | ptregs.xes &= 0xffff; | 562 | ptregs.xes &= 0xffff; |
diff --git a/arch/i386/pci/Makefile b/arch/i386/pci/Makefile index ead6122dd06d..5461d4d5ea1e 100644 --- a/arch/i386/pci/Makefile +++ b/arch/i386/pci/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | obj-y := i386.o | 1 | obj-y := i386.o |
2 | 2 | ||
3 | obj-$(CONFIG_PCI_BIOS) += pcbios.o | 3 | obj-$(CONFIG_PCI_BIOS) += pcbios.o |
4 | obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o | 4 | obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o |
5 | obj-$(CONFIG_PCI_DIRECT) += direct.o | 5 | obj-$(CONFIG_PCI_DIRECT) += direct.o |
6 | 6 | ||
7 | pci-y := fixup.o | 7 | pci-y := fixup.o |
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 70a9cc132cf7..4bb4d4b0f73a 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -155,7 +155,7 @@ static __init void unreachable_devices(void) | |||
155 | addr = get_base_addr(0, 0, PCI_DEVFN(i, 0)); | 155 | addr = get_base_addr(0, 0, PCI_DEVFN(i, 0)); |
156 | if (addr != 0) | 156 | if (addr != 0) |
157 | pci_exp_set_dev_base(addr, 0, PCI_DEVFN(i, 0)); | 157 | pci_exp_set_dev_base(addr, 0, PCI_DEVFN(i, 0)); |
158 | if (addr == 0 || readl((u32 __iomem *)addr) != val1) | 158 | if (addr == 0 || readl((u32 __iomem *)mmcfg_virt_addr) != val1) |
159 | set_bit(i, fallback_slots); | 159 | set_bit(i, fallback_slots); |
160 | spin_unlock_irqrestore(&pci_config_lock, flags); | 160 | spin_unlock_irqrestore(&pci_config_lock, flags); |
161 | } | 161 | } |
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig index e1924cc9687b..ff8bb3770c9d 100644 --- a/arch/ia64/configs/sn2_defconfig +++ b/arch/ia64/configs/sn2_defconfig | |||
@@ -113,7 +113,7 @@ CONFIG_IOSAPIC=y | |||
113 | CONFIG_IA64_SGI_SN_XP=m | 113 | CONFIG_IA64_SGI_SN_XP=m |
114 | CONFIG_FORCE_MAX_ZONEORDER=17 | 114 | CONFIG_FORCE_MAX_ZONEORDER=17 |
115 | CONFIG_SMP=y | 115 | CONFIG_SMP=y |
116 | CONFIG_NR_CPUS=512 | 116 | CONFIG_NR_CPUS=1024 |
117 | # CONFIG_HOTPLUG_CPU is not set | 117 | # CONFIG_HOTPLUG_CPU is not set |
118 | CONFIG_SCHED_SMT=y | 118 | CONFIG_SCHED_SMT=y |
119 | CONFIG_PREEMPT=y | 119 | CONFIG_PREEMPT=y |
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 5add0bcf87a7..088e5dded8dc 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/initrd.h> | 43 | #include <linux/initrd.h> |
44 | #include <linux/platform.h> | 44 | #include <linux/platform.h> |
45 | #include <linux/pm.h> | 45 | #include <linux/pm.h> |
46 | #include <linux/cpufreq.h> | ||
46 | 47 | ||
47 | #include <asm/ia32.h> | 48 | #include <asm/ia32.h> |
48 | #include <asm/machvec.h> | 49 | #include <asm/machvec.h> |
@@ -517,6 +518,7 @@ show_cpuinfo (struct seq_file *m, void *v) | |||
517 | char family[32], features[128], *cp, sep; | 518 | char family[32], features[128], *cp, sep; |
518 | struct cpuinfo_ia64 *c = v; | 519 | struct cpuinfo_ia64 *c = v; |
519 | unsigned long mask; | 520 | unsigned long mask; |
521 | unsigned int proc_freq; | ||
520 | int i; | 522 | int i; |
521 | 523 | ||
522 | mask = c->features; | 524 | mask = c->features; |
@@ -549,6 +551,10 @@ show_cpuinfo (struct seq_file *m, void *v) | |||
549 | sprintf(cp, " 0x%lx", mask); | 551 | sprintf(cp, " 0x%lx", mask); |
550 | } | 552 | } |
551 | 553 | ||
554 | proc_freq = cpufreq_quick_get(cpunum); | ||
555 | if (!proc_freq) | ||
556 | proc_freq = c->proc_freq / 1000; | ||
557 | |||
552 | seq_printf(m, | 558 | seq_printf(m, |
553 | "processor : %d\n" | 559 | "processor : %d\n" |
554 | "vendor : %s\n" | 560 | "vendor : %s\n" |
@@ -565,7 +571,7 @@ show_cpuinfo (struct seq_file *m, void *v) | |||
565 | "BogoMIPS : %lu.%02lu\n", | 571 | "BogoMIPS : %lu.%02lu\n", |
566 | cpunum, c->vendor, family, c->model, c->revision, c->archrev, | 572 | cpunum, c->vendor, family, c->model, c->revision, c->archrev, |
567 | features, c->ppn, c->number, | 573 | features, c->ppn, c->number, |
568 | c->proc_freq / 1000000, c->proc_freq % 1000000, | 574 | proc_freq / 1000, proc_freq % 1000, |
569 | c->itc_freq / 1000000, c->itc_freq % 1000000, | 575 | c->itc_freq / 1000000, c->itc_freq % 1000000, |
570 | lpj*HZ/500000, (lpj*HZ/5000) % 100); | 576 | lpj*HZ/500000, (lpj*HZ/5000) % 100); |
571 | #ifdef CONFIG_SMP | 577 | #ifdef CONFIG_SMP |
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 5b7e736f3b49..028a2b95936c 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c | |||
@@ -249,3 +249,32 @@ time_init (void) | |||
249 | */ | 249 | */ |
250 | set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); | 250 | set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); |
251 | } | 251 | } |
252 | |||
253 | #define SMALLUSECS 100 | ||
254 | |||
255 | void | ||
256 | udelay (unsigned long usecs) | ||
257 | { | ||
258 | unsigned long start; | ||
259 | unsigned long cycles; | ||
260 | unsigned long smallusecs; | ||
261 | |||
262 | /* | ||
263 | * Execute the non-preemptible delay loop (because the ITC might | ||
264 | * not be synchronized between CPUS) in relatively short time | ||
265 | * chunks, allowing preemption between the chunks. | ||
266 | */ | ||
267 | while (usecs > 0) { | ||
268 | smallusecs = (usecs > SMALLUSECS) ? SMALLUSECS : usecs; | ||
269 | preempt_disable(); | ||
270 | cycles = smallusecs*local_cpu_data->cyc_per_usec; | ||
271 | start = ia64_get_itc(); | ||
272 | |||
273 | while (ia64_get_itc() - start < cycles) | ||
274 | cpu_relax(); | ||
275 | |||
276 | preempt_enable(); | ||
277 | usecs -= smallusecs; | ||
278 | } | ||
279 | } | ||
280 | EXPORT_SYMBOL(udelay); | ||
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c index c6d40446c2c4..b631cf86ed44 100644 --- a/arch/ia64/kernel/uncached.c +++ b/arch/ia64/kernel/uncached.c | |||
@@ -53,7 +53,7 @@ static void uncached_ipi_visibility(void *data) | |||
53 | if ((status != PAL_VISIBILITY_OK) && | 53 | if ((status != PAL_VISIBILITY_OK) && |
54 | (status != PAL_VISIBILITY_OK_REMOTE_NEEDED)) | 54 | (status != PAL_VISIBILITY_OK_REMOTE_NEEDED)) |
55 | printk(KERN_DEBUG "pal_prefetch_visibility() returns %i on " | 55 | printk(KERN_DEBUG "pal_prefetch_visibility() returns %i on " |
56 | "CPU %i\n", status, get_cpu()); | 56 | "CPU %i\n", status, raw_smp_processor_id()); |
57 | } | 57 | } |
58 | 58 | ||
59 | 59 | ||
@@ -63,7 +63,7 @@ static void uncached_ipi_mc_drain(void *data) | |||
63 | status = ia64_pal_mc_drain(); | 63 | status = ia64_pal_mc_drain(); |
64 | if (status) | 64 | if (status) |
65 | printk(KERN_WARNING "ia64_pal_mc_drain() failed with %i on " | 65 | printk(KERN_WARNING "ia64_pal_mc_drain() failed with %i on " |
66 | "CPU %i\n", status, get_cpu()); | 66 | "CPU %i\n", status, raw_smp_processor_id()); |
67 | } | 67 | } |
68 | 68 | ||
69 | 69 | ||
@@ -105,7 +105,7 @@ uncached_get_new_chunk(struct gen_pool *poolp) | |||
105 | status = ia64_pal_prefetch_visibility(PAL_VISIBILITY_PHYSICAL); | 105 | status = ia64_pal_prefetch_visibility(PAL_VISIBILITY_PHYSICAL); |
106 | 106 | ||
107 | dprintk(KERN_INFO "pal_prefetch_visibility() returns %i on cpu %i\n", | 107 | dprintk(KERN_INFO "pal_prefetch_visibility() returns %i on cpu %i\n", |
108 | status, get_cpu()); | 108 | status, raw_smp_processor_id()); |
109 | 109 | ||
110 | if (!status) { | 110 | if (!status) { |
111 | status = smp_call_function(uncached_ipi_visibility, NULL, 0, 1); | 111 | status = smp_call_function(uncached_ipi_visibility, NULL, 0, 1); |
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index 30d8564e9603..73af6267d2ef 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S | |||
@@ -177,6 +177,9 @@ SECTIONS | |||
177 | } | 177 | } |
178 | . = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose kernel data */ | 178 | . = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose kernel data */ |
179 | 179 | ||
180 | .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) | ||
181 | { *(.data.read_mostly) } | ||
182 | |||
180 | .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) | 183 | .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) |
181 | { *(.data.cacheline_aligned) } | 184 | { *(.data.cacheline_aligned) } |
182 | 185 | ||
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c index 5d54f5f4e926..471bbaa65d1b 100644 --- a/arch/ia64/sn/kernel/sn2/sn2_smp.c +++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c | |||
@@ -202,7 +202,7 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, | |||
202 | unsigned long end, unsigned long nbits) | 202 | unsigned long end, unsigned long nbits) |
203 | { | 203 | { |
204 | int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0; | 204 | int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0; |
205 | int mymm = (mm == current->active_mm); | 205 | int mymm = (mm == current->active_mm && current->mm); |
206 | volatile unsigned long *ptc0, *ptc1; | 206 | volatile unsigned long *ptc0, *ptc1; |
207 | unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value; | 207 | unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value; |
208 | short nasids[MAX_NUMNODES], nix; | 208 | short nasids[MAX_NUMNODES], nix; |
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 330cf84d21fe..60353f5acc48 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
@@ -420,7 +420,7 @@ asmlinkage ssize_t sys32_pread(unsigned int fd, char * buf, | |||
420 | goto out; | 420 | goto out; |
421 | pos = merge_64(a4, a5); | 421 | pos = merge_64(a4, a5); |
422 | ret = rw_verify_area(READ, file, &pos, count); | 422 | ret = rw_verify_area(READ, file, &pos, count); |
423 | if (ret) | 423 | if (ret < 0) |
424 | goto out; | 424 | goto out; |
425 | ret = -EINVAL; | 425 | ret = -EINVAL; |
426 | if (!file->f_op || !(read = file->f_op->read)) | 426 | if (!file->f_op || !(read = file->f_op->read)) |
@@ -455,7 +455,7 @@ asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char * buf, | |||
455 | goto out; | 455 | goto out; |
456 | pos = merge_64(a4, a5); | 456 | pos = merge_64(a4, a5); |
457 | ret = rw_verify_area(WRITE, file, &pos, count); | 457 | ret = rw_verify_area(WRITE, file, &pos, count); |
458 | if (ret) | 458 | if (ret < 0) |
459 | goto out; | 459 | goto out; |
460 | ret = -EINVAL; | 460 | ret = -EINVAL; |
461 | if (!file->f_op || !(write = file->f_op->write)) | 461 | if (!file->f_op || !(write = file->f_op->write)) |
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index 4b433411b9e3..b657f7e44762 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.15-rc1 | 3 | # Linux kernel version: 2.6.15-rc5 |
4 | # Tue Nov 15 14:36:20 2005 | 4 | # Tue Dec 20 15:59:26 2005 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | 6 | CONFIG_PPC64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -53,6 +53,7 @@ CONFIG_KOBJECT_UEVENT=y | |||
53 | # CONFIG_IKCONFIG is not set | 53 | # CONFIG_IKCONFIG is not set |
54 | # CONFIG_CPUSETS is not set | 54 | # CONFIG_CPUSETS is not set |
55 | CONFIG_INITRAMFS_SOURCE="" | 55 | CONFIG_INITRAMFS_SOURCE="" |
56 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
56 | # CONFIG_EMBEDDED is not set | 57 | # CONFIG_EMBEDDED is not set |
57 | CONFIG_KALLSYMS=y | 58 | CONFIG_KALLSYMS=y |
58 | # CONFIG_KALLSYMS_ALL is not set | 59 | # CONFIG_KALLSYMS_ALL is not set |
@@ -151,7 +152,7 @@ CONFIG_FLATMEM_MANUAL=y | |||
151 | CONFIG_FLATMEM=y | 152 | CONFIG_FLATMEM=y |
152 | CONFIG_FLAT_NODE_MEM_MAP=y | 153 | CONFIG_FLAT_NODE_MEM_MAP=y |
153 | # CONFIG_SPARSEMEM_STATIC is not set | 154 | # CONFIG_SPARSEMEM_STATIC is not set |
154 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | 155 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
155 | # CONFIG_PPC_64K_PAGES is not set | 156 | # CONFIG_PPC_64K_PAGES is not set |
156 | CONFIG_SCHED_SMT=y | 157 | CONFIG_SCHED_SMT=y |
157 | CONFIG_PROC_DEVICETREE=y | 158 | CONFIG_PROC_DEVICETREE=y |
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index e7c23e3902b8..3c22ccb18519 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.15-rc1 | 3 | # Linux kernel version: 2.6.15-rc5 |
4 | # Tue Nov 15 14:39:20 2005 | 4 | # Tue Dec 20 15:59:30 2005 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | 6 | CONFIG_PPC64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -53,6 +53,7 @@ CONFIG_IKCONFIG=y | |||
53 | CONFIG_IKCONFIG_PROC=y | 53 | CONFIG_IKCONFIG_PROC=y |
54 | # CONFIG_CPUSETS is not set | 54 | # CONFIG_CPUSETS is not set |
55 | CONFIG_INITRAMFS_SOURCE="" | 55 | CONFIG_INITRAMFS_SOURCE="" |
56 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
56 | # CONFIG_EMBEDDED is not set | 57 | # CONFIG_EMBEDDED is not set |
57 | CONFIG_KALLSYMS=y | 58 | CONFIG_KALLSYMS=y |
58 | # CONFIG_KALLSYMS_ALL is not set | 59 | # CONFIG_KALLSYMS_ALL is not set |
@@ -162,7 +163,7 @@ CONFIG_FLATMEM_MANUAL=y | |||
162 | CONFIG_FLATMEM=y | 163 | CONFIG_FLATMEM=y |
163 | CONFIG_FLAT_NODE_MEM_MAP=y | 164 | CONFIG_FLAT_NODE_MEM_MAP=y |
164 | # CONFIG_SPARSEMEM_STATIC is not set | 165 | # CONFIG_SPARSEMEM_STATIC is not set |
165 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | 166 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
166 | # CONFIG_PPC_64K_PAGES is not set | 167 | # CONFIG_PPC_64K_PAGES is not set |
167 | # CONFIG_SCHED_SMT is not set | 168 | # CONFIG_SCHED_SMT is not set |
168 | CONFIG_PROC_DEVICETREE=y | 169 | CONFIG_PROC_DEVICETREE=y |
@@ -1203,6 +1204,7 @@ CONFIG_USB_MON=y | |||
1203 | CONFIG_USB_SERIAL=m | 1204 | CONFIG_USB_SERIAL=m |
1204 | CONFIG_USB_SERIAL_GENERIC=y | 1205 | CONFIG_USB_SERIAL_GENERIC=y |
1205 | # CONFIG_USB_SERIAL_AIRPRIME is not set | 1206 | # CONFIG_USB_SERIAL_AIRPRIME is not set |
1207 | # CONFIG_USB_SERIAL_ANYDATA is not set | ||
1206 | CONFIG_USB_SERIAL_BELKIN=m | 1208 | CONFIG_USB_SERIAL_BELKIN=m |
1207 | CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m | 1209 | CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m |
1208 | # CONFIG_USB_SERIAL_CP2101 is not set | 1210 | # CONFIG_USB_SERIAL_CP2101 is not set |
@@ -1233,7 +1235,6 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y | |||
1233 | CONFIG_USB_SERIAL_KLSI=m | 1235 | CONFIG_USB_SERIAL_KLSI=m |
1234 | CONFIG_USB_SERIAL_KOBIL_SCT=m | 1236 | CONFIG_USB_SERIAL_KOBIL_SCT=m |
1235 | CONFIG_USB_SERIAL_MCT_U232=m | 1237 | CONFIG_USB_SERIAL_MCT_U232=m |
1236 | # CONFIG_USB_SERIAL_NOKIA_DKU2 is not set | ||
1237 | CONFIG_USB_SERIAL_PL2303=m | 1238 | CONFIG_USB_SERIAL_PL2303=m |
1238 | # CONFIG_USB_SERIAL_HP4X is not set | 1239 | # CONFIG_USB_SERIAL_HP4X is not set |
1239 | CONFIG_USB_SERIAL_SAFE=m | 1240 | CONFIG_USB_SERIAL_SAFE=m |
diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig index 5d0866707a75..751a622fb7a7 100644 --- a/arch/powerpc/configs/iseries_defconfig +++ b/arch/powerpc/configs/iseries_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.15-rc1 | 3 | # Linux kernel version: 2.6.15-rc5 |
4 | # Tue Nov 15 14:38:09 2005 | 4 | # Tue Dec 20 15:59:32 2005 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | 6 | CONFIG_PPC64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -55,6 +55,7 @@ CONFIG_IKCONFIG=y | |||
55 | CONFIG_IKCONFIG_PROC=y | 55 | CONFIG_IKCONFIG_PROC=y |
56 | # CONFIG_CPUSETS is not set | 56 | # CONFIG_CPUSETS is not set |
57 | CONFIG_INITRAMFS_SOURCE="" | 57 | CONFIG_INITRAMFS_SOURCE="" |
58 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
58 | # CONFIG_EMBEDDED is not set | 59 | # CONFIG_EMBEDDED is not set |
59 | CONFIG_KALLSYMS=y | 60 | CONFIG_KALLSYMS=y |
60 | # CONFIG_KALLSYMS_ALL is not set | 61 | # CONFIG_KALLSYMS_ALL is not set |
@@ -144,7 +145,7 @@ CONFIG_FLATMEM_MANUAL=y | |||
144 | CONFIG_FLATMEM=y | 145 | CONFIG_FLATMEM=y |
145 | CONFIG_FLAT_NODE_MEM_MAP=y | 146 | CONFIG_FLAT_NODE_MEM_MAP=y |
146 | # CONFIG_SPARSEMEM_STATIC is not set | 147 | # CONFIG_SPARSEMEM_STATIC is not set |
147 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | 148 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
148 | # CONFIG_PPC_64K_PAGES is not set | 149 | # CONFIG_PPC_64K_PAGES is not set |
149 | # CONFIG_SCHED_SMT is not set | 150 | # CONFIG_SCHED_SMT is not set |
150 | CONFIG_PROC_DEVICETREE=y | 151 | CONFIG_PROC_DEVICETREE=y |
diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig index 92e42613ef06..07b6d3d23360 100644 --- a/arch/powerpc/configs/maple_defconfig +++ b/arch/powerpc/configs/maple_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.15-rc1 | 3 | # Linux kernel version: 2.6.15-rc5 |
4 | # Tue Nov 15 14:38:58 2005 | 4 | # Tue Dec 20 15:59:36 2005 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | 6 | CONFIG_PPC64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -53,6 +53,7 @@ CONFIG_IKCONFIG=y | |||
53 | CONFIG_IKCONFIG_PROC=y | 53 | CONFIG_IKCONFIG_PROC=y |
54 | # CONFIG_CPUSETS is not set | 54 | # CONFIG_CPUSETS is not set |
55 | CONFIG_INITRAMFS_SOURCE="" | 55 | CONFIG_INITRAMFS_SOURCE="" |
56 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
56 | # CONFIG_EMBEDDED is not set | 57 | # CONFIG_EMBEDDED is not set |
57 | CONFIG_KALLSYMS=y | 58 | CONFIG_KALLSYMS=y |
58 | CONFIG_KALLSYMS_ALL=y | 59 | CONFIG_KALLSYMS_ALL=y |
@@ -149,7 +150,7 @@ CONFIG_FLATMEM_MANUAL=y | |||
149 | CONFIG_FLATMEM=y | 150 | CONFIG_FLATMEM=y |
150 | CONFIG_FLAT_NODE_MEM_MAP=y | 151 | CONFIG_FLAT_NODE_MEM_MAP=y |
151 | # CONFIG_SPARSEMEM_STATIC is not set | 152 | # CONFIG_SPARSEMEM_STATIC is not set |
152 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | 153 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
153 | # CONFIG_PPC_64K_PAGES is not set | 154 | # CONFIG_PPC_64K_PAGES is not set |
154 | # CONFIG_SCHED_SMT is not set | 155 | # CONFIG_SCHED_SMT is not set |
155 | CONFIG_PROC_DEVICETREE=y | 156 | CONFIG_PROC_DEVICETREE=y |
@@ -242,7 +243,6 @@ CONFIG_TCP_CONG_BIC=y | |||
242 | # QoS and/or fair queueing | 243 | # QoS and/or fair queueing |
243 | # | 244 | # |
244 | # CONFIG_NET_SCHED is not set | 245 | # CONFIG_NET_SCHED is not set |
245 | # CONFIG_NET_CLS_ROUTE is not set | ||
246 | 246 | ||
247 | # | 247 | # |
248 | # Network testing | 248 | # Network testing |
@@ -794,6 +794,7 @@ CONFIG_USB_SERIAL=y | |||
794 | # CONFIG_USB_SERIAL_CONSOLE is not set | 794 | # CONFIG_USB_SERIAL_CONSOLE is not set |
795 | CONFIG_USB_SERIAL_GENERIC=y | 795 | CONFIG_USB_SERIAL_GENERIC=y |
796 | # CONFIG_USB_SERIAL_AIRPRIME is not set | 796 | # CONFIG_USB_SERIAL_AIRPRIME is not set |
797 | # CONFIG_USB_SERIAL_ANYDATA is not set | ||
797 | # CONFIG_USB_SERIAL_BELKIN is not set | 798 | # CONFIG_USB_SERIAL_BELKIN is not set |
798 | # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set | 799 | # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set |
799 | # CONFIG_USB_SERIAL_CP2101 is not set | 800 | # CONFIG_USB_SERIAL_CP2101 is not set |
@@ -824,7 +825,6 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y | |||
824 | # CONFIG_USB_SERIAL_KLSI is not set | 825 | # CONFIG_USB_SERIAL_KLSI is not set |
825 | # CONFIG_USB_SERIAL_KOBIL_SCT is not set | 826 | # CONFIG_USB_SERIAL_KOBIL_SCT is not set |
826 | # CONFIG_USB_SERIAL_MCT_U232 is not set | 827 | # CONFIG_USB_SERIAL_MCT_U232 is not set |
827 | # CONFIG_USB_SERIAL_NOKIA_DKU2 is not set | ||
828 | # CONFIG_USB_SERIAL_PL2303 is not set | 828 | # CONFIG_USB_SERIAL_PL2303 is not set |
829 | # CONFIG_USB_SERIAL_HP4X is not set | 829 | # CONFIG_USB_SERIAL_HP4X is not set |
830 | # CONFIG_USB_SERIAL_SAFE is not set | 830 | # CONFIG_USB_SERIAL_SAFE is not set |
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index b5ba3bbd96fb..509399eab6f5 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.15-rc1 | 3 | # Linux kernel version: 2.6.15-rc5 |
4 | # Fri Nov 18 16:23:24 2005 | 4 | # Tue Dec 20 15:59:38 2005 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | 6 | CONFIG_PPC64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -54,6 +54,7 @@ CONFIG_IKCONFIG=y | |||
54 | CONFIG_IKCONFIG_PROC=y | 54 | CONFIG_IKCONFIG_PROC=y |
55 | CONFIG_CPUSETS=y | 55 | CONFIG_CPUSETS=y |
56 | CONFIG_INITRAMFS_SOURCE="" | 56 | CONFIG_INITRAMFS_SOURCE="" |
57 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
57 | # CONFIG_EMBEDDED is not set | 58 | # CONFIG_EMBEDDED is not set |
58 | CONFIG_KALLSYMS=y | 59 | CONFIG_KALLSYMS=y |
59 | CONFIG_KALLSYMS_ALL=y | 60 | CONFIG_KALLSYMS_ALL=y |
@@ -176,7 +177,7 @@ CONFIG_HAVE_MEMORY_PRESENT=y | |||
176 | # CONFIG_SPARSEMEM_STATIC is not set | 177 | # CONFIG_SPARSEMEM_STATIC is not set |
177 | CONFIG_SPARSEMEM_EXTREME=y | 178 | CONFIG_SPARSEMEM_EXTREME=y |
178 | # CONFIG_MEMORY_HOTPLUG is not set | 179 | # CONFIG_MEMORY_HOTPLUG is not set |
179 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | 180 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
180 | # CONFIG_PPC_64K_PAGES is not set | 181 | # CONFIG_PPC_64K_PAGES is not set |
181 | # CONFIG_SCHED_SMT is not set | 182 | # CONFIG_SCHED_SMT is not set |
182 | CONFIG_PROC_DEVICETREE=y | 183 | CONFIG_PROC_DEVICETREE=y |
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index b589b196eb3f..a50ce0fa9243 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.15-rc1 | 3 | # Linux kernel version: 2.6.15-rc5 |
4 | # Tue Nov 15 14:36:55 2005 | 4 | # Tue Dec 20 15:59:40 2005 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | 6 | CONFIG_PPC64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -55,6 +55,7 @@ CONFIG_IKCONFIG=y | |||
55 | CONFIG_IKCONFIG_PROC=y | 55 | CONFIG_IKCONFIG_PROC=y |
56 | CONFIG_CPUSETS=y | 56 | CONFIG_CPUSETS=y |
57 | CONFIG_INITRAMFS_SOURCE="" | 57 | CONFIG_INITRAMFS_SOURCE="" |
58 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
58 | # CONFIG_EMBEDDED is not set | 59 | # CONFIG_EMBEDDED is not set |
59 | CONFIG_KALLSYMS=y | 60 | CONFIG_KALLSYMS=y |
60 | CONFIG_KALLSYMS_ALL=y | 61 | CONFIG_KALLSYMS_ALL=y |
@@ -163,7 +164,7 @@ CONFIG_HAVE_MEMORY_PRESENT=y | |||
163 | # CONFIG_SPARSEMEM_STATIC is not set | 164 | # CONFIG_SPARSEMEM_STATIC is not set |
164 | CONFIG_SPARSEMEM_EXTREME=y | 165 | CONFIG_SPARSEMEM_EXTREME=y |
165 | # CONFIG_MEMORY_HOTPLUG is not set | 166 | # CONFIG_MEMORY_HOTPLUG is not set |
166 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | 167 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
167 | CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y | 168 | CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y |
168 | # CONFIG_PPC_64K_PAGES is not set | 169 | # CONFIG_PPC_64K_PAGES is not set |
169 | CONFIG_SCHED_SMT=y | 170 | CONFIG_SCHED_SMT=y |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 2d22bf03484e..bce33a38399f 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -183,8 +183,8 @@ syscall_exit_trace_cont: | |||
183 | ld r13,GPR13(r1) /* returning to usermode */ | 183 | ld r13,GPR13(r1) /* returning to usermode */ |
184 | 1: ld r2,GPR2(r1) | 184 | 1: ld r2,GPR2(r1) |
185 | li r12,MSR_RI | 185 | li r12,MSR_RI |
186 | andc r10,r10,r12 | 186 | andc r11,r10,r12 |
187 | mtmsrd r10,1 /* clear MSR.RI */ | 187 | mtmsrd r11,1 /* clear MSR.RI */ |
188 | ld r1,GPR1(r1) | 188 | ld r1,GPR1(r1) |
189 | mtlr r4 | 189 | mtlr r4 |
190 | mtcr r5 | 190 | mtcr r5 |
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index a33583f3b0e7..a606504678bd 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -514,7 +514,7 @@ void __init htab_initialize(void) | |||
514 | #undef KB | 514 | #undef KB |
515 | #undef MB | 515 | #undef MB |
516 | 516 | ||
517 | void __init htab_initialize_secondary(void) | 517 | void htab_initialize_secondary(void) |
518 | { | 518 | { |
519 | if (!platform_is_lpar()) | 519 | if (!platform_is_lpar()) |
520 | mtspr(SPRN_SDR1, _SDR1); | 520 | mtspr(SPRN_SDR1, _SDR1); |
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 72ac18067ece..0377decc0719 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
@@ -48,11 +48,6 @@ static struct hw_interrupt_type xics_pic = { | |||
48 | .set_affinity = xics_set_affinity | 48 | .set_affinity = xics_set_affinity |
49 | }; | 49 | }; |
50 | 50 | ||
51 | static struct hw_interrupt_type xics_8259_pic = { | ||
52 | .typename = " XICS/8259", | ||
53 | .ack = xics_mask_and_ack_irq, | ||
54 | }; | ||
55 | |||
56 | /* This is used to map real irq numbers to virtual */ | 51 | /* This is used to map real irq numbers to virtual */ |
57 | static struct radix_tree_root irq_map = RADIX_TREE_INIT(GFP_ATOMIC); | 52 | static struct radix_tree_root irq_map = RADIX_TREE_INIT(GFP_ATOMIC); |
58 | 53 | ||
@@ -367,12 +362,7 @@ int xics_get_irq(struct pt_regs *regs) | |||
367 | /* for sanity, this had better be < NR_IRQS - 16 */ | 362 | /* for sanity, this had better be < NR_IRQS - 16 */ |
368 | if (vec == xics_irq_8259_cascade_real) { | 363 | if (vec == xics_irq_8259_cascade_real) { |
369 | irq = i8259_irq(regs); | 364 | irq = i8259_irq(regs); |
370 | if (irq == -1) { | 365 | xics_end_irq(irq_offset_up(xics_irq_8259_cascade)); |
371 | /* Spurious cascaded interrupt. Still must ack xics */ | ||
372 | xics_end_irq(irq_offset_up(xics_irq_8259_cascade)); | ||
373 | |||
374 | irq = -1; | ||
375 | } | ||
376 | } else if (vec == XICS_IRQ_SPURIOUS) { | 366 | } else if (vec == XICS_IRQ_SPURIOUS) { |
377 | irq = -1; | 367 | irq = -1; |
378 | } else { | 368 | } else { |
@@ -542,6 +532,7 @@ nextnode: | |||
542 | xics_irq_8259_cascade_real = *ireg; | 532 | xics_irq_8259_cascade_real = *ireg; |
543 | xics_irq_8259_cascade | 533 | xics_irq_8259_cascade |
544 | = virt_irq_create_mapping(xics_irq_8259_cascade_real); | 534 | = virt_irq_create_mapping(xics_irq_8259_cascade_real); |
535 | i8259_init(0, 0); | ||
545 | of_node_put(np); | 536 | of_node_put(np); |
546 | } | 537 | } |
547 | 538 | ||
@@ -565,12 +556,7 @@ nextnode: | |||
565 | #endif /* CONFIG_SMP */ | 556 | #endif /* CONFIG_SMP */ |
566 | } | 557 | } |
567 | 558 | ||
568 | xics_8259_pic.enable = i8259_pic.enable; | 559 | for (i = irq_offset_value(); i < NR_IRQS; ++i) |
569 | xics_8259_pic.disable = i8259_pic.disable; | ||
570 | xics_8259_pic.end = i8259_pic.end; | ||
571 | for (i = 0; i < 16; ++i) | ||
572 | get_irq_desc(i)->handler = &xics_8259_pic; | ||
573 | for (; i < NR_IRQS; ++i) | ||
574 | get_irq_desc(i)->handler = &xics_pic; | 560 | get_irq_desc(i)->handler = &xics_pic; |
575 | 561 | ||
576 | xics_setup_cpu(); | 562 | xics_setup_cpu(); |
@@ -590,7 +576,6 @@ static int __init xics_setup_i8259(void) | |||
590 | no_action, 0, "8259 cascade", NULL)) | 576 | no_action, 0, "8259 cascade", NULL)) |
591 | printk(KERN_ERR "xics_setup_i8259: couldn't get 8259 " | 577 | printk(KERN_ERR "xics_setup_i8259: couldn't get 8259 " |
592 | "cascade\n"); | 578 | "cascade\n"); |
593 | i8259_init(0, 0); | ||
594 | } | 579 | } |
595 | return 0; | 580 | return 0; |
596 | } | 581 | } |
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index d8991b88dc9c..5e8cc5ec6ab5 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c | |||
@@ -130,10 +130,11 @@ mpc85xx_cds_show_cpuinfo(struct seq_file *m) | |||
130 | } | 130 | } |
131 | 131 | ||
132 | #ifdef CONFIG_CPM2 | 132 | #ifdef CONFIG_CPM2 |
133 | static void cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs) | 133 | static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs) |
134 | { | 134 | { |
135 | while((irq = cpm2_get_irq(regs)) >= 0) | 135 | while((irq = cpm2_get_irq(regs)) >= 0) |
136 | __do_IRQ(irq, regs); | 136 | __do_IRQ(irq, regs); |
137 | return IRQ_HANDLED; | ||
137 | } | 138 | } |
138 | 139 | ||
139 | static struct irqaction cpm2_irqaction = { | 140 | static struct irqaction cpm2_irqaction = { |
diff --git a/arch/ppc/syslib/ppc4xx_dma.c b/arch/ppc/syslib/ppc4xx_dma.c index f15e64285f96..05ccd598dd4e 100644 --- a/arch/ppc/syslib/ppc4xx_dma.c +++ b/arch/ppc/syslib/ppc4xx_dma.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include <asm/system.h> | 31 | #include <asm/system.h> |
32 | #include <asm/io.h> | 32 | #include <asm/io.h> |
33 | #include <asm/dma.h> | ||
33 | #include <asm/ppc4xx_dma.h> | 34 | #include <asm/ppc4xx_dma.h> |
34 | 35 | ||
35 | ppc_dma_ch_t dma_channels[MAX_PPC4xx_DMA_CHANNELS]; | 36 | ppc_dma_ch_t dma_channels[MAX_PPC4xx_DMA_CHANNELS]; |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 3cfb8be3ff6d..56c34e7fd4ee 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -55,6 +55,10 @@ config NR_CPUS | |||
55 | depends on SMP | 55 | depends on SMP |
56 | default "32" | 56 | default "32" |
57 | 57 | ||
58 | config SPARC | ||
59 | bool | ||
60 | default y | ||
61 | |||
58 | # Identify this as a Sparc32 build | 62 | # Identify this as a Sparc32 build |
59 | config SPARC32 | 63 | config SPARC32 |
60 | bool | 64 | bool |
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c index 81c894acd0db..d07ae02101ad 100644 --- a/arch/sparc/kernel/sys_sunos.c +++ b/arch/sparc/kernel/sys_sunos.c | |||
@@ -894,7 +894,7 @@ asmlinkage long sunos_sysconf (int name) | |||
894 | ret = ARG_MAX; | 894 | ret = ARG_MAX; |
895 | break; | 895 | break; |
896 | case _SC_CHILD_MAX: | 896 | case _SC_CHILD_MAX: |
897 | ret = CHILD_MAX; | 897 | ret = -1; /* no limit */ |
898 | break; | 898 | break; |
899 | case _SC_CLK_TCK: | 899 | case _SC_CLK_TCK: |
900 | ret = HZ; | 900 | ret = HZ; |
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 38938d2e63aa..346c19a949fd 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S | |||
@@ -85,19 +85,9 @@ SECTIONS | |||
85 | } | 85 | } |
86 | _end = . ; | 86 | _end = . ; |
87 | PROVIDE (end = .); | 87 | PROVIDE (end = .); |
88 | /* Stabs debugging sections. */ | ||
89 | .stab 0 : { *(.stab) } | ||
90 | .stabstr 0 : { *(.stabstr) } | ||
91 | .stab.excl 0 : { *(.stab.excl) } | ||
92 | .stab.exclstr 0 : { *(.stab.exclstr) } | ||
93 | .stab.index 0 : { *(.stab.index) } | ||
94 | .stab.indexstr 0 : { *(.stab.indexstr) } | ||
95 | .comment 0 : { *(.comment) } | ||
96 | .debug 0 : { *(.debug) } | ||
97 | .debug_srcinfo 0 : { *(.debug_srcinfo) } | ||
98 | .debug_aranges 0 : { *(.debug_aranges) } | ||
99 | .debug_pubnames 0 : { *(.debug_pubnames) } | ||
100 | .debug_sfnames 0 : { *(.debug_sfnames) } | ||
101 | .line 0 : { *(.line) } | ||
102 | /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } | 88 | /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } |
89 | |||
90 | STABS_DEBUG | ||
91 | |||
92 | DWARF_DEBUG | ||
103 | } | 93 | } |
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 3fded69b1922..c4b7ad70cd7c 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig | |||
@@ -5,6 +5,10 @@ | |||
5 | 5 | ||
6 | mainmenu "Linux/UltraSPARC Kernel Configuration" | 6 | mainmenu "Linux/UltraSPARC Kernel Configuration" |
7 | 7 | ||
8 | config SPARC | ||
9 | bool | ||
10 | default y | ||
11 | |||
8 | config SPARC64 | 12 | config SPARC64 |
9 | bool | 13 | bool |
10 | default y | 14 | default y |
diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile index 43fe382da078..cad10c5b83d3 100644 --- a/arch/sparc64/Makefile +++ b/arch/sparc64/Makefile | |||
@@ -17,7 +17,6 @@ CC := $(shell if $(CC) -m64 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then | |||
17 | NEW_GCC := $(call cc-option-yn, -m64 -mcmodel=medlow) | 17 | NEW_GCC := $(call cc-option-yn, -m64 -mcmodel=medlow) |
18 | NEW_GAS := $(shell if $(LD) -V 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi) | 18 | NEW_GAS := $(shell if $(LD) -V 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi) |
19 | UNDECLARED_REGS := $(shell if $(CC) -c -x assembler /dev/null -Wa,--help | grep undeclared-regs > /dev/null; then echo y; else echo n; fi; ) | 19 | UNDECLARED_REGS := $(shell if $(CC) -c -x assembler /dev/null -Wa,--help | grep undeclared-regs > /dev/null; then echo y; else echo n; fi; ) |
20 | INLINE_LIMIT := $(call cc-option-yn, -m64 -finline-limit=100000) | ||
21 | 20 | ||
22 | export NEW_GCC | 21 | export NEW_GCC |
23 | 22 | ||
@@ -49,10 +48,6 @@ else | |||
49 | AFLAGS += -m64 -mcpu=ultrasparc $(CC_UNDECL) | 48 | AFLAGS += -m64 -mcpu=ultrasparc $(CC_UNDECL) |
50 | endif | 49 | endif |
51 | 50 | ||
52 | ifeq ($(INLINE_LIMIT),y) | ||
53 | CFLAGS := $(CFLAGS) -finline-limit=100000 | ||
54 | endif | ||
55 | |||
56 | ifeq ($(CONFIG_MCOUNT),y) | 51 | ifeq ($(CONFIG_MCOUNT),y) |
57 | CFLAGS := $(CFLAGS) -pg | 52 | CFLAGS := $(CFLAGS) -pg |
58 | endif | 53 | endif |
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index d0592ed54ea5..bfa4aa68312d 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c | |||
@@ -854,7 +854,7 @@ asmlinkage s32 sunos_sysconf (int name) | |||
854 | ret = ARG_MAX; | 854 | ret = ARG_MAX; |
855 | break; | 855 | break; |
856 | case _SC_CHILD_MAX: | 856 | case _SC_CHILD_MAX: |
857 | ret = CHILD_MAX; | 857 | ret = -1; /* no limit */ |
858 | break; | 858 | break; |
859 | case _SC_CLK_TCK: | 859 | case _SC_CLK_TCK: |
860 | ret = HZ; | 860 | ret = HZ; |
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S index 2af0cf0a8640..467d13a0d5c1 100644 --- a/arch/sparc64/kernel/vmlinux.lds.S +++ b/arch/sparc64/kernel/vmlinux.lds.S | |||
@@ -90,19 +90,9 @@ SECTIONS | |||
90 | } | 90 | } |
91 | _end = . ; | 91 | _end = . ; |
92 | PROVIDE (end = .); | 92 | PROVIDE (end = .); |
93 | /* Stabs debugging sections. */ | ||
94 | .stab 0 : { *(.stab) } | ||
95 | .stabstr 0 : { *(.stabstr) } | ||
96 | .stab.excl 0 : { *(.stab.excl) } | ||
97 | .stab.exclstr 0 : { *(.stab.exclstr) } | ||
98 | .stab.index 0 : { *(.stab.index) } | ||
99 | .stab.indexstr 0 : { *(.stab.indexstr) } | ||
100 | .comment 0 : { *(.comment) } | ||
101 | .debug 0 : { *(.debug) } | ||
102 | .debug_srcinfo 0 : { *(.debug_srcinfo) } | ||
103 | .debug_aranges 0 : { *(.debug_aranges) } | ||
104 | .debug_pubnames 0 : { *(.debug_pubnames) } | ||
105 | .debug_sfnames 0 : { *(.debug_sfnames) } | ||
106 | .line 0 : { *(.line) } | ||
107 | /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } | 93 | /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } |
94 | |||
95 | STABS_DEBUG | ||
96 | |||
97 | DWARF_DEBUG | ||
108 | } | 98 | } |
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c index 302efbcba70e..3ab4677395f2 100644 --- a/arch/sparc64/solaris/misc.c +++ b/arch/sparc64/solaris/misc.c | |||
@@ -353,7 +353,7 @@ asmlinkage int solaris_sysconf(int id) | |||
353 | { | 353 | { |
354 | switch (id) { | 354 | switch (id) { |
355 | case SOLARIS_CONFIG_NGROUPS: return NGROUPS_MAX; | 355 | case SOLARIS_CONFIG_NGROUPS: return NGROUPS_MAX; |
356 | case SOLARIS_CONFIG_CHILD_MAX: return CHILD_MAX; | 356 | case SOLARIS_CONFIG_CHILD_MAX: return -1; /* no limit */ |
357 | case SOLARIS_CONFIG_OPEN_FILES: return OPEN_MAX; | 357 | case SOLARIS_CONFIG_OPEN_FILES: return OPEN_MAX; |
358 | case SOLARIS_CONFIG_POSIX_VER: return 199309; | 358 | case SOLARIS_CONFIG_POSIX_VER: return 199309; |
359 | case SOLARIS_CONFIG_PAGESIZE: return PAGE_SIZE; | 359 | case SOLARIS_CONFIG_PAGESIZE: return PAGE_SIZE; |
diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 563301fe5df8..1eb21de9d1b5 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig | |||
@@ -289,6 +289,8 @@ source "arch/um/Kconfig.net" | |||
289 | 289 | ||
290 | source "drivers/net/Kconfig" | 290 | source "drivers/net/Kconfig" |
291 | 291 | ||
292 | source "drivers/connector/Kconfig" | ||
293 | |||
292 | source "fs/Kconfig" | 294 | source "fs/Kconfig" |
293 | 295 | ||
294 | source "security/Kconfig" | 296 | source "security/Kconfig" |
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 index 4f118d5cc2ee..38df311e75dc 100644 --- a/arch/um/Makefile-x86_64 +++ b/arch/um/Makefile-x86_64 | |||
@@ -12,3 +12,7 @@ CHECKFLAGS += -m64 | |||
12 | 12 | ||
13 | ELF_ARCH := i386:x86-64 | 13 | ELF_ARCH := i386:x86-64 |
14 | ELF_FORMAT := elf64-x86-64 | 14 | ELF_FORMAT := elf64-x86-64 |
15 | |||
16 | # Not on all 64-bit distros /lib is a symlink to /lib64. PLD is an example. | ||
17 | |||
18 | LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64 | ||
diff --git a/arch/um/include/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h index 6ba8cbbe0d36..b492b12b4a10 100644 --- a/arch/um/include/sysdep-i386/stub.h +++ b/arch/um/include/sysdep-i386/stub.h | |||
@@ -6,8 +6,12 @@ | |||
6 | #ifndef __SYSDEP_STUB_H | 6 | #ifndef __SYSDEP_STUB_H |
7 | #define __SYSDEP_STUB_H | 7 | #define __SYSDEP_STUB_H |
8 | 8 | ||
9 | #include <sys/mman.h> | ||
9 | #include <asm/ptrace.h> | 10 | #include <asm/ptrace.h> |
10 | #include <asm/unistd.h> | 11 | #include <asm/unistd.h> |
12 | #include "stub-data.h" | ||
13 | #include "kern_constants.h" | ||
14 | #include "uml-config.h" | ||
11 | 15 | ||
12 | extern void stub_segv_handler(int sig); | 16 | extern void stub_segv_handler(int sig); |
13 | extern void stub_clone_handler(void); | 17 | extern void stub_clone_handler(void); |
@@ -76,23 +80,22 @@ static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, | |||
76 | return ret; | 80 | return ret; |
77 | } | 81 | } |
78 | 82 | ||
79 | static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3, | 83 | static inline void trap_myself(void) |
80 | long arg4, long arg5, long arg6) | ||
81 | { | 84 | { |
82 | long ret; | 85 | __asm("int3"); |
83 | |||
84 | __asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; " | ||
85 | "int $0x80 ; pop %%ebp" | ||
86 | : "=a" (ret) | ||
87 | : "g" (syscall), "b" (arg1), "c" (arg2), "d" (arg3), | ||
88 | "S" (arg4), "D" (arg5), "0" (arg6)); | ||
89 | |||
90 | return ret; | ||
91 | } | 86 | } |
92 | 87 | ||
93 | static inline void trap_myself(void) | 88 | static inline void remap_stack(int fd, unsigned long offset) |
94 | { | 89 | { |
95 | __asm("int3"); | 90 | __asm__ volatile ("movl %%eax,%%ebp ; movl %0,%%eax ; int $0x80 ;" |
91 | "movl %7, %%ebx ; movl %%eax, (%%ebx)" | ||
92 | : : "g" (STUB_MMAP_NR), "b" (UML_CONFIG_STUB_DATA), | ||
93 | "c" (UM_KERN_PAGE_SIZE), | ||
94 | "d" (PROT_READ | PROT_WRITE), | ||
95 | "S" (MAP_FIXED | MAP_SHARED), "D" (fd), | ||
96 | "a" (offset), | ||
97 | "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err) | ||
98 | : "memory"); | ||
96 | } | 99 | } |
97 | 100 | ||
98 | #endif | 101 | #endif |
diff --git a/arch/um/include/sysdep-x86_64/stub.h b/arch/um/include/sysdep-x86_64/stub.h index c41689c13dc9..92e989f81761 100644 --- a/arch/um/include/sysdep-x86_64/stub.h +++ b/arch/um/include/sysdep-x86_64/stub.h | |||
@@ -6,8 +6,12 @@ | |||
6 | #ifndef __SYSDEP_STUB_H | 6 | #ifndef __SYSDEP_STUB_H |
7 | #define __SYSDEP_STUB_H | 7 | #define __SYSDEP_STUB_H |
8 | 8 | ||
9 | #include <sys/mman.h> | ||
9 | #include <asm/unistd.h> | 10 | #include <asm/unistd.h> |
10 | #include <sysdep/ptrace_user.h> | 11 | #include <sysdep/ptrace_user.h> |
12 | #include "stub-data.h" | ||
13 | #include "kern_constants.h" | ||
14 | #include "uml-config.h" | ||
11 | 15 | ||
12 | extern void stub_segv_handler(int sig); | 16 | extern void stub_segv_handler(int sig); |
13 | extern void stub_clone_handler(void); | 17 | extern void stub_clone_handler(void); |
@@ -81,23 +85,23 @@ static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, | |||
81 | return ret; | 85 | return ret; |
82 | } | 86 | } |
83 | 87 | ||
84 | static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3, | 88 | static inline void trap_myself(void) |
85 | long arg4, long arg5, long arg6) | ||
86 | { | 89 | { |
87 | long ret; | 90 | __asm("int3"); |
88 | |||
89 | __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " | ||
90 | "movq %7, %%r9; " __syscall : "=a" (ret) | ||
91 | : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3), | ||
92 | "g" (arg4), "g" (arg5), "g" (arg6) | ||
93 | : __syscall_clobber, "r10", "r8", "r9" ); | ||
94 | |||
95 | return ret; | ||
96 | } | 91 | } |
97 | 92 | ||
98 | static inline void trap_myself(void) | 93 | static inline void remap_stack(long fd, unsigned long offset) |
99 | { | 94 | { |
100 | __asm("int3"); | 95 | __asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; " |
96 | "movq %6, %%r9; " __syscall "; movq %7, %%rbx ; " | ||
97 | "movq %%rax, (%%rbx)": | ||
98 | : "a" (STUB_MMAP_NR), "D" (UML_CONFIG_STUB_DATA), | ||
99 | "S" (UM_KERN_PAGE_SIZE), | ||
100 | "d" (PROT_READ | PROT_WRITE), | ||
101 | "g" (MAP_FIXED | MAP_SHARED), "g" (fd), | ||
102 | "g" (offset), | ||
103 | "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err) | ||
104 | : __syscall_clobber, "r10", "r8", "r9" ); | ||
101 | } | 105 | } |
102 | 106 | ||
103 | #endif | 107 | #endif |
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c index cb37ce9124a6..47b812b3bca8 100644 --- a/arch/um/kernel/skas/clone.c +++ b/arch/um/kernel/skas/clone.c | |||
@@ -18,11 +18,10 @@ | |||
18 | * on some systems. | 18 | * on some systems. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #define STUB_DATA(field) (((struct stub_data *) UML_CONFIG_STUB_DATA)->field) | ||
22 | |||
23 | void __attribute__ ((__section__ (".__syscall_stub"))) | 21 | void __attribute__ ((__section__ (".__syscall_stub"))) |
24 | stub_clone_handler(void) | 22 | stub_clone_handler(void) |
25 | { | 23 | { |
24 | struct stub_data *data = (struct stub_data *) UML_CONFIG_STUB_DATA; | ||
26 | long err; | 25 | long err; |
27 | 26 | ||
28 | err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD, | 27 | err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD, |
@@ -35,17 +34,21 @@ stub_clone_handler(void) | |||
35 | if(err) | 34 | if(err) |
36 | goto out; | 35 | goto out; |
37 | 36 | ||
38 | err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL, | 37 | err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL, |
39 | (long) &STUB_DATA(timer), 0); | 38 | (long) &data->timer, 0); |
40 | if(err) | 39 | if(err) |
41 | goto out; | 40 | goto out; |
42 | 41 | ||
43 | err = stub_syscall6(STUB_MMAP_NR, UML_CONFIG_STUB_DATA, | 42 | remap_stack(data->fd, data->offset); |
44 | UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, | 43 | goto done; |
45 | MAP_FIXED | MAP_SHARED, STUB_DATA(fd), | 44 | |
46 | STUB_DATA(offset)); | ||
47 | out: | 45 | out: |
48 | /* save current result. Parent: pid; child: retcode of mmap */ | 46 | /* save current result. |
49 | STUB_DATA(err) = err; | 47 | * Parent: pid; |
48 | * child: retcode of mmap already saved and it jumps around this | ||
49 | * assignment | ||
50 | */ | ||
51 | data->err = err; | ||
52 | done: | ||
50 | trap_myself(); | 53 | trap_myself(); |
51 | } | 54 | } |
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 37517d49c4ae..29a9e3f43763 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c | |||
@@ -116,16 +116,16 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, | |||
116 | if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { | 116 | if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { |
117 | int exit_with = WEXITSTATUS(status); | 117 | int exit_with = WEXITSTATUS(status); |
118 | if (exit_with == 2) | 118 | if (exit_with == 2) |
119 | printk("check_ptrace : child exited with status 2. " | 119 | printf("check_ptrace : child exited with status 2. " |
120 | "Serious trouble happening! Try updating your " | 120 | "Serious trouble happening! Try updating your " |
121 | "host skas patch!\nDisabling SYSEMU support."); | 121 | "host skas patch!\nDisabling SYSEMU support."); |
122 | printk("check_ptrace : child exited with exitcode %d, while " | 122 | printf("check_ptrace : child exited with exitcode %d, while " |
123 | "expecting %d; status 0x%x", exit_with, | 123 | "expecting %d; status 0x%x", exit_with, |
124 | exitcode, status); | 124 | exitcode, status); |
125 | if (mustpanic) | 125 | if (mustpanic) |
126 | panic("\n"); | 126 | panic("\n"); |
127 | else | 127 | else |
128 | printk("\n"); | 128 | printf("\n"); |
129 | ret = -1; | 129 | ret = -1; |
130 | } | 130 | } |
131 | 131 | ||
@@ -183,7 +183,7 @@ static void __init check_sysemu(void) | |||
183 | void *stack; | 183 | void *stack; |
184 | int pid, n, status, count=0; | 184 | int pid, n, status, count=0; |
185 | 185 | ||
186 | printk("Checking syscall emulation patch for ptrace..."); | 186 | printf("Checking syscall emulation patch for ptrace..."); |
187 | sysemu_supported = 0; | 187 | sysemu_supported = 0; |
188 | pid = start_ptraced_child(&stack); | 188 | pid = start_ptraced_child(&stack); |
189 | 189 | ||
@@ -207,10 +207,10 @@ static void __init check_sysemu(void) | |||
207 | goto fail_stopped; | 207 | goto fail_stopped; |
208 | 208 | ||
209 | sysemu_supported = 1; | 209 | sysemu_supported = 1; |
210 | printk("OK\n"); | 210 | printf("OK\n"); |
211 | set_using_sysemu(!force_sysemu_disabled); | 211 | set_using_sysemu(!force_sysemu_disabled); |
212 | 212 | ||
213 | printk("Checking advanced syscall emulation patch for ptrace..."); | 213 | printf("Checking advanced syscall emulation patch for ptrace..."); |
214 | pid = start_ptraced_child(&stack); | 214 | pid = start_ptraced_child(&stack); |
215 | 215 | ||
216 | if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0, | 216 | if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0, |
@@ -246,7 +246,7 @@ static void __init check_sysemu(void) | |||
246 | goto fail_stopped; | 246 | goto fail_stopped; |
247 | 247 | ||
248 | sysemu_supported = 2; | 248 | sysemu_supported = 2; |
249 | printk("OK\n"); | 249 | printf("OK\n"); |
250 | 250 | ||
251 | if ( !force_sysemu_disabled ) | 251 | if ( !force_sysemu_disabled ) |
252 | set_using_sysemu(sysemu_supported); | 252 | set_using_sysemu(sysemu_supported); |
@@ -255,7 +255,7 @@ static void __init check_sysemu(void) | |||
255 | fail: | 255 | fail: |
256 | stop_ptraced_child(pid, stack, 1, 0); | 256 | stop_ptraced_child(pid, stack, 1, 0); |
257 | fail_stopped: | 257 | fail_stopped: |
258 | printk("missing\n"); | 258 | printf("missing\n"); |
259 | } | 259 | } |
260 | 260 | ||
261 | static void __init check_ptrace(void) | 261 | static void __init check_ptrace(void) |
@@ -263,7 +263,7 @@ static void __init check_ptrace(void) | |||
263 | void *stack; | 263 | void *stack; |
264 | int pid, syscall, n, status; | 264 | int pid, syscall, n, status; |
265 | 265 | ||
266 | printk("Checking that ptrace can change system call numbers..."); | 266 | printf("Checking that ptrace can change system call numbers..."); |
267 | pid = start_ptraced_child(&stack); | 267 | pid = start_ptraced_child(&stack); |
268 | 268 | ||
269 | if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) | 269 | if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) |
@@ -292,7 +292,7 @@ static void __init check_ptrace(void) | |||
292 | } | 292 | } |
293 | } | 293 | } |
294 | stop_ptraced_child(pid, stack, 0, 1); | 294 | stop_ptraced_child(pid, stack, 0, 1); |
295 | printk("OK\n"); | 295 | printf("OK\n"); |
296 | check_sysemu(); | 296 | check_sysemu(); |
297 | } | 297 | } |
298 | 298 | ||
@@ -472,6 +472,8 @@ int can_do_skas(void) | |||
472 | 472 | ||
473 | int have_devanon = 0; | 473 | int have_devanon = 0; |
474 | 474 | ||
475 | /* Runs on boot kernel stack - already safe to use printk. */ | ||
476 | |||
475 | void check_devanon(void) | 477 | void check_devanon(void) |
476 | { | 478 | { |
477 | int fd; | 479 | int fd; |
diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c index 56d3f870926b..8da6ab31152a 100644 --- a/arch/um/os-Linux/user_syms.c +++ b/arch/um/os-Linux/user_syms.c | |||
@@ -34,6 +34,11 @@ EXPORT_SYMBOL(strstr); | |||
34 | int sym(void); \ | 34 | int sym(void); \ |
35 | EXPORT_SYMBOL(sym); | 35 | EXPORT_SYMBOL(sym); |
36 | 36 | ||
37 | extern void readdir64(void) __attribute__((weak)); | ||
38 | EXPORT_SYMBOL(readdir64); | ||
39 | extern void truncate64(void) __attribute__((weak)); | ||
40 | EXPORT_SYMBOL(truncate64); | ||
41 | |||
37 | #ifdef SUBARCH_i386 | 42 | #ifdef SUBARCH_i386 |
38 | EXPORT_SYMBOL(vsyscall_ehdr); | 43 | EXPORT_SYMBOL(vsyscall_ehdr); |
39 | EXPORT_SYMBOL(vsyscall_end); | 44 | EXPORT_SYMBOL(vsyscall_end); |
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index b3fbf125709b..2e41cabd3d93 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules | |||
@@ -21,11 +21,6 @@ define unprofile | |||
21 | endef | 21 | endef |
22 | 22 | ||
23 | 23 | ||
24 | # The stubs and unmap.o can't try to call mcount or update basic block data | ||
25 | define unprofile | ||
26 | $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) | ||
27 | endef | ||
28 | |||
29 | # cmd_make_link checks to see if the $(foo-dir) variable starts with a /. If | 24 | # cmd_make_link checks to see if the $(foo-dir) variable starts with a /. If |
30 | # so, it's considered to be a path relative to $(srcdir) rather than | 25 | # so, it's considered to be a path relative to $(srcdir) rather than |
31 | # $(srcdir)/arch/$(SUBARCH). This is because x86_64 wants to get ldt.c from | 26 | # $(srcdir)/arch/$(SUBARCH). This is because x86_64 wants to get ldt.c from |
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 150059dbee12..f5fd5b0156d0 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile | |||
@@ -1,6 +1,8 @@ | |||
1 | obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ | 1 | obj-y := bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ |
2 | ptrace_user.o semaphore.o signal.o sigcontext.o stub.o stub_segv.o \ | 2 | ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o \ |
3 | syscalls.o sysrq.o sys_call_table.o | 3 | sys_call_table.o |
4 | |||
5 | obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o | ||
4 | 6 | ||
5 | obj-$(CONFIG_HIGHMEM) += highmem.o | 7 | obj-$(CONFIG_HIGHMEM) += highmem.o |
6 | obj-$(CONFIG_MODULES) += module.o | 8 | obj-$(CONFIG_MODULES) += module.o |
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index 00b2025427df..a351091fbd99 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile | |||
@@ -6,8 +6,9 @@ | |||
6 | 6 | ||
7 | #XXX: why into lib-y? | 7 | #XXX: why into lib-y? |
8 | lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o ldt.o mem.o memcpy.o \ | 8 | lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o ldt.o mem.o memcpy.o \ |
9 | ptrace.o ptrace_user.o sigcontext.o signal.o stub.o \ | 9 | ptrace.o ptrace_user.o sigcontext.o signal.o syscalls.o \ |
10 | stub_segv.o syscalls.o syscall_table.o sysrq.o thunk.o | 10 | syscall_table.o sysrq.o thunk.o |
11 | lib-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o | ||
11 | 12 | ||
12 | obj-y := ksyms.o | 13 | obj-y := ksyms.o |
13 | obj-$(CONFIG_MODULES) += module.o um_module.o | 14 | obj-$(CONFIG_MODULES) += module.o um_module.o |
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 750e01dcbdf4..64c4534b930c 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/edd.h> | 42 | #include <linux/edd.h> |
43 | #include <linux/mmzone.h> | 43 | #include <linux/mmzone.h> |
44 | #include <linux/kexec.h> | 44 | #include <linux/kexec.h> |
45 | #include <linux/cpufreq.h> | ||
45 | 46 | ||
46 | #include <asm/mtrr.h> | 47 | #include <asm/mtrr.h> |
47 | #include <asm/uaccess.h> | 48 | #include <asm/uaccess.h> |
@@ -1256,8 +1257,11 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
1256 | seq_printf(m, "stepping\t: unknown\n"); | 1257 | seq_printf(m, "stepping\t: unknown\n"); |
1257 | 1258 | ||
1258 | if (cpu_has(c,X86_FEATURE_TSC)) { | 1259 | if (cpu_has(c,X86_FEATURE_TSC)) { |
1260 | unsigned int freq = cpufreq_quick_get((unsigned)(c-cpu_data)); | ||
1261 | if (!freq) | ||
1262 | freq = cpu_khz; | ||
1259 | seq_printf(m, "cpu MHz\t\t: %u.%03u\n", | 1263 | seq_printf(m, "cpu MHz\t\t: %u.%03u\n", |
1260 | cpu_khz / 1000, (cpu_khz % 1000)); | 1264 | freq / 1000, (freq % 1000)); |
1261 | } | 1265 | } |
1262 | 1266 | ||
1263 | /* Cache size */ | 1267 | /* Cache size */ |
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 286f6a624c3a..c016dfe84784 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
@@ -348,7 +348,7 @@ size_zones(unsigned long *z, unsigned long *h, | |||
348 | } | 348 | } |
349 | 349 | ||
350 | /* Compute holes */ | 350 | /* Compute holes */ |
351 | w = 0; | 351 | w = start_pfn; |
352 | for (i = 0; i < MAX_NR_ZONES; i++) { | 352 | for (i = 0; i < MAX_NR_ZONES; i++) { |
353 | unsigned long s = w; | 353 | unsigned long s = w; |
354 | w += z[i]; | 354 | w += z[i]; |
diff --git a/arch/x86_64/pci/Makefile b/arch/x86_64/pci/Makefile index bb34e5ef916c..a8f75a2a0f6f 100644 --- a/arch/x86_64/pci/Makefile +++ b/arch/x86_64/pci/Makefile | |||
@@ -11,7 +11,7 @@ obj-y += fixup.o | |||
11 | obj-$(CONFIG_ACPI) += acpi.o | 11 | obj-$(CONFIG_ACPI) += acpi.o |
12 | obj-y += legacy.o irq.o common.o | 12 | obj-y += legacy.o irq.o common.o |
13 | # mmconfig has a 64bit special | 13 | # mmconfig has a 64bit special |
14 | obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o | 14 | obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o |
15 | 15 | ||
16 | obj-$(CONFIG_NUMA) += k8-bus.o | 16 | obj-$(CONFIG_NUMA) += k8-bus.o |
17 | 17 | ||
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 4e390dfd3157..1d8852f7bbff 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c | |||
@@ -442,11 +442,37 @@ error: | |||
442 | return err; | 442 | return err; |
443 | } | 443 | } |
444 | 444 | ||
445 | |||
446 | /* Send basic block requests */ | ||
447 | static int __blk_send_generic(request_queue_t *q, struct gendisk *bd_disk, int cmd, int data) | ||
448 | { | ||
449 | struct request *rq; | ||
450 | int err; | ||
451 | |||
452 | rq = blk_get_request(q, WRITE, __GFP_WAIT); | ||
453 | rq->flags |= REQ_BLOCK_PC; | ||
454 | rq->data = NULL; | ||
455 | rq->data_len = 0; | ||
456 | rq->timeout = BLK_DEFAULT_TIMEOUT; | ||
457 | memset(rq->cmd, 0, sizeof(rq->cmd)); | ||
458 | rq->cmd[0] = cmd; | ||
459 | rq->cmd[4] = data; | ||
460 | rq->cmd_len = 6; | ||
461 | err = blk_execute_rq(q, bd_disk, rq, 0); | ||
462 | blk_put_request(rq); | ||
463 | |||
464 | return err; | ||
465 | } | ||
466 | |||
467 | static inline int blk_send_start_stop(request_queue_t *q, struct gendisk *bd_disk, int data) | ||
468 | { | ||
469 | return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data); | ||
470 | } | ||
471 | |||
445 | int scsi_cmd_ioctl(struct file *file, struct gendisk *bd_disk, unsigned int cmd, void __user *arg) | 472 | int scsi_cmd_ioctl(struct file *file, struct gendisk *bd_disk, unsigned int cmd, void __user *arg) |
446 | { | 473 | { |
447 | request_queue_t *q; | 474 | request_queue_t *q; |
448 | struct request *rq; | 475 | int err; |
449 | int close = 0, err; | ||
450 | 476 | ||
451 | q = bd_disk->queue; | 477 | q = bd_disk->queue; |
452 | if (!q) | 478 | if (!q) |
@@ -564,19 +590,10 @@ int scsi_cmd_ioctl(struct file *file, struct gendisk *bd_disk, unsigned int cmd, | |||
564 | err = sg_scsi_ioctl(file, q, bd_disk, arg); | 590 | err = sg_scsi_ioctl(file, q, bd_disk, arg); |
565 | break; | 591 | break; |
566 | case CDROMCLOSETRAY: | 592 | case CDROMCLOSETRAY: |
567 | close = 1; | 593 | err = blk_send_start_stop(q, bd_disk, 0x03); |
594 | break; | ||
568 | case CDROMEJECT: | 595 | case CDROMEJECT: |
569 | rq = blk_get_request(q, WRITE, __GFP_WAIT); | 596 | err = blk_send_start_stop(q, bd_disk, 0x02); |
570 | rq->flags |= REQ_BLOCK_PC; | ||
571 | rq->data = NULL; | ||
572 | rq->data_len = 0; | ||
573 | rq->timeout = BLK_DEFAULT_TIMEOUT; | ||
574 | memset(rq->cmd, 0, sizeof(rq->cmd)); | ||
575 | rq->cmd[0] = GPCMD_START_STOP_UNIT; | ||
576 | rq->cmd[4] = 0x02 + (close != 0); | ||
577 | rq->cmd_len = 6; | ||
578 | err = blk_execute_rq(q, bd_disk, rq, 0); | ||
579 | blk_put_request(rq); | ||
580 | break; | 597 | break; |
581 | default: | 598 | default: |
582 | err = -ENOTTY; | 599 | err = -ENOTTY; |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 5f51057518b0..807b0df308f1 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -274,8 +274,6 @@ static void acpi_processor_idle(void) | |||
274 | } | 274 | } |
275 | } | 275 | } |
276 | 276 | ||
277 | cx->usage++; | ||
278 | |||
279 | #ifdef CONFIG_HOTPLUG_CPU | 277 | #ifdef CONFIG_HOTPLUG_CPU |
280 | /* | 278 | /* |
281 | * Check for P_LVL2_UP flag before entering C2 and above on | 279 | * Check for P_LVL2_UP flag before entering C2 and above on |
@@ -283,9 +281,12 @@ static void acpi_processor_idle(void) | |||
283 | * detection phase, to work cleanly with logical CPU hotplug. | 281 | * detection phase, to work cleanly with logical CPU hotplug. |
284 | */ | 282 | */ |
285 | if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && | 283 | if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && |
286 | !pr->flags.has_cst && acpi_fadt.plvl2_up) | 284 | !pr->flags.has_cst && !acpi_fadt.plvl2_up) |
287 | cx->type = ACPI_STATE_C1; | 285 | cx = &pr->power.states[ACPI_STATE_C1]; |
288 | #endif | 286 | #endif |
287 | |||
288 | cx->usage++; | ||
289 | |||
289 | /* | 290 | /* |
290 | * Sleep: | 291 | * Sleep: |
291 | * ------ | 292 | * ------ |
@@ -386,6 +387,15 @@ static void acpi_processor_idle(void) | |||
386 | 387 | ||
387 | next_state = pr->power.state; | 388 | next_state = pr->power.state; |
388 | 389 | ||
390 | #ifdef CONFIG_HOTPLUG_CPU | ||
391 | /* Don't do promotion/demotion */ | ||
392 | if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) && | ||
393 | !pr->flags.has_cst && !acpi_fadt.plvl2_up) { | ||
394 | next_state = cx; | ||
395 | goto end; | ||
396 | } | ||
397 | #endif | ||
398 | |||
389 | /* | 399 | /* |
390 | * Promotion? | 400 | * Promotion? |
391 | * ---------- | 401 | * ---------- |
@@ -557,7 +567,7 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) | |||
557 | * Check for P_LVL2_UP flag before entering C2 and above on | 567 | * Check for P_LVL2_UP flag before entering C2 and above on |
558 | * an SMP system. | 568 | * an SMP system. |
559 | */ | 569 | */ |
560 | if ((num_online_cpus() > 1) && acpi_fadt.plvl2_up) | 570 | if ((num_online_cpus() > 1) && !acpi_fadt.plvl2_up) |
561 | return_VALUE(-ENODEV); | 571 | return_VALUE(-ENODEV); |
562 | #endif | 572 | #endif |
563 | 573 | ||
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index f37584015324..dc9817cfb882 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
@@ -102,8 +102,8 @@ static int cpu_has_cpufreq(unsigned int cpu) | |||
102 | { | 102 | { |
103 | struct cpufreq_policy policy; | 103 | struct cpufreq_policy policy; |
104 | if (!acpi_thermal_cpufreq_is_init || cpufreq_get_policy(&policy, cpu)) | 104 | if (!acpi_thermal_cpufreq_is_init || cpufreq_get_policy(&policy, cpu)) |
105 | return -ENODEV; | 105 | return 0; |
106 | return 0; | 106 | return 1; |
107 | } | 107 | } |
108 | 108 | ||
109 | static int acpi_thermal_cpufreq_increase(unsigned int cpu) | 109 | static int acpi_thermal_cpufreq_increase(unsigned int cpu) |
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 0c5abc536c7a..2ce872d75890 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c | |||
@@ -84,14 +84,14 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) | |||
84 | 84 | ||
85 | /* Find a free owner ID */ | 85 | /* Find a free owner ID */ |
86 | 86 | ||
87 | for (i = 0; i < 32; i++) { | 87 | for (i = 0; i < 64; i++) { |
88 | if (!(acpi_gbl_owner_id_mask & (1 << i))) { | 88 | if (!(acpi_gbl_owner_id_mask & (1ULL << i))) { |
89 | ACPI_DEBUG_PRINT((ACPI_DB_VALUES, | 89 | ACPI_DEBUG_PRINT((ACPI_DB_VALUES, |
90 | "Current owner_id mask: %8.8X New ID: %2.2X\n", | 90 | "Current owner_id mask: %16.16LX New ID: %2.2X\n", |
91 | acpi_gbl_owner_id_mask, | 91 | acpi_gbl_owner_id_mask, |
92 | (unsigned int)(i + 1))); | 92 | (unsigned int)(i + 1))); |
93 | 93 | ||
94 | acpi_gbl_owner_id_mask |= (1 << i); | 94 | acpi_gbl_owner_id_mask |= (1ULL << i); |
95 | *owner_id = (acpi_owner_id) (i + 1); | 95 | *owner_id = (acpi_owner_id) (i + 1); |
96 | goto exit; | 96 | goto exit; |
97 | } | 97 | } |
@@ -106,7 +106,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) | |||
106 | */ | 106 | */ |
107 | *owner_id = 0; | 107 | *owner_id = 0; |
108 | status = AE_OWNER_ID_LIMIT; | 108 | status = AE_OWNER_ID_LIMIT; |
109 | ACPI_REPORT_ERROR(("Could not allocate new owner_id (32 max), AE_OWNER_ID_LIMIT\n")); | 109 | ACPI_REPORT_ERROR(("Could not allocate new owner_id (64 max), AE_OWNER_ID_LIMIT\n")); |
110 | 110 | ||
111 | exit: | 111 | exit: |
112 | (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); | 112 | (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); |
@@ -123,7 +123,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) | |||
123 | * control method or unloading a table. Either way, we would | 123 | * control method or unloading a table. Either way, we would |
124 | * ignore any error anyway. | 124 | * ignore any error anyway. |
125 | * | 125 | * |
126 | * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 32 | 126 | * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 64 |
127 | * | 127 | * |
128 | ******************************************************************************/ | 128 | ******************************************************************************/ |
129 | 129 | ||
@@ -140,7 +140,7 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) | |||
140 | 140 | ||
141 | /* Zero is not a valid owner_iD */ | 141 | /* Zero is not a valid owner_iD */ |
142 | 142 | ||
143 | if ((owner_id == 0) || (owner_id > 32)) { | 143 | if ((owner_id == 0) || (owner_id > 64)) { |
144 | ACPI_REPORT_ERROR(("Invalid owner_id: %2.2X\n", owner_id)); | 144 | ACPI_REPORT_ERROR(("Invalid owner_id: %2.2X\n", owner_id)); |
145 | return_VOID; | 145 | return_VOID; |
146 | } | 146 | } |
@@ -158,8 +158,8 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) | |||
158 | 158 | ||
159 | /* Free the owner ID only if it is valid */ | 159 | /* Free the owner ID only if it is valid */ |
160 | 160 | ||
161 | if (acpi_gbl_owner_id_mask & (1 << owner_id)) { | 161 | if (acpi_gbl_owner_id_mask & (1ULL << owner_id)) { |
162 | acpi_gbl_owner_id_mask ^= (1 << owner_id); | 162 | acpi_gbl_owner_id_mask ^= (1ULL << owner_id); |
163 | } | 163 | } |
164 | 164 | ||
165 | (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); | 165 | (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); |
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 7b1cd93892be..c4b9d2adfc08 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
@@ -358,7 +358,8 @@ config BLK_DEV_UB | |||
358 | This driver supports certain USB attached storage devices | 358 | This driver supports certain USB attached storage devices |
359 | such as flash keys. | 359 | such as flash keys. |
360 | 360 | ||
361 | Warning: Enabling this cripples the usb-storage driver. | 361 | If you enable this driver, it is recommended to avoid conflicts |
362 | with usb-storage by enabling USB_LIBUSUAL. | ||
362 | 363 | ||
363 | If unsure, say N. | 364 | If unsure, say N. |
364 | 365 | ||
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index bfb23d543ff7..10740a065088 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -9,7 +9,6 @@ | |||
9 | * | 9 | * |
10 | * TODO (sorted by decreasing priority) | 10 | * TODO (sorted by decreasing priority) |
11 | * -- Kill first_open (Al Viro fixed the block layer now) | 11 | * -- Kill first_open (Al Viro fixed the block layer now) |
12 | * -- Do resets with usb_device_reset (needs a thread context, use khubd) | ||
13 | * -- set readonly flag for CDs, set removable flag for CF readers | 12 | * -- set readonly flag for CDs, set removable flag for CF readers |
14 | * -- do inquiry and verify we got a disk and not a tape (for LUN mismatch) | 13 | * -- do inquiry and verify we got a disk and not a tape (for LUN mismatch) |
15 | * -- special case some senses, e.g. 3a/0 -> no media present, reduce retries | 14 | * -- special case some senses, e.g. 3a/0 -> no media present, reduce retries |
@@ -29,6 +28,7 @@ | |||
29 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
30 | #include <linux/module.h> | 29 | #include <linux/module.h> |
31 | #include <linux/usb.h> | 30 | #include <linux/usb.h> |
31 | #include <linux/usb_usual.h> | ||
32 | #include <linux/blkdev.h> | 32 | #include <linux/blkdev.h> |
33 | #include <linux/devfs_fs_kernel.h> | 33 | #include <linux/devfs_fs_kernel.h> |
34 | #include <linux/timer.h> | 34 | #include <linux/timer.h> |
@@ -107,16 +107,6 @@ | |||
107 | */ | 107 | */ |
108 | 108 | ||
109 | /* | 109 | /* |
110 | * Definitions which have to be scattered once we understand the layout better. | ||
111 | */ | ||
112 | |||
113 | /* Transport (despite PR in the name) */ | ||
114 | #define US_PR_BULK 0x50 /* bulk only */ | ||
115 | |||
116 | /* Protocol */ | ||
117 | #define US_SC_SCSI 0x06 /* Transparent */ | ||
118 | |||
119 | /* | ||
120 | * This many LUNs per USB device. | 110 | * This many LUNs per USB device. |
121 | * Every one of them takes a host, see UB_MAX_HOSTS. | 111 | * Every one of them takes a host, see UB_MAX_HOSTS. |
122 | */ | 112 | */ |
@@ -125,7 +115,7 @@ | |||
125 | /* | 115 | /* |
126 | */ | 116 | */ |
127 | 117 | ||
128 | #define UB_MINORS_PER_MAJOR 8 | 118 | #define UB_PARTS_PER_LUN 8 |
129 | 119 | ||
130 | #define UB_MAX_CDB_SIZE 16 /* Corresponds to Bulk */ | 120 | #define UB_MAX_CDB_SIZE 16 /* Corresponds to Bulk */ |
131 | 121 | ||
@@ -245,6 +235,13 @@ struct ub_scsi_cmd { | |||
245 | void *back; | 235 | void *back; |
246 | }; | 236 | }; |
247 | 237 | ||
238 | struct ub_request { | ||
239 | struct request *rq; | ||
240 | unsigned int current_try; | ||
241 | unsigned int nsg; /* sgv[nsg] */ | ||
242 | struct scatterlist sgv[UB_MAX_REQ_SG]; | ||
243 | }; | ||
244 | |||
248 | /* | 245 | /* |
249 | */ | 246 | */ |
250 | struct ub_capacity { | 247 | struct ub_capacity { |
@@ -340,6 +337,8 @@ struct ub_lun { | |||
340 | int readonly; | 337 | int readonly; |
341 | int first_open; /* Kludge. See ub_bd_open. */ | 338 | int first_open; /* Kludge. See ub_bd_open. */ |
342 | 339 | ||
340 | struct ub_request urq; | ||
341 | |||
343 | /* Use Ingo's mempool if or when we have more than one command. */ | 342 | /* Use Ingo's mempool if or when we have more than one command. */ |
344 | /* | 343 | /* |
345 | * Currently we never need more than one command for the whole device. | 344 | * Currently we never need more than one command for the whole device. |
@@ -360,6 +359,7 @@ struct ub_dev { | |||
360 | atomic_t poison; /* The USB device is disconnected */ | 359 | atomic_t poison; /* The USB device is disconnected */ |
361 | int openc; /* protected by ub_lock! */ | 360 | int openc; /* protected by ub_lock! */ |
362 | /* kref is too implicit for our taste */ | 361 | /* kref is too implicit for our taste */ |
362 | int reset; /* Reset is running */ | ||
363 | unsigned int tagcnt; | 363 | unsigned int tagcnt; |
364 | char name[12]; | 364 | char name[12]; |
365 | struct usb_device *dev; | 365 | struct usb_device *dev; |
@@ -387,6 +387,9 @@ struct ub_dev { | |||
387 | struct bulk_cs_wrap work_bcs; | 387 | struct bulk_cs_wrap work_bcs; |
388 | struct usb_ctrlrequest work_cr; | 388 | struct usb_ctrlrequest work_cr; |
389 | 389 | ||
390 | struct work_struct reset_work; | ||
391 | wait_queue_head_t reset_wait; | ||
392 | |||
390 | int sg_stat[6]; | 393 | int sg_stat[6]; |
391 | struct ub_scsi_trace tr; | 394 | struct ub_scsi_trace tr; |
392 | }; | 395 | }; |
@@ -395,12 +398,14 @@ struct ub_dev { | |||
395 | */ | 398 | */ |
396 | static void ub_cleanup(struct ub_dev *sc); | 399 | static void ub_cleanup(struct ub_dev *sc); |
397 | static int ub_request_fn_1(struct ub_lun *lun, struct request *rq); | 400 | static int ub_request_fn_1(struct ub_lun *lun, struct request *rq); |
398 | static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, | 401 | static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, |
399 | struct ub_scsi_cmd *cmd, struct request *rq); | 402 | struct ub_scsi_cmd *cmd, struct ub_request *urq); |
400 | static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, | 403 | static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, |
401 | struct ub_scsi_cmd *cmd, struct request *rq); | 404 | struct ub_scsi_cmd *cmd, struct ub_request *urq); |
402 | static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd); | 405 | static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd); |
403 | static void ub_end_rq(struct request *rq, int uptodate); | 406 | static void ub_end_rq(struct request *rq, int uptodate); |
407 | static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun, | ||
408 | struct ub_request *urq, struct ub_scsi_cmd *cmd); | ||
404 | static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd); | 409 | static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd); |
405 | static void ub_urb_complete(struct urb *urb, struct pt_regs *pt); | 410 | static void ub_urb_complete(struct urb *urb, struct pt_regs *pt); |
406 | static void ub_scsi_action(unsigned long _dev); | 411 | static void ub_scsi_action(unsigned long _dev); |
@@ -415,6 +420,8 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd); | |||
415 | static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, | 420 | static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, |
416 | int stalled_pipe); | 421 | int stalled_pipe); |
417 | static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd); | 422 | static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd); |
423 | static void ub_reset_enter(struct ub_dev *sc); | ||
424 | static void ub_reset_task(void *arg); | ||
418 | static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun); | 425 | static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun); |
419 | static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, | 426 | static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, |
420 | struct ub_capacity *ret); | 427 | struct ub_capacity *ret); |
@@ -422,13 +429,18 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum); | |||
422 | 429 | ||
423 | /* | 430 | /* |
424 | */ | 431 | */ |
432 | #ifdef CONFIG_USB_LIBUSUAL | ||
433 | |||
434 | #define ub_usb_ids storage_usb_ids | ||
435 | #else | ||
436 | |||
425 | static struct usb_device_id ub_usb_ids[] = { | 437 | static struct usb_device_id ub_usb_ids[] = { |
426 | // { USB_DEVICE_VER(0x0781, 0x0002, 0x0009, 0x0009) }, /* SDDR-31 */ | ||
427 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) }, | 438 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) }, |
428 | { } | 439 | { } |
429 | }; | 440 | }; |
430 | 441 | ||
431 | MODULE_DEVICE_TABLE(usb, ub_usb_ids); | 442 | MODULE_DEVICE_TABLE(usb, ub_usb_ids); |
443 | #endif /* CONFIG_USB_LIBUSUAL */ | ||
432 | 444 | ||
433 | /* | 445 | /* |
434 | * Find me a way to identify "next free minor" for add_disk(), | 446 | * Find me a way to identify "next free minor" for add_disk(), |
@@ -522,6 +534,9 @@ static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, | |||
522 | spin_lock_irqsave(&sc->lock, flags); | 534 | spin_lock_irqsave(&sc->lock, flags); |
523 | 535 | ||
524 | cnt += sprintf(page + cnt, | 536 | cnt += sprintf(page + cnt, |
537 | "poison %d reset %d\n", | ||
538 | atomic_read(&sc->poison), sc->reset); | ||
539 | cnt += sprintf(page + cnt, | ||
525 | "qlen %d qmax %d\n", | 540 | "qlen %d qmax %d\n", |
526 | sc->cmd_queue.qlen, sc->cmd_queue.qmax); | 541 | sc->cmd_queue.qlen, sc->cmd_queue.qmax); |
527 | cnt += sprintf(page + cnt, | 542 | cnt += sprintf(page + cnt, |
@@ -770,7 +785,8 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq) | |||
770 | { | 785 | { |
771 | struct ub_dev *sc = lun->udev; | 786 | struct ub_dev *sc = lun->udev; |
772 | struct ub_scsi_cmd *cmd; | 787 | struct ub_scsi_cmd *cmd; |
773 | int rc; | 788 | struct ub_request *urq; |
789 | int n_elem; | ||
774 | 790 | ||
775 | if (atomic_read(&sc->poison) || lun->changed) { | 791 | if (atomic_read(&sc->poison) || lun->changed) { |
776 | blkdev_dequeue_request(rq); | 792 | blkdev_dequeue_request(rq); |
@@ -778,65 +794,70 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq) | |||
778 | return 0; | 794 | return 0; |
779 | } | 795 | } |
780 | 796 | ||
797 | if (lun->urq.rq != NULL) | ||
798 | return -1; | ||
781 | if ((cmd = ub_get_cmd(lun)) == NULL) | 799 | if ((cmd = ub_get_cmd(lun)) == NULL) |
782 | return -1; | 800 | return -1; |
783 | memset(cmd, 0, sizeof(struct ub_scsi_cmd)); | 801 | memset(cmd, 0, sizeof(struct ub_scsi_cmd)); |
784 | 802 | ||
785 | blkdev_dequeue_request(rq); | 803 | blkdev_dequeue_request(rq); |
804 | |||
805 | urq = &lun->urq; | ||
806 | memset(urq, 0, sizeof(struct ub_request)); | ||
807 | urq->rq = rq; | ||
808 | |||
809 | /* | ||
810 | * get scatterlist from block layer | ||
811 | */ | ||
812 | n_elem = blk_rq_map_sg(lun->disk->queue, rq, &urq->sgv[0]); | ||
813 | if (n_elem < 0) { | ||
814 | printk(KERN_INFO "%s: failed request map (%d)\n", | ||
815 | lun->name, n_elem); /* P3 */ | ||
816 | goto drop; | ||
817 | } | ||
818 | if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */ | ||
819 | printk(KERN_WARNING "%s: request with %d segments\n", | ||
820 | lun->name, n_elem); | ||
821 | goto drop; | ||
822 | } | ||
823 | urq->nsg = n_elem; | ||
824 | sc->sg_stat[n_elem < 5 ? n_elem : 5]++; | ||
825 | |||
786 | if (blk_pc_request(rq)) { | 826 | if (blk_pc_request(rq)) { |
787 | rc = ub_cmd_build_packet(sc, lun, cmd, rq); | 827 | ub_cmd_build_packet(sc, lun, cmd, urq); |
788 | } else { | 828 | } else { |
789 | rc = ub_cmd_build_block(sc, lun, cmd, rq); | 829 | ub_cmd_build_block(sc, lun, cmd, urq); |
790 | } | ||
791 | if (rc != 0) { | ||
792 | ub_put_cmd(lun, cmd); | ||
793 | ub_end_rq(rq, 0); | ||
794 | return 0; | ||
795 | } | 830 | } |
796 | cmd->state = UB_CMDST_INIT; | 831 | cmd->state = UB_CMDST_INIT; |
797 | cmd->lun = lun; | 832 | cmd->lun = lun; |
798 | cmd->done = ub_rw_cmd_done; | 833 | cmd->done = ub_rw_cmd_done; |
799 | cmd->back = rq; | 834 | cmd->back = urq; |
800 | 835 | ||
801 | cmd->tag = sc->tagcnt++; | 836 | cmd->tag = sc->tagcnt++; |
802 | if (ub_submit_scsi(sc, cmd) != 0) { | 837 | if (ub_submit_scsi(sc, cmd) != 0) |
803 | ub_put_cmd(lun, cmd); | 838 | goto drop; |
804 | ub_end_rq(rq, 0); | ||
805 | return 0; | ||
806 | } | ||
807 | 839 | ||
808 | return 0; | 840 | return 0; |
841 | |||
842 | drop: | ||
843 | ub_put_cmd(lun, cmd); | ||
844 | ub_end_rq(rq, 0); | ||
845 | return 0; | ||
809 | } | 846 | } |
810 | 847 | ||
811 | static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, | 848 | static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, |
812 | struct ub_scsi_cmd *cmd, struct request *rq) | 849 | struct ub_scsi_cmd *cmd, struct ub_request *urq) |
813 | { | 850 | { |
814 | int ub_dir; | 851 | struct request *rq = urq->rq; |
815 | int n_elem; | ||
816 | unsigned int block, nblks; | 852 | unsigned int block, nblks; |
817 | 853 | ||
818 | if (rq_data_dir(rq) == WRITE) | 854 | if (rq_data_dir(rq) == WRITE) |
819 | ub_dir = UB_DIR_WRITE; | 855 | cmd->dir = UB_DIR_WRITE; |
820 | else | 856 | else |
821 | ub_dir = UB_DIR_READ; | 857 | cmd->dir = UB_DIR_READ; |
822 | cmd->dir = ub_dir; | ||
823 | 858 | ||
824 | /* | 859 | cmd->nsg = urq->nsg; |
825 | * get scatterlist from block layer | 860 | memcpy(cmd->sgv, urq->sgv, sizeof(struct scatterlist) * cmd->nsg); |
826 | */ | ||
827 | n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]); | ||
828 | if (n_elem <= 0) { | ||
829 | printk(KERN_INFO "%s: failed request map (%d)\n", | ||
830 | sc->name, n_elem); /* P3 */ | ||
831 | return -1; /* request with no s/g entries? */ | ||
832 | } | ||
833 | if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */ | ||
834 | printk(KERN_WARNING "%s: request with %d segments\n", | ||
835 | sc->name, n_elem); | ||
836 | return -1; | ||
837 | } | ||
838 | cmd->nsg = n_elem; | ||
839 | sc->sg_stat[n_elem < 5 ? n_elem : 5]++; | ||
840 | 861 | ||
841 | /* | 862 | /* |
842 | * build the command | 863 | * build the command |
@@ -847,7 +868,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, | |||
847 | block = rq->sector >> lun->capacity.bshift; | 868 | block = rq->sector >> lun->capacity.bshift; |
848 | nblks = rq->nr_sectors >> lun->capacity.bshift; | 869 | nblks = rq->nr_sectors >> lun->capacity.bshift; |
849 | 870 | ||
850 | cmd->cdb[0] = (ub_dir == UB_DIR_READ)? READ_10: WRITE_10; | 871 | cmd->cdb[0] = (cmd->dir == UB_DIR_READ)? READ_10: WRITE_10; |
851 | /* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */ | 872 | /* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */ |
852 | cmd->cdb[2] = block >> 24; | 873 | cmd->cdb[2] = block >> 24; |
853 | cmd->cdb[3] = block >> 16; | 874 | cmd->cdb[3] = block >> 16; |
@@ -858,14 +879,12 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, | |||
858 | cmd->cdb_len = 10; | 879 | cmd->cdb_len = 10; |
859 | 880 | ||
860 | cmd->len = rq->nr_sectors * 512; | 881 | cmd->len = rq->nr_sectors * 512; |
861 | |||
862 | return 0; | ||
863 | } | 882 | } |
864 | 883 | ||
865 | static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, | 884 | static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, |
866 | struct ub_scsi_cmd *cmd, struct request *rq) | 885 | struct ub_scsi_cmd *cmd, struct ub_request *urq) |
867 | { | 886 | { |
868 | int n_elem; | 887 | struct request *rq = urq->rq; |
869 | 888 | ||
870 | if (rq->data_len == 0) { | 889 | if (rq->data_len == 0) { |
871 | cmd->dir = UB_DIR_NONE; | 890 | cmd->dir = UB_DIR_NONE; |
@@ -874,40 +893,26 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, | |||
874 | cmd->dir = UB_DIR_WRITE; | 893 | cmd->dir = UB_DIR_WRITE; |
875 | else | 894 | else |
876 | cmd->dir = UB_DIR_READ; | 895 | cmd->dir = UB_DIR_READ; |
877 | |||
878 | } | 896 | } |
879 | 897 | ||
880 | /* | 898 | cmd->nsg = urq->nsg; |
881 | * get scatterlist from block layer | 899 | memcpy(cmd->sgv, urq->sgv, sizeof(struct scatterlist) * cmd->nsg); |
882 | */ | ||
883 | n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]); | ||
884 | if (n_elem < 0) { | ||
885 | printk(KERN_INFO "%s: failed request map (%d)\n", | ||
886 | sc->name, n_elem); /* P3 */ | ||
887 | return -1; | ||
888 | } | ||
889 | if (n_elem > UB_MAX_REQ_SG) { /* Paranoia */ | ||
890 | printk(KERN_WARNING "%s: request with %d segments\n", | ||
891 | sc->name, n_elem); | ||
892 | return -1; | ||
893 | } | ||
894 | cmd->nsg = n_elem; | ||
895 | sc->sg_stat[n_elem < 5 ? n_elem : 5]++; | ||
896 | 900 | ||
897 | memcpy(&cmd->cdb, rq->cmd, rq->cmd_len); | 901 | memcpy(&cmd->cdb, rq->cmd, rq->cmd_len); |
898 | cmd->cdb_len = rq->cmd_len; | 902 | cmd->cdb_len = rq->cmd_len; |
899 | 903 | ||
900 | cmd->len = rq->data_len; | 904 | cmd->len = rq->data_len; |
901 | |||
902 | return 0; | ||
903 | } | 905 | } |
904 | 906 | ||
905 | static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | 907 | static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) |
906 | { | 908 | { |
907 | struct request *rq = cmd->back; | ||
908 | struct ub_lun *lun = cmd->lun; | 909 | struct ub_lun *lun = cmd->lun; |
910 | struct ub_request *urq = cmd->back; | ||
911 | struct request *rq; | ||
909 | int uptodate; | 912 | int uptodate; |
910 | 913 | ||
914 | rq = urq->rq; | ||
915 | |||
911 | if (cmd->error == 0) { | 916 | if (cmd->error == 0) { |
912 | uptodate = 1; | 917 | uptodate = 1; |
913 | 918 | ||
@@ -928,9 +933,16 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
928 | rq->errors = SAM_STAT_CHECK_CONDITION; | 933 | rq->errors = SAM_STAT_CHECK_CONDITION; |
929 | else | 934 | else |
930 | rq->errors = DID_ERROR << 16; | 935 | rq->errors = DID_ERROR << 16; |
936 | } else { | ||
937 | if (cmd->error == -EIO) { | ||
938 | if (ub_rw_cmd_retry(sc, lun, urq, cmd) == 0) | ||
939 | return; | ||
940 | } | ||
931 | } | 941 | } |
932 | } | 942 | } |
933 | 943 | ||
944 | urq->rq = NULL; | ||
945 | |||
934 | ub_put_cmd(lun, cmd); | 946 | ub_put_cmd(lun, cmd); |
935 | ub_end_rq(rq, uptodate); | 947 | ub_end_rq(rq, uptodate); |
936 | blk_start_queue(lun->disk->queue); | 948 | blk_start_queue(lun->disk->queue); |
@@ -938,13 +950,45 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
938 | 950 | ||
939 | static void ub_end_rq(struct request *rq, int uptodate) | 951 | static void ub_end_rq(struct request *rq, int uptodate) |
940 | { | 952 | { |
941 | int rc; | 953 | end_that_request_first(rq, uptodate, rq->hard_nr_sectors); |
942 | |||
943 | rc = end_that_request_first(rq, uptodate, rq->hard_nr_sectors); | ||
944 | // assert(rc == 0); | ||
945 | end_that_request_last(rq); | 954 | end_that_request_last(rq); |
946 | } | 955 | } |
947 | 956 | ||
957 | static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun, | ||
958 | struct ub_request *urq, struct ub_scsi_cmd *cmd) | ||
959 | { | ||
960 | |||
961 | if (atomic_read(&sc->poison)) | ||
962 | return -ENXIO; | ||
963 | |||
964 | ub_reset_enter(sc); | ||
965 | |||
966 | if (urq->current_try >= 3) | ||
967 | return -EIO; | ||
968 | urq->current_try++; | ||
969 | /* P3 */ printk("%s: dir %c len/act %d/%d " | ||
970 | "[sense %x %02x %02x] retry %d\n", | ||
971 | sc->name, UB_DIR_CHAR(cmd->dir), cmd->len, cmd->act_len, | ||
972 | cmd->key, cmd->asc, cmd->ascq, urq->current_try); | ||
973 | |||
974 | memset(cmd, 0, sizeof(struct ub_scsi_cmd)); | ||
975 | ub_cmd_build_block(sc, lun, cmd, urq); | ||
976 | |||
977 | cmd->state = UB_CMDST_INIT; | ||
978 | cmd->lun = lun; | ||
979 | cmd->done = ub_rw_cmd_done; | ||
980 | cmd->back = urq; | ||
981 | |||
982 | cmd->tag = sc->tagcnt++; | ||
983 | |||
984 | #if 0 /* Wasteful */ | ||
985 | return ub_submit_scsi(sc, cmd); | ||
986 | #else | ||
987 | ub_cmdq_add(sc, cmd); | ||
988 | return 0; | ||
989 | #endif | ||
990 | } | ||
991 | |||
948 | /* | 992 | /* |
949 | * Submit a regular SCSI operation (not an auto-sense). | 993 | * Submit a regular SCSI operation (not an auto-sense). |
950 | * | 994 | * |
@@ -1075,7 +1119,7 @@ static void ub_scsi_dispatch(struct ub_dev *sc) | |||
1075 | struct ub_scsi_cmd *cmd; | 1119 | struct ub_scsi_cmd *cmd; |
1076 | int rc; | 1120 | int rc; |
1077 | 1121 | ||
1078 | while ((cmd = ub_cmdq_peek(sc)) != NULL) { | 1122 | while (!sc->reset && (cmd = ub_cmdq_peek(sc)) != NULL) { |
1079 | if (cmd->state == UB_CMDST_DONE) { | 1123 | if (cmd->state == UB_CMDST_DONE) { |
1080 | ub_cmdq_pop(sc); | 1124 | ub_cmdq_pop(sc); |
1081 | (*cmd->done)(sc, cmd); | 1125 | (*cmd->done)(sc, cmd); |
@@ -1098,11 +1142,12 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1098 | { | 1142 | { |
1099 | struct urb *urb = &sc->work_urb; | 1143 | struct urb *urb = &sc->work_urb; |
1100 | struct bulk_cs_wrap *bcs; | 1144 | struct bulk_cs_wrap *bcs; |
1145 | int len; | ||
1101 | int rc; | 1146 | int rc; |
1102 | 1147 | ||
1103 | if (atomic_read(&sc->poison)) { | 1148 | if (atomic_read(&sc->poison)) { |
1104 | /* A little too simplistic, I feel... */ | 1149 | ub_state_done(sc, cmd, -ENODEV); |
1105 | goto Bad_End; | 1150 | return; |
1106 | } | 1151 | } |
1107 | 1152 | ||
1108 | if (cmd->state == UB_CMDST_CLEAR) { | 1153 | if (cmd->state == UB_CMDST_CLEAR) { |
@@ -1110,7 +1155,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1110 | /* | 1155 | /* |
1111 | * STALL while clearning STALL. | 1156 | * STALL while clearning STALL. |
1112 | * The control pipe clears itself - nothing to do. | 1157 | * The control pipe clears itself - nothing to do. |
1113 | * XXX Might try to reset the device here and retry. | ||
1114 | */ | 1158 | */ |
1115 | printk(KERN_NOTICE "%s: stall on control pipe\n", | 1159 | printk(KERN_NOTICE "%s: stall on control pipe\n", |
1116 | sc->name); | 1160 | sc->name); |
@@ -1129,11 +1173,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1129 | 1173 | ||
1130 | } else if (cmd->state == UB_CMDST_CLR2STS) { | 1174 | } else if (cmd->state == UB_CMDST_CLR2STS) { |
1131 | if (urb->status == -EPIPE) { | 1175 | if (urb->status == -EPIPE) { |
1132 | /* | ||
1133 | * STALL while clearning STALL. | ||
1134 | * The control pipe clears itself - nothing to do. | ||
1135 | * XXX Might try to reset the device here and retry. | ||
1136 | */ | ||
1137 | printk(KERN_NOTICE "%s: stall on control pipe\n", | 1176 | printk(KERN_NOTICE "%s: stall on control pipe\n", |
1138 | sc->name); | 1177 | sc->name); |
1139 | goto Bad_End; | 1178 | goto Bad_End; |
@@ -1151,11 +1190,6 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1151 | 1190 | ||
1152 | } else if (cmd->state == UB_CMDST_CLRRS) { | 1191 | } else if (cmd->state == UB_CMDST_CLRRS) { |
1153 | if (urb->status == -EPIPE) { | 1192 | if (urb->status == -EPIPE) { |
1154 | /* | ||
1155 | * STALL while clearning STALL. | ||
1156 | * The control pipe clears itself - nothing to do. | ||
1157 | * XXX Might try to reset the device here and retry. | ||
1158 | */ | ||
1159 | printk(KERN_NOTICE "%s: stall on control pipe\n", | 1193 | printk(KERN_NOTICE "%s: stall on control pipe\n", |
1160 | sc->name); | 1194 | sc->name); |
1161 | goto Bad_End; | 1195 | goto Bad_End; |
@@ -1172,7 +1206,12 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1172 | ub_state_stat_counted(sc, cmd); | 1206 | ub_state_stat_counted(sc, cmd); |
1173 | 1207 | ||
1174 | } else if (cmd->state == UB_CMDST_CMD) { | 1208 | } else if (cmd->state == UB_CMDST_CMD) { |
1175 | if (urb->status == -EPIPE) { | 1209 | switch (urb->status) { |
1210 | case 0: | ||
1211 | break; | ||
1212 | case -EOVERFLOW: | ||
1213 | goto Bad_End; | ||
1214 | case -EPIPE: | ||
1176 | rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); | 1215 | rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); |
1177 | if (rc != 0) { | 1216 | if (rc != 0) { |
1178 | printk(KERN_NOTICE "%s: " | 1217 | printk(KERN_NOTICE "%s: " |
@@ -1182,17 +1221,20 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1182 | * This is typically ENOMEM or some other such shit. | 1221 | * This is typically ENOMEM or some other such shit. |
1183 | * Retrying is pointless. Just do Bad End on it... | 1222 | * Retrying is pointless. Just do Bad End on it... |
1184 | */ | 1223 | */ |
1185 | goto Bad_End; | 1224 | ub_state_done(sc, cmd, rc); |
1225 | return; | ||
1186 | } | 1226 | } |
1187 | cmd->state = UB_CMDST_CLEAR; | 1227 | cmd->state = UB_CMDST_CLEAR; |
1188 | ub_cmdtr_state(sc, cmd); | 1228 | ub_cmdtr_state(sc, cmd); |
1189 | return; | 1229 | return; |
1190 | } | 1230 | case -ESHUTDOWN: /* unplug */ |
1191 | if (urb->status != 0) { | 1231 | case -EILSEQ: /* unplug timeout on uhci */ |
1232 | ub_state_done(sc, cmd, -ENODEV); | ||
1233 | return; | ||
1234 | default: | ||
1192 | goto Bad_End; | 1235 | goto Bad_End; |
1193 | } | 1236 | } |
1194 | if (urb->actual_length != US_BULK_CB_WRAP_LEN) { | 1237 | if (urb->actual_length != US_BULK_CB_WRAP_LEN) { |
1195 | /* XXX Must do reset here to unconfuse the device */ | ||
1196 | goto Bad_End; | 1238 | goto Bad_End; |
1197 | } | 1239 | } |
1198 | 1240 | ||
@@ -1211,11 +1253,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1211 | printk(KERN_NOTICE "%s: " | 1253 | printk(KERN_NOTICE "%s: " |
1212 | "unable to submit clear (%d)\n", | 1254 | "unable to submit clear (%d)\n", |
1213 | sc->name, rc); | 1255 | sc->name, rc); |
1214 | /* | 1256 | ub_state_done(sc, cmd, rc); |
1215 | * This is typically ENOMEM or some other such shit. | 1257 | return; |
1216 | * Retrying is pointless. Just do Bad End on it... | ||
1217 | */ | ||
1218 | goto Bad_End; | ||
1219 | } | 1258 | } |
1220 | cmd->state = UB_CMDST_CLR2STS; | 1259 | cmd->state = UB_CMDST_CLR2STS; |
1221 | ub_cmdtr_state(sc, cmd); | 1260 | ub_cmdtr_state(sc, cmd); |
@@ -1224,14 +1263,50 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1224 | if (urb->status == -EOVERFLOW) { | 1263 | if (urb->status == -EOVERFLOW) { |
1225 | /* | 1264 | /* |
1226 | * A babble? Failure, but we must transfer CSW now. | 1265 | * A babble? Failure, but we must transfer CSW now. |
1227 | * XXX This is going to end in perpetual babble. Reset. | ||
1228 | */ | 1266 | */ |
1229 | cmd->error = -EOVERFLOW; /* A cheap trick... */ | 1267 | cmd->error = -EOVERFLOW; /* A cheap trick... */ |
1230 | ub_state_stat(sc, cmd); | 1268 | ub_state_stat(sc, cmd); |
1231 | return; | 1269 | return; |
1232 | } | 1270 | } |
1233 | if (urb->status != 0) | 1271 | |
1234 | goto Bad_End; | 1272 | if (cmd->dir == UB_DIR_WRITE) { |
1273 | /* | ||
1274 | * Do not continue writes in case of a failure. | ||
1275 | * Doing so would cause sectors to be mixed up, | ||
1276 | * which is worse than sectors lost. | ||
1277 | * | ||
1278 | * We must try to read the CSW, or many devices | ||
1279 | * get confused. | ||
1280 | */ | ||
1281 | len = urb->actual_length; | ||
1282 | if (urb->status != 0 || | ||
1283 | len != cmd->sgv[cmd->current_sg].length) { | ||
1284 | cmd->act_len += len; | ||
1285 | ub_cmdtr_act_len(sc, cmd); | ||
1286 | |||
1287 | cmd->error = -EIO; | ||
1288 | ub_state_stat(sc, cmd); | ||
1289 | return; | ||
1290 | } | ||
1291 | |||
1292 | } else { | ||
1293 | /* | ||
1294 | * If an error occurs on read, we record it, and | ||
1295 | * continue to fetch data in order to avoid bubble. | ||
1296 | * | ||
1297 | * As a small shortcut, we stop if we detect that | ||
1298 | * a CSW mixed into data. | ||
1299 | */ | ||
1300 | if (urb->status != 0) | ||
1301 | cmd->error = -EIO; | ||
1302 | |||
1303 | len = urb->actual_length; | ||
1304 | if (urb->status != 0 || | ||
1305 | len != cmd->sgv[cmd->current_sg].length) { | ||
1306 | if ((len & 0x1FF) == US_BULK_CS_WRAP_LEN) | ||
1307 | goto Bad_End; | ||
1308 | } | ||
1309 | } | ||
1235 | 1310 | ||
1236 | cmd->act_len += urb->actual_length; | 1311 | cmd->act_len += urb->actual_length; |
1237 | ub_cmdtr_act_len(sc, cmd); | 1312 | ub_cmdtr_act_len(sc, cmd); |
@@ -1249,11 +1324,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1249 | printk(KERN_NOTICE "%s: " | 1324 | printk(KERN_NOTICE "%s: " |
1250 | "unable to submit clear (%d)\n", | 1325 | "unable to submit clear (%d)\n", |
1251 | sc->name, rc); | 1326 | sc->name, rc); |
1252 | /* | 1327 | ub_state_done(sc, cmd, rc); |
1253 | * This is typically ENOMEM or some other such shit. | 1328 | return; |
1254 | * Retrying is pointless. Just do Bad End on it... | ||
1255 | */ | ||
1256 | goto Bad_End; | ||
1257 | } | 1329 | } |
1258 | 1330 | ||
1259 | /* | 1331 | /* |
@@ -1266,14 +1338,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1266 | ub_cmdtr_state(sc, cmd); | 1338 | ub_cmdtr_state(sc, cmd); |
1267 | return; | 1339 | return; |
1268 | } | 1340 | } |
1269 | if (urb->status == -EOVERFLOW) { | 1341 | |
1270 | /* | 1342 | /* Catch everything, including -EOVERFLOW and other nasties. */ |
1271 | * XXX We are screwed here. Retrying is pointless, | ||
1272 | * because the pipelined data will not get in until | ||
1273 | * we read with a big enough buffer. We must reset XXX. | ||
1274 | */ | ||
1275 | goto Bad_End; | ||
1276 | } | ||
1277 | if (urb->status != 0) | 1343 | if (urb->status != 0) |
1278 | goto Bad_End; | 1344 | goto Bad_End; |
1279 | 1345 | ||
@@ -1319,15 +1385,15 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1319 | return; | 1385 | return; |
1320 | } | 1386 | } |
1321 | 1387 | ||
1322 | rc = le32_to_cpu(bcs->Residue); | 1388 | len = le32_to_cpu(bcs->Residue); |
1323 | if (rc != cmd->len - cmd->act_len) { | 1389 | if (len != cmd->len - cmd->act_len) { |
1324 | /* | 1390 | /* |
1325 | * It is all right to transfer less, the caller has | 1391 | * It is all right to transfer less, the caller has |
1326 | * to check. But it's not all right if the device | 1392 | * to check. But it's not all right if the device |
1327 | * counts disagree with our counts. | 1393 | * counts disagree with our counts. |
1328 | */ | 1394 | */ |
1329 | /* P3 */ printk("%s: resid %d len %d act %d\n", | 1395 | /* P3 */ printk("%s: resid %d len %d act %d\n", |
1330 | sc->name, rc, cmd->len, cmd->act_len); | 1396 | sc->name, len, cmd->len, cmd->act_len); |
1331 | goto Bad_End; | 1397 | goto Bad_End; |
1332 | } | 1398 | } |
1333 | 1399 | ||
@@ -1338,13 +1404,13 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1338 | ub_state_sense(sc, cmd); | 1404 | ub_state_sense(sc, cmd); |
1339 | return; | 1405 | return; |
1340 | case US_BULK_STAT_PHASE: | 1406 | case US_BULK_STAT_PHASE: |
1341 | /* XXX We must reset the transport here */ | ||
1342 | /* P3 */ printk("%s: status PHASE\n", sc->name); | 1407 | /* P3 */ printk("%s: status PHASE\n", sc->name); |
1343 | goto Bad_End; | 1408 | goto Bad_End; |
1344 | default: | 1409 | default: |
1345 | printk(KERN_INFO "%s: unknown CSW status 0x%x\n", | 1410 | printk(KERN_INFO "%s: unknown CSW status 0x%x\n", |
1346 | sc->name, bcs->Status); | 1411 | sc->name, bcs->Status); |
1347 | goto Bad_End; | 1412 | ub_state_done(sc, cmd, -EINVAL); |
1413 | return; | ||
1348 | } | 1414 | } |
1349 | 1415 | ||
1350 | /* Not zeroing error to preserve a babble indicator */ | 1416 | /* Not zeroing error to preserve a babble indicator */ |
@@ -1364,7 +1430,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1364 | printk(KERN_WARNING "%s: " | 1430 | printk(KERN_WARNING "%s: " |
1365 | "wrong command state %d\n", | 1431 | "wrong command state %d\n", |
1366 | sc->name, cmd->state); | 1432 | sc->name, cmd->state); |
1367 | goto Bad_End; | 1433 | ub_state_done(sc, cmd, -EINVAL); |
1434 | return; | ||
1368 | } | 1435 | } |
1369 | return; | 1436 | return; |
1370 | 1437 | ||
@@ -1612,6 +1679,93 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd) | |||
1612 | } | 1679 | } |
1613 | 1680 | ||
1614 | /* | 1681 | /* |
1682 | * Reset management | ||
1683 | */ | ||
1684 | |||
1685 | static void ub_reset_enter(struct ub_dev *sc) | ||
1686 | { | ||
1687 | |||
1688 | if (sc->reset) { | ||
1689 | /* This happens often on multi-LUN devices. */ | ||
1690 | return; | ||
1691 | } | ||
1692 | sc->reset = 1; | ||
1693 | |||
1694 | #if 0 /* Not needed because the disconnect waits for us. */ | ||
1695 | unsigned long flags; | ||
1696 | spin_lock_irqsave(&ub_lock, flags); | ||
1697 | sc->openc++; | ||
1698 | spin_unlock_irqrestore(&ub_lock, flags); | ||
1699 | #endif | ||
1700 | |||
1701 | #if 0 /* We let them stop themselves. */ | ||
1702 | struct list_head *p; | ||
1703 | struct ub_lun *lun; | ||
1704 | list_for_each(p, &sc->luns) { | ||
1705 | lun = list_entry(p, struct ub_lun, link); | ||
1706 | blk_stop_queue(lun->disk->queue); | ||
1707 | } | ||
1708 | #endif | ||
1709 | |||
1710 | schedule_work(&sc->reset_work); | ||
1711 | } | ||
1712 | |||
1713 | static void ub_reset_task(void *arg) | ||
1714 | { | ||
1715 | struct ub_dev *sc = arg; | ||
1716 | unsigned long flags; | ||
1717 | struct list_head *p; | ||
1718 | struct ub_lun *lun; | ||
1719 | int lkr, rc; | ||
1720 | |||
1721 | if (!sc->reset) { | ||
1722 | printk(KERN_WARNING "%s: Running reset unrequested\n", | ||
1723 | sc->name); | ||
1724 | return; | ||
1725 | } | ||
1726 | |||
1727 | if (atomic_read(&sc->poison)) { | ||
1728 | printk(KERN_NOTICE "%s: Not resetting disconnected device\n", | ||
1729 | sc->name); /* P3 This floods. Remove soon. XXX */ | ||
1730 | } else if (sc->dev->actconfig->desc.bNumInterfaces != 1) { | ||
1731 | printk(KERN_NOTICE "%s: Not resetting multi-interface device\n", | ||
1732 | sc->name); /* P3 This floods. Remove soon. XXX */ | ||
1733 | } else { | ||
1734 | if ((lkr = usb_lock_device_for_reset(sc->dev, sc->intf)) < 0) { | ||
1735 | printk(KERN_NOTICE | ||
1736 | "%s: usb_lock_device_for_reset failed (%d)\n", | ||
1737 | sc->name, lkr); | ||
1738 | } else { | ||
1739 | rc = usb_reset_device(sc->dev); | ||
1740 | if (rc < 0) { | ||
1741 | printk(KERN_NOTICE "%s: " | ||
1742 | "usb_lock_device_for_reset failed (%d)\n", | ||
1743 | sc->name, rc); | ||
1744 | } | ||
1745 | |||
1746 | if (lkr) | ||
1747 | usb_unlock_device(sc->dev); | ||
1748 | } | ||
1749 | } | ||
1750 | |||
1751 | /* | ||
1752 | * In theory, no commands can be running while reset is active, | ||
1753 | * so nobody can ask for another reset, and so we do not need any | ||
1754 | * queues of resets or anything. We do need a spinlock though, | ||
1755 | * to interact with block layer. | ||
1756 | */ | ||
1757 | spin_lock_irqsave(&sc->lock, flags); | ||
1758 | sc->reset = 0; | ||
1759 | tasklet_schedule(&sc->tasklet); | ||
1760 | list_for_each(p, &sc->luns) { | ||
1761 | lun = list_entry(p, struct ub_lun, link); | ||
1762 | blk_start_queue(lun->disk->queue); | ||
1763 | } | ||
1764 | wake_up(&sc->reset_wait); | ||
1765 | spin_unlock_irqrestore(&sc->lock, flags); | ||
1766 | } | ||
1767 | |||
1768 | /* | ||
1615 | * This is called from a process context. | 1769 | * This is called from a process context. |
1616 | */ | 1770 | */ |
1617 | static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun) | 1771 | static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun) |
@@ -2146,7 +2300,7 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev, | |||
2146 | if (ep_in == NULL || ep_out == NULL) { | 2300 | if (ep_in == NULL || ep_out == NULL) { |
2147 | printk(KERN_NOTICE "%s: failed endpoint check\n", | 2301 | printk(KERN_NOTICE "%s: failed endpoint check\n", |
2148 | sc->name); | 2302 | sc->name); |
2149 | return -EIO; | 2303 | return -ENODEV; |
2150 | } | 2304 | } |
2151 | 2305 | ||
2152 | /* Calculate and store the pipe values */ | 2306 | /* Calculate and store the pipe values */ |
@@ -2172,6 +2326,9 @@ static int ub_probe(struct usb_interface *intf, | |||
2172 | int rc; | 2326 | int rc; |
2173 | int i; | 2327 | int i; |
2174 | 2328 | ||
2329 | if (usb_usual_check_type(dev_id, USB_US_TYPE_UB)) | ||
2330 | return -ENXIO; | ||
2331 | |||
2175 | rc = -ENOMEM; | 2332 | rc = -ENOMEM; |
2176 | if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL) | 2333 | if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL) |
2177 | goto err_core; | 2334 | goto err_core; |
@@ -2181,6 +2338,8 @@ static int ub_probe(struct usb_interface *intf, | |||
2181 | usb_init_urb(&sc->work_urb); | 2338 | usb_init_urb(&sc->work_urb); |
2182 | tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc); | 2339 | tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc); |
2183 | atomic_set(&sc->poison, 0); | 2340 | atomic_set(&sc->poison, 0); |
2341 | INIT_WORK(&sc->reset_work, ub_reset_task, sc); | ||
2342 | init_waitqueue_head(&sc->reset_wait); | ||
2184 | 2343 | ||
2185 | init_timer(&sc->work_timer); | 2344 | init_timer(&sc->work_timer); |
2186 | sc->work_timer.data = (unsigned long) sc; | 2345 | sc->work_timer.data = (unsigned long) sc; |
@@ -2201,7 +2360,8 @@ static int ub_probe(struct usb_interface *intf, | |||
2201 | 2360 | ||
2202 | /* XXX Verify that we can handle the device (from descriptors) */ | 2361 | /* XXX Verify that we can handle the device (from descriptors) */ |
2203 | 2362 | ||
2204 | ub_get_pipes(sc, sc->dev, intf); | 2363 | if (ub_get_pipes(sc, sc->dev, intf) != 0) |
2364 | goto err_dev_desc; | ||
2205 | 2365 | ||
2206 | if (device_create_file(&sc->intf->dev, &dev_attr_diag) != 0) | 2366 | if (device_create_file(&sc->intf->dev, &dev_attr_diag) != 0) |
2207 | goto err_diag; | 2367 | goto err_diag; |
@@ -2272,6 +2432,7 @@ static int ub_probe(struct usb_interface *intf, | |||
2272 | 2432 | ||
2273 | /* device_remove_file(&sc->intf->dev, &dev_attr_diag); */ | 2433 | /* device_remove_file(&sc->intf->dev, &dev_attr_diag); */ |
2274 | err_diag: | 2434 | err_diag: |
2435 | err_dev_desc: | ||
2275 | usb_set_intfdata(intf, NULL); | 2436 | usb_set_intfdata(intf, NULL); |
2276 | // usb_put_intf(sc->intf); | 2437 | // usb_put_intf(sc->intf); |
2277 | usb_put_dev(sc->dev); | 2438 | usb_put_dev(sc->dev); |
@@ -2309,14 +2470,14 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) | |||
2309 | ub_revalidate(sc, lun); | 2470 | ub_revalidate(sc, lun); |
2310 | 2471 | ||
2311 | rc = -ENOMEM; | 2472 | rc = -ENOMEM; |
2312 | if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL) | 2473 | if ((disk = alloc_disk(UB_PARTS_PER_LUN)) == NULL) |
2313 | goto err_diskalloc; | 2474 | goto err_diskalloc; |
2314 | 2475 | ||
2315 | lun->disk = disk; | 2476 | lun->disk = disk; |
2316 | sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a'); | 2477 | sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a'); |
2317 | sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a'); | 2478 | sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a'); |
2318 | disk->major = UB_MAJOR; | 2479 | disk->major = UB_MAJOR; |
2319 | disk->first_minor = lun->id * UB_MINORS_PER_MAJOR; | 2480 | disk->first_minor = lun->id * UB_PARTS_PER_LUN; |
2320 | disk->fops = &ub_bd_fops; | 2481 | disk->fops = &ub_bd_fops; |
2321 | disk->private_data = lun; | 2482 | disk->private_data = lun; |
2322 | disk->driverfs_dev = &sc->intf->dev; | 2483 | disk->driverfs_dev = &sc->intf->dev; |
@@ -2380,6 +2541,11 @@ static void ub_disconnect(struct usb_interface *intf) | |||
2380 | atomic_set(&sc->poison, 1); | 2541 | atomic_set(&sc->poison, 1); |
2381 | 2542 | ||
2382 | /* | 2543 | /* |
2544 | * Wait for reset to end, if any. | ||
2545 | */ | ||
2546 | wait_event(sc->reset_wait, !sc->reset); | ||
2547 | |||
2548 | /* | ||
2383 | * Blow away queued commands. | 2549 | * Blow away queued commands. |
2384 | * | 2550 | * |
2385 | * Actually, this never works, because before we get here | 2551 | * Actually, this never works, because before we get here |
@@ -2392,7 +2558,7 @@ static void ub_disconnect(struct usb_interface *intf) | |||
2392 | { | 2558 | { |
2393 | struct ub_scsi_cmd *cmd; | 2559 | struct ub_scsi_cmd *cmd; |
2394 | int cnt = 0; | 2560 | int cnt = 0; |
2395 | while ((cmd = ub_cmdq_pop(sc)) != NULL) { | 2561 | while ((cmd = ub_cmdq_peek(sc)) != NULL) { |
2396 | cmd->error = -ENOTCONN; | 2562 | cmd->error = -ENOTCONN; |
2397 | cmd->state = UB_CMDST_DONE; | 2563 | cmd->state = UB_CMDST_DONE; |
2398 | ub_cmdtr_state(sc, cmd); | 2564 | ub_cmdtr_state(sc, cmd); |
@@ -2461,7 +2627,6 @@ static void ub_disconnect(struct usb_interface *intf) | |||
2461 | } | 2627 | } |
2462 | 2628 | ||
2463 | static struct usb_driver ub_driver = { | 2629 | static struct usb_driver ub_driver = { |
2464 | .owner = THIS_MODULE, | ||
2465 | .name = "ub", | 2630 | .name = "ub", |
2466 | .probe = ub_probe, | 2631 | .probe = ub_probe, |
2467 | .disconnect = ub_disconnect, | 2632 | .disconnect = ub_disconnect, |
@@ -2479,6 +2644,7 @@ static int __init ub_init(void) | |||
2479 | if ((rc = usb_register(&ub_driver)) != 0) | 2644 | if ((rc = usb_register(&ub_driver)) != 0) |
2480 | goto err_register; | 2645 | goto err_register; |
2481 | 2646 | ||
2647 | usb_usual_set_present(USB_US_TYPE_UB); | ||
2482 | return 0; | 2648 | return 0; |
2483 | 2649 | ||
2484 | err_register: | 2650 | err_register: |
@@ -2494,6 +2660,7 @@ static void __exit ub_exit(void) | |||
2494 | 2660 | ||
2495 | devfs_remove(DEVFS_NAME); | 2661 | devfs_remove(DEVFS_NAME); |
2496 | unregister_blkdev(UB_MAJOR, DRV_NAME); | 2662 | unregister_blkdev(UB_MAJOR, DRV_NAME); |
2663 | usb_usual_clear_present(USB_US_TYPE_UB); | ||
2497 | } | 2664 | } |
2498 | 2665 | ||
2499 | module_init(ub_init); | 2666 | module_init(ub_init); |
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c index 8e7fb3551775..3e7a067cc087 100644 --- a/drivers/bluetooth/bcm203x.c +++ b/drivers/bluetooth/bcm203x.c | |||
@@ -275,7 +275,6 @@ static void bcm203x_disconnect(struct usb_interface *intf) | |||
275 | } | 275 | } |
276 | 276 | ||
277 | static struct usb_driver bcm203x_driver = { | 277 | static struct usb_driver bcm203x_driver = { |
278 | .owner = THIS_MODULE, | ||
279 | .name = "bcm203x", | 278 | .name = "bcm203x", |
280 | .probe = bcm203x_probe, | 279 | .probe = bcm203x_probe, |
281 | .disconnect = bcm203x_disconnect, | 280 | .disconnect = bcm203x_disconnect, |
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c index 067e27893e4a..8947c8837dac 100644 --- a/drivers/bluetooth/bfusb.c +++ b/drivers/bluetooth/bfusb.c | |||
@@ -768,7 +768,6 @@ static void bfusb_disconnect(struct usb_interface *intf) | |||
768 | } | 768 | } |
769 | 769 | ||
770 | static struct usb_driver bfusb_driver = { | 770 | static struct usb_driver bfusb_driver = { |
771 | .owner = THIS_MODULE, | ||
772 | .name = "bfusb", | 771 | .name = "bfusb", |
773 | .probe = bfusb_probe, | 772 | .probe = bfusb_probe, |
774 | .disconnect = bfusb_disconnect, | 773 | .disconnect = bfusb_disconnect, |
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c index 394796315adc..9446960ac742 100644 --- a/drivers/bluetooth/bpa10x.c +++ b/drivers/bluetooth/bpa10x.c | |||
@@ -619,7 +619,6 @@ static void bpa10x_disconnect(struct usb_interface *intf) | |||
619 | } | 619 | } |
620 | 620 | ||
621 | static struct usb_driver bpa10x_driver = { | 621 | static struct usb_driver bpa10x_driver = { |
622 | .owner = THIS_MODULE, | ||
623 | .name = "bpa10x", | 622 | .name = "bpa10x", |
624 | .probe = bpa10x_probe, | 623 | .probe = bpa10x_probe, |
625 | .disconnect = bpa10x_disconnect, | 624 | .disconnect = bpa10x_disconnect, |
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index 057cb2b6e6d1..92382e823285 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c | |||
@@ -1044,7 +1044,6 @@ static void hci_usb_disconnect(struct usb_interface *intf) | |||
1044 | } | 1044 | } |
1045 | 1045 | ||
1046 | static struct usb_driver hci_usb_driver = { | 1046 | static struct usb_driver hci_usb_driver = { |
1047 | .owner = THIS_MODULE, | ||
1048 | .name = "hci_usb", | 1047 | .name = "hci_usb", |
1049 | .probe = hci_usb_probe, | 1048 | .probe = hci_usb_probe, |
1050 | .disconnect = hci_usb_disconnect, | 1049 | .disconnect = hci_usb_disconnect, |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index b46a72d782d6..84e68cdd451b 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -687,7 +687,7 @@ config NVRAM | |||
687 | 687 | ||
688 | config RTC | 688 | config RTC |
689 | tristate "Enhanced Real Time Clock Support" | 689 | tristate "Enhanced Real Time Clock Support" |
690 | depends on !PPC32 && !PARISC && !IA64 && !M68K | 690 | depends on !PPC32 && !PARISC && !IA64 && !M68K && (!SPARC || PCI) |
691 | ---help--- | 691 | ---help--- |
692 | If you say Y here and create a character special file /dev/rtc with | 692 | If you say Y here and create a character special file /dev/rtc with |
693 | major number 10 and minor number 135 using mknod ("man mknod"), you | 693 | major number 10 and minor number 135 using mknod ("man mknod"), you |
@@ -735,7 +735,7 @@ config SGI_IP27_RTC | |||
735 | 735 | ||
736 | config GEN_RTC | 736 | config GEN_RTC |
737 | tristate "Generic /dev/rtc emulation" | 737 | tristate "Generic /dev/rtc emulation" |
738 | depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC32 && !SPARC64 | 738 | depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC |
739 | ---help--- | 739 | ---help--- |
740 | If you say Y here and create a character special file /dev/rtc with | 740 | If you say Y here and create a character special file /dev/rtc with |
741 | major number 10 and minor number 135 using mknod ("man mknod"), you | 741 | major number 10 and minor number 135 using mknod ("man mknod"), you |
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 9f2b4efd0c7a..342302d46743 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
@@ -1311,7 +1311,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) | |||
1311 | 1311 | ||
1312 | static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | 1312 | static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) |
1313 | { | 1313 | { |
1314 | drm_radeon_private_t *dev_priv = dev->dev_private;; | 1314 | drm_radeon_private_t *dev_priv = dev->dev_private; |
1315 | DRM_DEBUG("\n"); | 1315 | DRM_DEBUG("\n"); |
1316 | 1316 | ||
1317 | dev_priv->is_pci = init->is_pci; | 1317 | dev_priv->is_pci = init->is_pci; |
@@ -1522,7 +1522,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) | |||
1522 | 1522 | ||
1523 | dev_priv->gart_size = init->gart_size; | 1523 | dev_priv->gart_size = init->gart_size; |
1524 | dev_priv->gart_vm_start = dev_priv->fb_location | 1524 | dev_priv->gart_vm_start = dev_priv->fb_location |
1525 | + RADEON_READ(RADEON_CONFIG_APER_SIZE) * 2; | 1525 | + RADEON_READ(RADEON_CONFIG_APER_SIZE); |
1526 | 1526 | ||
1527 | #if __OS_HAS_AGP | 1527 | #if __OS_HAS_AGP |
1528 | if (!dev_priv->is_pci) | 1528 | if (!dev_priv->is_pci) |
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 7bda7e33d2bd..d92ccee3e54c 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h | |||
@@ -379,6 +379,7 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, | |||
379 | # define RADEON_PLL_WR_EN (1 << 7) | 379 | # define RADEON_PLL_WR_EN (1 << 7) |
380 | #define RADEON_CLOCK_CNTL_INDEX 0x0008 | 380 | #define RADEON_CLOCK_CNTL_INDEX 0x0008 |
381 | #define RADEON_CONFIG_APER_SIZE 0x0108 | 381 | #define RADEON_CONFIG_APER_SIZE 0x0108 |
382 | #define RADEON_CONFIG_MEMSIZE 0x00f8 | ||
382 | #define RADEON_CRTC_OFFSET 0x0224 | 383 | #define RADEON_CRTC_OFFSET 0x0224 |
383 | #define RADEON_CRTC_OFFSET_CNTL 0x0228 | 384 | #define RADEON_CRTC_OFFSET_CNTL 0x0228 |
384 | # define RADEON_CRTC_TILE_EN (1 << 15) | 385 | # define RADEON_CRTC_TILE_EN (1 << 15) |
diff --git a/drivers/char/ip2/i2pack.h b/drivers/char/ip2/i2pack.h index e9b87a78622c..00342a677c90 100644 --- a/drivers/char/ip2/i2pack.h +++ b/drivers/char/ip2/i2pack.h | |||
@@ -358,7 +358,7 @@ typedef struct _failStat | |||
358 | #define MB_OUT_STRIPPED 0x40 // Board has read all output from fifo | 358 | #define MB_OUT_STRIPPED 0x40 // Board has read all output from fifo |
359 | #define MB_FATAL_ERROR 0x20 // Board has encountered a fatal error | 359 | #define MB_FATAL_ERROR 0x20 // Board has encountered a fatal error |
360 | 360 | ||
361 | #pragma pack(4) // Reset padding to command-line default | 361 | #pragma pack() // Reset padding to command-line default |
362 | 362 | ||
363 | #endif // I2PACK_H | 363 | #endif // I2PACK_H |
364 | 364 | ||
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 449d029ad4f4..8b603b2d1c42 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -930,8 +930,8 @@ static void kbd_refresh_leds(struct input_handle *handle) | |||
930 | } | 930 | } |
931 | 931 | ||
932 | #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\ | 932 | #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\ |
933 | defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) ||\ | 933 | defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\ |
934 | defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\ | 934 | defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\ |
935 | (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC)) | 935 | (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC)) |
936 | 936 | ||
937 | #define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\ | 937 | #define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\ |
@@ -958,7 +958,7 @@ static unsigned short x86_keycodes[256] = | |||
958 | extern int mac_hid_mouse_emulate_buttons(int, int, int); | 958 | extern int mac_hid_mouse_emulate_buttons(int, int, int); |
959 | #endif /* CONFIG_MAC_EMUMOUSEBTN */ | 959 | #endif /* CONFIG_MAC_EMUMOUSEBTN */ |
960 | 960 | ||
961 | #if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) | 961 | #ifdef CONFIG_SPARC |
962 | static int sparc_l1_a_state = 0; | 962 | static int sparc_l1_a_state = 0; |
963 | extern void sun_do_break(void); | 963 | extern void sun_do_break(void); |
964 | #endif | 964 | #endif |
@@ -1045,7 +1045,7 @@ static void kbd_keycode(unsigned int keycode, int down, | |||
1045 | 1045 | ||
1046 | if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT) | 1046 | if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT) |
1047 | sysrq_alt = down; | 1047 | sysrq_alt = down; |
1048 | #if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) | 1048 | #ifdef CONFIG_SPARC |
1049 | if (keycode == KEY_STOP) | 1049 | if (keycode == KEY_STOP) |
1050 | sparc_l1_a_state = down; | 1050 | sparc_l1_a_state = down; |
1051 | #endif | 1051 | #endif |
@@ -1072,7 +1072,7 @@ static void kbd_keycode(unsigned int keycode, int down, | |||
1072 | return; | 1072 | return; |
1073 | } | 1073 | } |
1074 | #endif | 1074 | #endif |
1075 | #if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) | 1075 | #ifdef CONFIG_SPARC |
1076 | if (keycode == KEY_A && sparc_l1_a_state) { | 1076 | if (keycode == KEY_A && sparc_l1_a_state) { |
1077 | sparc_l1_a_state = 0; | 1077 | sparc_l1_a_state = 0; |
1078 | sun_do_break(); | 1078 | sun_do_break(); |
diff --git a/drivers/char/random.c b/drivers/char/random.c index 7999da25fe40..bdfdfd28594d 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -1554,10 +1554,8 @@ __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr, | |||
1554 | 1554 | ||
1555 | EXPORT_SYMBOL(secure_tcp_sequence_number); | 1555 | EXPORT_SYMBOL(secure_tcp_sequence_number); |
1556 | 1556 | ||
1557 | 1557 | /* Generate secure starting point for ephemeral IPV4 transport port search */ | |
1558 | 1558 | u32 secure_ipv4_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport) | |
1559 | /* Generate secure starting point for ephemeral TCP port search */ | ||
1560 | u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport) | ||
1561 | { | 1559 | { |
1562 | struct keydata *keyptr = get_keyptr(); | 1560 | struct keydata *keyptr = get_keyptr(); |
1563 | u32 hash[4]; | 1561 | u32 hash[4]; |
@@ -1575,7 +1573,7 @@ u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport) | |||
1575 | } | 1573 | } |
1576 | 1574 | ||
1577 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 1575 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
1578 | u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dport) | 1576 | u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dport) |
1579 | { | 1577 | { |
1580 | struct keydata *keyptr = get_keyptr(); | 1578 | struct keydata *keyptr = get_keyptr(); |
1581 | u32 hash[12]; | 1579 | u32 hash[12]; |
@@ -1586,7 +1584,7 @@ u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dp | |||
1586 | 1584 | ||
1587 | return twothirdsMD4Transform(daddr, hash); | 1585 | return twothirdsMD4Transform(daddr, hash); |
1588 | } | 1586 | } |
1589 | EXPORT_SYMBOL(secure_tcpv6_port_ephemeral); | 1587 | EXPORT_SYMBOL(secure_ipv6_port_ephemeral); |
1590 | #endif | 1588 | #endif |
1591 | 1589 | ||
1592 | #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) | 1590 | #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) |
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index f66c7ad6fd38..3c1dafaa3441 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c | |||
@@ -419,7 +419,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
419 | while (this_round > 1) { | 419 | while (this_round > 1) { |
420 | unsigned short w; | 420 | unsigned short w; |
421 | 421 | ||
422 | w = get_unaligned(((const unsigned short *)con_buf0)); | 422 | w = get_unaligned(((unsigned short *)con_buf0)); |
423 | vcs_scr_writew(vc, w, org++); | 423 | vcs_scr_writew(vc, w, org++); |
424 | con_buf0 += 2; | 424 | con_buf0 += 2; |
425 | this_round -= 2; | 425 | this_round -= 2; |
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c index c800cce73c1e..b6640606b44d 100644 --- a/drivers/char/watchdog/booke_wdt.c +++ b/drivers/char/watchdog/booke_wdt.c | |||
@@ -173,7 +173,7 @@ static int __init booke_wdt_init(void) | |||
173 | int ret = 0; | 173 | int ret = 0; |
174 | 174 | ||
175 | printk (KERN_INFO "PowerPC Book-E Watchdog Timer Loaded\n"); | 175 | printk (KERN_INFO "PowerPC Book-E Watchdog Timer Loaded\n"); |
176 | ident.firmware_version = cpu_specs[0].pvr_value; | 176 | ident.firmware_version = cur_cpu_spec->pvr_value; |
177 | 177 | ||
178 | ret = misc_register(&booke_wdt_miscdev); | 178 | ret = misc_register(&booke_wdt_miscdev); |
179 | if (ret) { | 179 | if (ret) { |
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c index 092e9b133750..1533f56baa42 100644 --- a/drivers/char/watchdog/pcwd_usb.c +++ b/drivers/char/watchdog/pcwd_usb.c | |||
@@ -151,7 +151,6 @@ static void usb_pcwd_disconnect (struct usb_interface *interface); | |||
151 | 151 | ||
152 | /* usb specific object needed to register this driver with the usb subsystem */ | 152 | /* usb specific object needed to register this driver with the usb subsystem */ |
153 | static struct usb_driver usb_pcwd_driver = { | 153 | static struct usb_driver usb_pcwd_driver = { |
154 | .owner = THIS_MODULE, | ||
155 | .name = DRIVER_NAME, | 154 | .name = DRIVER_NAME, |
156 | .probe = usb_pcwd_probe, | 155 | .probe = usb_pcwd_probe, |
157 | .disconnect = usb_pcwd_disconnect, | 156 | .disconnect = usb_pcwd_disconnect, |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 815902c2c856..a9163d02983a 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -823,6 +823,30 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, unsigne | |||
823 | 823 | ||
824 | 824 | ||
825 | /** | 825 | /** |
826 | * cpufreq_quick_get - get the CPU frequency (in kHz) frpm policy->cur | ||
827 | * @cpu: CPU number | ||
828 | * | ||
829 | * This is the last known freq, without actually getting it from the driver. | ||
830 | * Return value will be same as what is shown in scaling_cur_freq in sysfs. | ||
831 | */ | ||
832 | unsigned int cpufreq_quick_get(unsigned int cpu) | ||
833 | { | ||
834 | struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); | ||
835 | unsigned int ret = 0; | ||
836 | |||
837 | if (policy) { | ||
838 | down(&policy->lock); | ||
839 | ret = policy->cur; | ||
840 | up(&policy->lock); | ||
841 | cpufreq_cpu_put(policy); | ||
842 | } | ||
843 | |||
844 | return (ret); | ||
845 | } | ||
846 | EXPORT_SYMBOL(cpufreq_quick_get); | ||
847 | |||
848 | |||
849 | /** | ||
826 | * cpufreq_get - get the current CPU frequency (in kHz) | 850 | * cpufreq_get - get the current CPU frequency (in kHz) |
827 | * @cpu: CPU number | 851 | * @cpu: CPU number |
828 | * | 852 | * |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 2ed5c4363b53..39543a2bed0f 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
@@ -93,7 +93,7 @@ static inline unsigned int get_cpu_idle_time(unsigned int cpu) | |||
93 | { | 93 | { |
94 | return kstat_cpu(cpu).cpustat.idle + | 94 | return kstat_cpu(cpu).cpustat.idle + |
95 | kstat_cpu(cpu).cpustat.iowait + | 95 | kstat_cpu(cpu).cpustat.iowait + |
96 | ( !dbs_tuners_ins.ignore_nice ? | 96 | ( dbs_tuners_ins.ignore_nice ? |
97 | kstat_cpu(cpu).cpustat.nice : | 97 | kstat_cpu(cpu).cpustat.nice : |
98 | 0); | 98 | 0); |
99 | } | 99 | } |
@@ -127,7 +127,7 @@ show_one(sampling_rate, sampling_rate); | |||
127 | show_one(sampling_down_factor, sampling_down_factor); | 127 | show_one(sampling_down_factor, sampling_down_factor); |
128 | show_one(up_threshold, up_threshold); | 128 | show_one(up_threshold, up_threshold); |
129 | show_one(down_threshold, down_threshold); | 129 | show_one(down_threshold, down_threshold); |
130 | show_one(ignore_nice, ignore_nice); | 130 | show_one(ignore_nice_load, ignore_nice); |
131 | show_one(freq_step, freq_step); | 131 | show_one(freq_step, freq_step); |
132 | 132 | ||
133 | static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, | 133 | static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, |
@@ -207,7 +207,7 @@ static ssize_t store_down_threshold(struct cpufreq_policy *unused, | |||
207 | return count; | 207 | return count; |
208 | } | 208 | } |
209 | 209 | ||
210 | static ssize_t store_ignore_nice(struct cpufreq_policy *policy, | 210 | static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, |
211 | const char *buf, size_t count) | 211 | const char *buf, size_t count) |
212 | { | 212 | { |
213 | unsigned int input; | 213 | unsigned int input; |
@@ -272,7 +272,7 @@ define_one_rw(sampling_rate); | |||
272 | define_one_rw(sampling_down_factor); | 272 | define_one_rw(sampling_down_factor); |
273 | define_one_rw(up_threshold); | 273 | define_one_rw(up_threshold); |
274 | define_one_rw(down_threshold); | 274 | define_one_rw(down_threshold); |
275 | define_one_rw(ignore_nice); | 275 | define_one_rw(ignore_nice_load); |
276 | define_one_rw(freq_step); | 276 | define_one_rw(freq_step); |
277 | 277 | ||
278 | static struct attribute * dbs_attributes[] = { | 278 | static struct attribute * dbs_attributes[] = { |
@@ -282,7 +282,7 @@ static struct attribute * dbs_attributes[] = { | |||
282 | &sampling_down_factor.attr, | 282 | &sampling_down_factor.attr, |
283 | &up_threshold.attr, | 283 | &up_threshold.attr, |
284 | &down_threshold.attr, | 284 | &down_threshold.attr, |
285 | &ignore_nice.attr, | 285 | &ignore_nice_load.attr, |
286 | &freq_step.attr, | 286 | &freq_step.attr, |
287 | NULL | 287 | NULL |
288 | }; | 288 | }; |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 17741111246b..e69fd8dd1f1c 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -89,7 +89,7 @@ static inline unsigned int get_cpu_idle_time(unsigned int cpu) | |||
89 | { | 89 | { |
90 | return kstat_cpu(cpu).cpustat.idle + | 90 | return kstat_cpu(cpu).cpustat.idle + |
91 | kstat_cpu(cpu).cpustat.iowait + | 91 | kstat_cpu(cpu).cpustat.iowait + |
92 | ( !dbs_tuners_ins.ignore_nice ? | 92 | ( dbs_tuners_ins.ignore_nice ? |
93 | kstat_cpu(cpu).cpustat.nice : | 93 | kstat_cpu(cpu).cpustat.nice : |
94 | 0); | 94 | 0); |
95 | } | 95 | } |
@@ -122,7 +122,7 @@ static ssize_t show_##file_name \ | |||
122 | show_one(sampling_rate, sampling_rate); | 122 | show_one(sampling_rate, sampling_rate); |
123 | show_one(sampling_down_factor, sampling_down_factor); | 123 | show_one(sampling_down_factor, sampling_down_factor); |
124 | show_one(up_threshold, up_threshold); | 124 | show_one(up_threshold, up_threshold); |
125 | show_one(ignore_nice, ignore_nice); | 125 | show_one(ignore_nice_load, ignore_nice); |
126 | 126 | ||
127 | static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, | 127 | static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, |
128 | const char *buf, size_t count) | 128 | const char *buf, size_t count) |
@@ -182,7 +182,7 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, | |||
182 | return count; | 182 | return count; |
183 | } | 183 | } |
184 | 184 | ||
185 | static ssize_t store_ignore_nice(struct cpufreq_policy *policy, | 185 | static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, |
186 | const char *buf, size_t count) | 186 | const char *buf, size_t count) |
187 | { | 187 | { |
188 | unsigned int input; | 188 | unsigned int input; |
@@ -223,7 +223,7 @@ __ATTR(_name, 0644, show_##_name, store_##_name) | |||
223 | define_one_rw(sampling_rate); | 223 | define_one_rw(sampling_rate); |
224 | define_one_rw(sampling_down_factor); | 224 | define_one_rw(sampling_down_factor); |
225 | define_one_rw(up_threshold); | 225 | define_one_rw(up_threshold); |
226 | define_one_rw(ignore_nice); | 226 | define_one_rw(ignore_nice_load); |
227 | 227 | ||
228 | static struct attribute * dbs_attributes[] = { | 228 | static struct attribute * dbs_attributes[] = { |
229 | &sampling_rate_max.attr, | 229 | &sampling_rate_max.attr, |
@@ -231,7 +231,7 @@ static struct attribute * dbs_attributes[] = { | |||
231 | &sampling_rate.attr, | 231 | &sampling_rate.attr, |
232 | &sampling_down_factor.attr, | 232 | &sampling_down_factor.attr, |
233 | &up_threshold.attr, | 233 | &up_threshold.attr, |
234 | &ignore_nice.attr, | 234 | &ignore_nice_load.attr, |
235 | NULL | 235 | NULL |
236 | }; | 236 | }; |
237 | 237 | ||
diff --git a/drivers/fc4/Kconfig b/drivers/fc4/Kconfig index f00c02a13ed6..345dbe6f10df 100644 --- a/drivers/fc4/Kconfig +++ b/drivers/fc4/Kconfig | |||
@@ -26,7 +26,7 @@ comment "FC4 drivers" | |||
26 | 26 | ||
27 | config FC4_SOC | 27 | config FC4_SOC |
28 | tristate "Sun SOC/Sbus" | 28 | tristate "Sun SOC/Sbus" |
29 | depends on FC4!=n && (SPARC32 || SPARC64) | 29 | depends on FC4!=n && SPARC |
30 | help | 30 | help |
31 | Serial Optical Channel is an interface card with one or two Fibre | 31 | Serial Optical Channel is an interface card with one or two Fibre |
32 | Optic ports, each of which can be connected to a disk array. Note | 32 | Optic ports, each of which can be connected to a disk array. Note |
@@ -38,7 +38,7 @@ config FC4_SOC | |||
38 | 38 | ||
39 | config FC4_SOCAL | 39 | config FC4_SOCAL |
40 | tristate "Sun SOC+ (aka SOCAL)" | 40 | tristate "Sun SOC+ (aka SOCAL)" |
41 | depends on FC4!=n && (SPARC32 || SPARC64) | 41 | depends on FC4!=n && SPARC |
42 | ---help--- | 42 | ---help--- |
43 | Serial Optical Channel Plus is an interface card with up to two | 43 | Serial Optical Channel Plus is an interface card with up to two |
44 | Fibre Optic ports. This card supports FC Arbitrated Loop (usually | 44 | Fibre Optic ports. This card supports FC Arbitrated Loop (usually |
@@ -62,7 +62,7 @@ config SCSI_PLUTO | |||
62 | be called pluto. | 62 | be called pluto. |
63 | 63 | ||
64 | config SCSI_FCAL | 64 | config SCSI_FCAL |
65 | tristate "Sun Enterprise Network Array (A5000 and EX500)" if SPARC32 || SPARC64 | 65 | tristate "Sun Enterprise Network Array (A5000 and EX500)" if SPARC |
66 | depends on FC4!=n && SCSI | 66 | depends on FC4!=n && SCSI |
67 | help | 67 | help |
68 | This driver drives FC-AL disks connected through a Fibre Channel | 68 | This driver drives FC-AL disks connected through a Fibre Channel |
@@ -75,7 +75,7 @@ config SCSI_FCAL | |||
75 | 75 | ||
76 | config SCSI_FCAL | 76 | config SCSI_FCAL |
77 | prompt "Generic FC-AL disk driver" | 77 | prompt "Generic FC-AL disk driver" |
78 | depends on FC4!=n && SCSI && !SPARC32 && !SPARC64 | 78 | depends on FC4!=n && SCSI && !SPARC |
79 | 79 | ||
80 | endmenu | 80 | endmenu |
81 | 81 | ||
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index afd7634e5cc9..81031eb51056 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c | |||
@@ -529,14 +529,15 @@ mv64xxx_i2c_probe(struct platform_device *pd) | |||
529 | i2c_set_adapdata(&drv_data->adapter, drv_data); | 529 | i2c_set_adapdata(&drv_data->adapter, drv_data); |
530 | 530 | ||
531 | if (request_irq(drv_data->irq, mv64xxx_i2c_intr, 0, | 531 | if (request_irq(drv_data->irq, mv64xxx_i2c_intr, 0, |
532 | MV64XXX_I2C_CTLR_NAME, drv_data)) { | 532 | MV64XXX_I2C_CTLR_NAME, drv_data)) { |
533 | 533 | dev_err(&drv_data->adapter.dev, | |
534 | dev_err(dev, "mv64xxx: Can't register intr handler " | 534 | "mv64xxx: Can't register intr handler irq: %d\n", |
535 | "irq: %d\n", drv_data->irq); | 535 | drv_data->irq); |
536 | rc = -EINVAL; | 536 | rc = -EINVAL; |
537 | goto exit_unmap_regs; | 537 | goto exit_unmap_regs; |
538 | } else if ((rc = i2c_add_adapter(&drv_data->adapter)) != 0) { | 538 | } else if ((rc = i2c_add_adapter(&drv_data->adapter)) != 0) { |
539 | dev_err(dev, "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc); | 539 | dev_err(&drv_data->adapter.dev, |
540 | "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc); | ||
540 | goto exit_free_irq; | 541 | goto exit_free_irq; |
541 | } | 542 | } |
542 | 543 | ||
diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h index 38f42112dff0..ae9b02cc013f 100644 --- a/drivers/ieee1394/hosts.h +++ b/drivers/ieee1394/hosts.h | |||
@@ -41,6 +41,7 @@ struct hpsb_host { | |||
41 | /* this nodes state */ | 41 | /* this nodes state */ |
42 | unsigned in_bus_reset:1; | 42 | unsigned in_bus_reset:1; |
43 | unsigned is_shutdown:1; | 43 | unsigned is_shutdown:1; |
44 | unsigned resume_packet_sent:1; | ||
44 | 45 | ||
45 | /* this nodes' duties on the bus */ | 46 | /* this nodes' duties on the bus */ |
46 | unsigned is_root:1; | 47 | unsigned is_root:1; |
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 7fff5a1d2ea4..0ea37b1bccb2 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
@@ -1349,6 +1349,33 @@ static void nodemgr_update_pdrv(struct node_entry *ne) | |||
1349 | } | 1349 | } |
1350 | 1350 | ||
1351 | 1351 | ||
1352 | /* Write the BROADCAST_CHANNEL as per IEEE1394a 8.3.2.3.11 and 8.4.2.3. This | ||
1353 | * seems like an optional service but in the end it is practically mandatory | ||
1354 | * as a consequence of these clauses. | ||
1355 | * | ||
1356 | * Note that we cannot do a broadcast write to all nodes at once because some | ||
1357 | * pre-1394a devices would hang. */ | ||
1358 | static void nodemgr_irm_write_bc(struct node_entry *ne, int generation) | ||
1359 | { | ||
1360 | const u64 bc_addr = (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL); | ||
1361 | quadlet_t bc_remote, bc_local; | ||
1362 | int ret; | ||
1363 | |||
1364 | if (!ne->host->is_irm || ne->generation != generation || | ||
1365 | ne->nodeid == ne->host->node_id) | ||
1366 | return; | ||
1367 | |||
1368 | bc_local = cpu_to_be32(ne->host->csr.broadcast_channel); | ||
1369 | |||
1370 | /* Check if the register is implemented and 1394a compliant. */ | ||
1371 | ret = hpsb_read(ne->host, ne->nodeid, generation, bc_addr, &bc_remote, | ||
1372 | sizeof(bc_remote)); | ||
1373 | if (!ret && bc_remote & cpu_to_be32(0x80000000) && | ||
1374 | bc_remote != bc_local) | ||
1375 | hpsb_node_write(ne, bc_addr, &bc_local, sizeof(bc_local)); | ||
1376 | } | ||
1377 | |||
1378 | |||
1352 | static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation) | 1379 | static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation) |
1353 | { | 1380 | { |
1354 | struct device *dev; | 1381 | struct device *dev; |
@@ -1360,6 +1387,8 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge | |||
1360 | if (!dev) | 1387 | if (!dev) |
1361 | return; | 1388 | return; |
1362 | 1389 | ||
1390 | nodemgr_irm_write_bc(ne, generation); | ||
1391 | |||
1363 | /* If "needs_probe", then this is either a new or changed node we | 1392 | /* If "needs_probe", then this is either a new or changed node we |
1364 | * rescan totally. If the generation matches for an existing node | 1393 | * rescan totally. If the generation matches for an existing node |
1365 | * (one that existed prior to the bus reset) we send update calls | 1394 | * (one that existed prior to the bus reset) we send update calls |
@@ -1413,9 +1442,25 @@ static void nodemgr_node_probe(struct host_info *hi, int generation) | |||
1413 | return; | 1442 | return; |
1414 | } | 1443 | } |
1415 | 1444 | ||
1416 | /* Because we are a 1394a-2000 compliant IRM, we need to inform all the other | 1445 | static int nodemgr_send_resume_packet(struct hpsb_host *host) |
1417 | * nodes of the broadcast channel. (Really we're only setting the validity | 1446 | { |
1418 | * bit). Other IRM responsibilities go in here as well. */ | 1447 | struct hpsb_packet *packet; |
1448 | int ret = 1; | ||
1449 | |||
1450 | packet = hpsb_make_phypacket(host, | ||
1451 | 0x003c0000 | NODEID_TO_NODE(host->node_id) << 24); | ||
1452 | if (packet) { | ||
1453 | packet->no_waiter = 1; | ||
1454 | packet->generation = get_hpsb_generation(host); | ||
1455 | ret = hpsb_send_packet(packet); | ||
1456 | } | ||
1457 | if (ret) | ||
1458 | HPSB_WARN("fw-host%d: Failed to broadcast resume packet", | ||
1459 | host->id); | ||
1460 | return ret; | ||
1461 | } | ||
1462 | |||
1463 | /* Perform a few high-level IRM responsibilities. */ | ||
1419 | static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles) | 1464 | static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles) |
1420 | { | 1465 | { |
1421 | quadlet_t bc; | 1466 | quadlet_t bc; |
@@ -1424,13 +1469,8 @@ static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles) | |||
1424 | if (!host->is_irm || host->irm_id == (nodeid_t)-1) | 1469 | if (!host->is_irm || host->irm_id == (nodeid_t)-1) |
1425 | return 1; | 1470 | return 1; |
1426 | 1471 | ||
1427 | host->csr.broadcast_channel |= 0x40000000; /* set validity bit */ | 1472 | /* We are a 1394a-2000 compliant IRM. Set the validity bit. */ |
1428 | 1473 | host->csr.broadcast_channel |= 0x40000000; | |
1429 | bc = cpu_to_be32(host->csr.broadcast_channel); | ||
1430 | |||
1431 | hpsb_write(host, LOCAL_BUS | ALL_NODES, get_hpsb_generation(host), | ||
1432 | (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL), | ||
1433 | &bc, sizeof(quadlet_t)); | ||
1434 | 1474 | ||
1435 | /* If there is no bus manager then we should set the root node's | 1475 | /* If there is no bus manager then we should set the root node's |
1436 | * force_root bit to promote bus stability per the 1394 | 1476 | * force_root bit to promote bus stability per the 1394 |
@@ -1463,6 +1503,13 @@ static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles) | |||
1463 | } | 1503 | } |
1464 | } | 1504 | } |
1465 | 1505 | ||
1506 | /* Some devices suspend their ports while being connected to an inactive | ||
1507 | * host adapter, i.e. if connected before the low-level driver is | ||
1508 | * loaded. They become visible either when physically unplugged and | ||
1509 | * replugged, or when receiving a resume packet. Send one once. */ | ||
1510 | if (!host->resume_packet_sent && !nodemgr_send_resume_packet(host)) | ||
1511 | host->resume_packet_sent = 1; | ||
1512 | |||
1466 | return 1; | 1513 | return 1; |
1467 | } | 1514 | } |
1468 | 1515 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 475d98fa9e26..780009c7eaa6 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -47,6 +47,8 @@ | |||
47 | #include <linux/ip.h> | 47 | #include <linux/ip.h> |
48 | #include <linux/in.h> | 48 | #include <linux/in.h> |
49 | 49 | ||
50 | #include <net/dst.h> | ||
51 | |||
50 | MODULE_AUTHOR("Roland Dreier"); | 52 | MODULE_AUTHOR("Roland Dreier"); |
51 | MODULE_DESCRIPTION("IP-over-InfiniBand net driver"); | 53 | MODULE_DESCRIPTION("IP-over-InfiniBand net driver"); |
52 | MODULE_LICENSE("Dual BSD/GPL"); | 54 | MODULE_LICENSE("Dual BSD/GPL"); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index ef3ee035bbc8..ed0c2ead8bc1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -43,6 +43,8 @@ | |||
43 | #include <linux/delay.h> | 43 | #include <linux/delay.h> |
44 | #include <linux/completion.h> | 44 | #include <linux/completion.h> |
45 | 45 | ||
46 | #include <net/dst.h> | ||
47 | |||
46 | #include "ipoib.h" | 48 | #include "ipoib.h" |
47 | 49 | ||
48 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG | 50 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG |
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index 64b4a3080985..bc2fce60f9f8 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c | |||
@@ -235,7 +235,6 @@ static struct usb_device_id iforce_usb_ids [] = { | |||
235 | MODULE_DEVICE_TABLE (usb, iforce_usb_ids); | 235 | MODULE_DEVICE_TABLE (usb, iforce_usb_ids); |
236 | 236 | ||
237 | struct usb_driver iforce_usb_driver = { | 237 | struct usb_driver iforce_usb_driver = { |
238 | .owner = THIS_MODULE, | ||
239 | .name = "iforce", | 238 | .name = "iforce", |
240 | .probe = iforce_usb_probe, | 239 | .probe = iforce_usb_probe, |
241 | .disconnect = iforce_usb_disconnect, | 240 | .disconnect = iforce_usb_disconnect, |
diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c index 99a642d2a1fe..1849b176cf18 100644 --- a/drivers/input/joystick/warrior.c +++ b/drivers/input/joystick/warrior.c | |||
@@ -172,7 +172,7 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) | |||
172 | input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 8); | 172 | input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 8); |
173 | input_set_abs_params(input_dev, ABS_THROTTLE, -112, 112, 0, 0); | 173 | input_set_abs_params(input_dev, ABS_THROTTLE, -112, 112, 0, 0); |
174 | input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0); | 174 | input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0); |
175 | input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0); | 175 | input_set_abs_params(input_dev, ABS_HAT0Y, -1, 1, 0, 0); |
176 | 176 | ||
177 | serio_set_drvdata(serio, warrior); | 177 | serio_set_drvdata(serio, warrior); |
178 | 178 | ||
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 07813fc0523f..e08dbe08f46d 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -26,7 +26,7 @@ config INPUT_PCSPKR | |||
26 | 26 | ||
27 | config INPUT_SPARCSPKR | 27 | config INPUT_SPARCSPKR |
28 | tristate "SPARC Speaker support" | 28 | tristate "SPARC Speaker support" |
29 | depends on PCI && (SPARC32 || SPARC64) | 29 | depends on PCI && SPARC |
30 | help | 30 | help |
31 | Say Y here if you want the standard Speaker on Sparc PCI systems | 31 | Say Y here if you want the standard Speaker on Sparc PCI systems |
32 | to be used for bells and whistles. | 32 | to be used for bells and whistles. |
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index 4bf584364d28..2f9a04ae725f 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c | |||
@@ -95,7 +95,7 @@ static void sermouse_process_msc(struct sermouse *sermouse, signed char data, st | |||
95 | 95 | ||
96 | input_sync(dev); | 96 | input_sync(dev); |
97 | 97 | ||
98 | if (++sermouse->count == (5 - ((sermouse->type == SERIO_SUN) << 1))) | 98 | if (++sermouse->count == 5) |
99 | sermouse->count = 0; | 99 | sermouse->count = 0; |
100 | } | 100 | } |
101 | 101 | ||
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h index 13835039a2a7..cbbf3842da5b 100644 --- a/drivers/input/serio/i8042.h +++ b/drivers/input/serio/i8042.h | |||
@@ -21,7 +21,7 @@ | |||
21 | #include "i8042-ip22io.h" | 21 | #include "i8042-ip22io.h" |
22 | #elif defined(CONFIG_PPC) | 22 | #elif defined(CONFIG_PPC) |
23 | #include "i8042-ppcio.h" | 23 | #include "i8042-ppcio.h" |
24 | #elif defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) | 24 | #elif defined(CONFIG_SPARC) |
25 | #include "i8042-sparcio.h" | 25 | #include "i8042-sparcio.h" |
26 | #elif defined(CONFIG_X86) || defined(CONFIG_IA64) | 26 | #elif defined(CONFIG_X86) || defined(CONFIG_IA64) |
27 | #include "i8042-x86ia64io.h" | 27 | #include "i8042-x86ia64io.h" |
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index f8457ef48826..ca5b4a3b683e 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c | |||
@@ -1715,7 +1715,6 @@ hfc_usb_disconnect(struct usb_interface | |||
1715 | /* our driver information structure */ | 1715 | /* our driver information structure */ |
1716 | /************************************/ | 1716 | /************************************/ |
1717 | static struct usb_driver hfc_drv = { | 1717 | static struct usb_driver hfc_drv = { |
1718 | .owner = THIS_MODULE, | ||
1719 | .name = "hfc_usb", | 1718 | .name = "hfc_usb", |
1720 | .id_table = hfcusb_idtab, | 1719 | .id_table = hfcusb_idtab, |
1721 | .probe = hfc_usb_probe, | 1720 | .probe = hfc_usb_probe, |
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c index 8e192a3a3490..99cb0f3d59a1 100644 --- a/drivers/isdn/hisax/st5481_init.c +++ b/drivers/isdn/hisax/st5481_init.c | |||
@@ -180,7 +180,6 @@ static struct usb_device_id st5481_ids[] = { | |||
180 | MODULE_DEVICE_TABLE (usb, st5481_ids); | 180 | MODULE_DEVICE_TABLE (usb, st5481_ids); |
181 | 181 | ||
182 | static struct usb_driver st5481_usb_driver = { | 182 | static struct usb_driver st5481_usb_driver = { |
183 | .owner = THIS_MODULE, | ||
184 | .name = "st5481_usb", | 183 | .name = "st5481_usb", |
185 | .probe = probe_st5481, | 184 | .probe = probe_st5481, |
186 | .disconnect = disconnect_st5481, | 185 | .disconnect = disconnect_st5481, |
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 3fc8cdd94c3d..190878eef990 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c | |||
@@ -923,7 +923,7 @@ static void do_monitor_cpu_combined(void) | |||
923 | if (temp_combi >= ((state0->mpu.tmax + 8) << 16)) { | 923 | if (temp_combi >= ((state0->mpu.tmax + 8) << 16)) { |
924 | printk(KERN_WARNING "Warning ! Temperature way above maximum (%d) !\n", | 924 | printk(KERN_WARNING "Warning ! Temperature way above maximum (%d) !\n", |
925 | temp_combi >> 16); | 925 | temp_combi >> 16); |
926 | state0->overtemp = CPU_MAX_OVERTEMP; | 926 | state0->overtemp += CPU_MAX_OVERTEMP / 4; |
927 | } else if (temp_combi > (state0->mpu.tmax << 16)) | 927 | } else if (temp_combi > (state0->mpu.tmax << 16)) |
928 | state0->overtemp++; | 928 | state0->overtemp++; |
929 | else | 929 | else |
@@ -933,7 +933,7 @@ static void do_monitor_cpu_combined(void) | |||
933 | if (state0->overtemp > 0) { | 933 | if (state0->overtemp > 0) { |
934 | state0->rpm = state0->mpu.rmaxn_exhaust_fan; | 934 | state0->rpm = state0->mpu.rmaxn_exhaust_fan; |
935 | state0->intake_rpm = intake = state0->mpu.rmaxn_intake_fan; | 935 | state0->intake_rpm = intake = state0->mpu.rmaxn_intake_fan; |
936 | pump = state0->pump_min; | 936 | pump = state0->pump_max; |
937 | goto do_set_fans; | 937 | goto do_set_fans; |
938 | } | 938 | } |
939 | 939 | ||
@@ -998,7 +998,7 @@ static void do_monitor_cpu_split(struct cpu_pid_state *state) | |||
998 | printk(KERN_WARNING "Warning ! CPU %d temperature way above maximum" | 998 | printk(KERN_WARNING "Warning ! CPU %d temperature way above maximum" |
999 | " (%d) !\n", | 999 | " (%d) !\n", |
1000 | state->index, temp >> 16); | 1000 | state->index, temp >> 16); |
1001 | state->overtemp = CPU_MAX_OVERTEMP; | 1001 | state->overtemp += CPU_MAX_OVERTEMP / 4; |
1002 | } else if (temp > (state->mpu.tmax << 16)) | 1002 | } else if (temp > (state->mpu.tmax << 16)) |
1003 | state->overtemp++; | 1003 | state->overtemp++; |
1004 | else | 1004 | else |
@@ -1060,7 +1060,7 @@ static void do_monitor_cpu_rack(struct cpu_pid_state *state) | |||
1060 | printk(KERN_WARNING "Warning ! CPU %d temperature way above maximum" | 1060 | printk(KERN_WARNING "Warning ! CPU %d temperature way above maximum" |
1061 | " (%d) !\n", | 1061 | " (%d) !\n", |
1062 | state->index, temp >> 16); | 1062 | state->index, temp >> 16); |
1063 | state->overtemp = CPU_MAX_OVERTEMP; | 1063 | state->overtemp = CPU_MAX_OVERTEMP / 4; |
1064 | } else if (temp > (state->mpu.tmax << 16)) | 1064 | } else if (temp > (state->mpu.tmax << 16)) |
1065 | state->overtemp++; | 1065 | state->overtemp++; |
1066 | else | 1066 | else |
diff --git a/drivers/md/md.c b/drivers/md/md.c index cd12fca73b0d..8175a2a222da 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1729,7 +1729,7 @@ level_show(mddev_t *mddev, char *page) | |||
1729 | if (p == NULL && mddev->raid_disks == 0) | 1729 | if (p == NULL && mddev->raid_disks == 0) |
1730 | return 0; | 1730 | return 0; |
1731 | if (mddev->level >= 0) | 1731 | if (mddev->level >= 0) |
1732 | return sprintf(page, "RAID-%d\n", mddev->level); | 1732 | return sprintf(page, "raid%d\n", mddev->level); |
1733 | else | 1733 | else |
1734 | return sprintf(page, "%s\n", p->name); | 1734 | return sprintf(page, "%s\n", p->name); |
1735 | } | 1735 | } |
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c index 0a78ba3737a5..a6c91db40ad6 100644 --- a/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/drivers/media/dvb/b2c2/flexcop-usb.c | |||
@@ -544,7 +544,6 @@ static struct usb_device_id flexcop_usb_table [] = { | |||
544 | 544 | ||
545 | /* usb specific object needed to register this driver with the usb subsystem */ | 545 | /* usb specific object needed to register this driver with the usb subsystem */ |
546 | static struct usb_driver flexcop_usb_driver = { | 546 | static struct usb_driver flexcop_usb_driver = { |
547 | .owner = THIS_MODULE, | ||
548 | .name = "b2c2_flexcop_usb", | 547 | .name = "b2c2_flexcop_usb", |
549 | .probe = flexcop_usb_probe, | 548 | .probe = flexcop_usb_probe, |
550 | .disconnect = flexcop_usb_disconnect, | 549 | .disconnect = flexcop_usb_disconnect, |
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index 336fc284fa52..b996fb59b7e4 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c | |||
@@ -986,7 +986,6 @@ static const struct usb_device_id cinergyt2_table [] __devinitdata = { | |||
986 | MODULE_DEVICE_TABLE(usb, cinergyt2_table); | 986 | MODULE_DEVICE_TABLE(usb, cinergyt2_table); |
987 | 987 | ||
988 | static struct usb_driver cinergyt2_driver = { | 988 | static struct usb_driver cinergyt2_driver = { |
989 | .owner = THIS_MODULE, | ||
990 | .name = "cinergyT2", | 989 | .name = "cinergyT2", |
991 | .probe = cinergyt2_probe, | 990 | .probe = cinergyt2_probe, |
992 | .disconnect = cinergyt2_disconnect, | 991 | .disconnect = cinergyt2_disconnect, |
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c index 8c7beffb045f..ce44aa6bbb83 100644 --- a/drivers/media/dvb/dvb-usb/a800.c +++ b/drivers/media/dvb/dvb-usb/a800.c | |||
@@ -144,7 +144,6 @@ static struct dvb_usb_properties a800_properties = { | |||
144 | }; | 144 | }; |
145 | 145 | ||
146 | static struct usb_driver a800_driver = { | 146 | static struct usb_driver a800_driver = { |
147 | .owner = THIS_MODULE, | ||
148 | .name = "dvb_usb_a800", | 147 | .name = "dvb_usb_a800", |
149 | .probe = a800_probe, | 148 | .probe = a800_probe, |
150 | .disconnect = dvb_usb_device_exit, | 149 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 3fe383f4bb4c..d05fab01cccd 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c | |||
@@ -241,7 +241,6 @@ static struct dvb_usb_properties cxusb_properties = { | |||
241 | }; | 241 | }; |
242 | 242 | ||
243 | static struct usb_driver cxusb_driver = { | 243 | static struct usb_driver cxusb_driver = { |
244 | .owner = THIS_MODULE, | ||
245 | .name = "dvb_usb_cxusb", | 244 | .name = "dvb_usb_cxusb", |
246 | .probe = cxusb_probe, | 245 | .probe = cxusb_probe, |
247 | .disconnect = dvb_usb_device_exit, | 246 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index aa271a2496d5..52ac3e5adf5d 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c | |||
@@ -373,7 +373,6 @@ static struct dvb_usb_properties artec_t1_usb2_properties = { | |||
373 | }; | 373 | }; |
374 | 374 | ||
375 | static struct usb_driver dibusb_driver = { | 375 | static struct usb_driver dibusb_driver = { |
376 | .owner = THIS_MODULE, | ||
377 | .name = "dvb_usb_dibusb_mb", | 376 | .name = "dvb_usb_dibusb_mb", |
378 | .probe = dibusb_probe, | 377 | .probe = dibusb_probe, |
379 | .disconnect = dvb_usb_device_exit, | 378 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c index 6a0912eab396..55802fba3c29 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mc.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c | |||
@@ -82,7 +82,6 @@ static struct dvb_usb_properties dibusb_mc_properties = { | |||
82 | }; | 82 | }; |
83 | 83 | ||
84 | static struct usb_driver dibusb_mc_driver = { | 84 | static struct usb_driver dibusb_mc_driver = { |
85 | .owner = THIS_MODULE, | ||
86 | .name = "dvb_usb_dibusb_mc", | 85 | .name = "dvb_usb_dibusb_mc", |
87 | .probe = dibusb_mc_probe, | 86 | .probe = dibusb_mc_probe, |
88 | .disconnect = dvb_usb_device_exit, | 87 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index f98e306a5759..450417a9e64b 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c | |||
@@ -233,7 +233,6 @@ static struct dvb_usb_properties digitv_properties = { | |||
233 | }; | 233 | }; |
234 | 234 | ||
235 | static struct usb_driver digitv_driver = { | 235 | static struct usb_driver digitv_driver = { |
236 | .owner = THIS_MODULE, | ||
237 | .name = "dvb_usb_digitv", | 236 | .name = "dvb_usb_digitv", |
238 | .probe = digitv_probe, | 237 | .probe = digitv_probe, |
239 | .disconnect = dvb_usb_device_exit, | 238 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c index b595476332cd..6e2bac873445 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/drivers/media/dvb/dvb-usb/dtt200u.c | |||
@@ -198,7 +198,6 @@ static struct dvb_usb_properties wt220u_properties = { | |||
198 | 198 | ||
199 | /* usb specific object needed to register this driver with the usb subsystem */ | 199 | /* usb specific object needed to register this driver with the usb subsystem */ |
200 | static struct usb_driver dtt200u_usb_driver = { | 200 | static struct usb_driver dtt200u_usb_driver = { |
201 | .owner = THIS_MODULE, | ||
202 | .name = "dvb_usb_dtt200u", | 201 | .name = "dvb_usb_dtt200u", |
203 | .probe = dtt200u_usb_probe, | 202 | .probe = dtt200u_usb_probe, |
204 | .disconnect = dvb_usb_device_exit, | 203 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c index 1841a66427bf..fac48fc7a4ac 100644 --- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c +++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c | |||
@@ -202,7 +202,6 @@ static struct dvb_usb_properties nova_t_properties = { | |||
202 | }; | 202 | }; |
203 | 203 | ||
204 | static struct usb_driver nova_t_driver = { | 204 | static struct usb_driver nova_t_driver = { |
205 | .owner = THIS_MODULE, | ||
206 | .name = "dvb_usb_nova_t_usb2", | 205 | .name = "dvb_usb_nova_t_usb2", |
207 | .probe = nova_t_probe, | 206 | .probe = nova_t_probe, |
208 | .disconnect = dvb_usb_device_exit, | 207 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c index 6fd67657c269..14f1911c79bb 100644 --- a/drivers/media/dvb/dvb-usb/umt-010.c +++ b/drivers/media/dvb/dvb-usb/umt-010.c | |||
@@ -128,7 +128,6 @@ static struct dvb_usb_properties umt_properties = { | |||
128 | }; | 128 | }; |
129 | 129 | ||
130 | static struct usb_driver umt_driver = { | 130 | static struct usb_driver umt_driver = { |
131 | .owner = THIS_MODULE, | ||
132 | .name = "dvb_usb_umt_010", | 131 | .name = "dvb_usb_umt_010", |
133 | .probe = umt_probe, | 132 | .probe = umt_probe, |
134 | .disconnect = dvb_usb_device_exit, | 133 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c index de13c04e8e64..afa00fdb5ec0 100644 --- a/drivers/media/dvb/dvb-usb/vp702x.c +++ b/drivers/media/dvb/dvb-usb/vp702x.c | |||
@@ -256,7 +256,6 @@ static struct dvb_usb_properties vp702x_properties = { | |||
256 | 256 | ||
257 | /* usb specific object needed to register this driver with the usb subsystem */ | 257 | /* usb specific object needed to register this driver with the usb subsystem */ |
258 | static struct usb_driver vp702x_usb_driver = { | 258 | static struct usb_driver vp702x_usb_driver = { |
259 | .owner = THIS_MODULE, | ||
260 | .name = "dvb-usb-vp702x", | 259 | .name = "dvb-usb-vp702x", |
261 | .probe = vp702x_usb_probe, | 260 | .probe = vp702x_usb_probe, |
262 | .disconnect = dvb_usb_device_exit, | 261 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 75765e3a569c..3835235b68df 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c | |||
@@ -253,7 +253,6 @@ static struct dvb_usb_properties vp7045_properties = { | |||
253 | 253 | ||
254 | /* usb specific object needed to register this driver with the usb subsystem */ | 254 | /* usb specific object needed to register this driver with the usb subsystem */ |
255 | static struct usb_driver vp7045_usb_driver = { | 255 | static struct usb_driver vp7045_usb_driver = { |
256 | .owner = THIS_MODULE, | ||
257 | .name = "dvb_usb_vp7045", | 256 | .name = "dvb_usb_vp7045", |
258 | .probe = vp7045_usb_probe, | 257 | .probe = vp7045_usb_probe, |
259 | .disconnect = dvb_usb_device_exit, | 258 | .disconnect = dvb_usb_device_exit, |
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 992be0be6b1e..7dae91e5863c 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -176,6 +176,9 @@ static void init_av7110_av(struct av7110 *av7110) | |||
176 | } | 176 | } |
177 | } | 177 | } |
178 | 178 | ||
179 | if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000e) | ||
180 | av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, SpdifSwitch, 1, 0); // SPDIF on | ||
181 | |||
179 | ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); | 182 | ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); |
180 | if (ret < 0) | 183 | if (ret < 0) |
181 | printk("dvb-ttpci:cannot set volume :%d\n",ret); | 184 | printk("dvb-ttpci:cannot set volume :%d\n",ret); |
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h index fedd20f9815d..2a5e87ba1052 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.h +++ b/drivers/media/dvb/ttpci/av7110_hw.h | |||
@@ -143,7 +143,8 @@ enum av7110_audio_command { | |||
143 | MainSwitch, | 143 | MainSwitch, |
144 | ADSwitch, | 144 | ADSwitch, |
145 | SendDiSEqC, | 145 | SendDiSEqC, |
146 | SetRegister | 146 | SetRegister, |
147 | SpdifSwitch | ||
147 | }; | 148 | }; |
148 | 149 | ||
149 | enum av7110_request_command { | 150 | enum av7110_request_command { |
diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c index 9774e94d1e7d..1439cb752874 100644 --- a/drivers/media/video/cpia_usb.c +++ b/drivers/media/video/cpia_usb.c | |||
@@ -582,7 +582,6 @@ MODULE_LICENSE("GPL"); | |||
582 | 582 | ||
583 | 583 | ||
584 | static struct usb_driver cpia_driver = { | 584 | static struct usb_driver cpia_driver = { |
585 | .owner = THIS_MODULE, | ||
586 | .name = "cpia", | 585 | .name = "cpia", |
587 | .probe = cpia_probe, | 586 | .probe = cpia_probe, |
588 | .disconnect = cpia_disconnect, | 587 | .disconnect = cpia_disconnect, |
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index aea3f038cff6..5b93723a1768 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -333,24 +333,30 @@ static int set_input(struct i2c_client *client, enum cx25840_input input) | |||
333 | 333 | ||
334 | static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) | 334 | static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) |
335 | { | 335 | { |
336 | u8 fmt; | 336 | u8 fmt=0; /* zero is autodetect */ |
337 | 337 | ||
338 | switch (std) { | 338 | /* First tests should be against specific std */ |
339 | /* zero is autodetect */ | 339 | if (std & V4L2_STD_NTSC_M_JP) { |
340 | case 0: fmt = 0x0; break; | 340 | fmt=0x2; |
341 | /* default ntsc to ntsc-m */ | 341 | } else if (std & V4L2_STD_NTSC_443) { |
342 | case V4L2_STD_NTSC: | 342 | fmt=0x3; |
343 | case V4L2_STD_NTSC_M: fmt = 0x1; break; | 343 | } else if (std & V4L2_STD_PAL_M) { |
344 | case V4L2_STD_NTSC_M_JP: fmt = 0x2; break; | 344 | fmt=0x5; |
345 | case V4L2_STD_NTSC_443: fmt = 0x3; break; | 345 | } else if (std & V4L2_STD_PAL_N) { |
346 | case V4L2_STD_PAL: fmt = 0x4; break; | 346 | fmt=0x6; |
347 | case V4L2_STD_PAL_M: fmt = 0x5; break; | 347 | } else if (std & V4L2_STD_PAL_Nc) { |
348 | case V4L2_STD_PAL_N: fmt = 0x6; break; | 348 | fmt=0x7; |
349 | case V4L2_STD_PAL_Nc: fmt = 0x7; break; | 349 | } else if (std & V4L2_STD_PAL_60) { |
350 | case V4L2_STD_PAL_60: fmt = 0x8; break; | 350 | fmt=0x8; |
351 | case V4L2_STD_SECAM: fmt = 0xc; break; | 351 | } else { |
352 | default: | 352 | /* Then, test against generic ones */ |
353 | return -ERANGE; | 353 | if (std & V4L2_STD_NTSC) { |
354 | fmt=0x1; | ||
355 | } else if (std & V4L2_STD_PAL) { | ||
356 | fmt=0x4; | ||
357 | } else if (std & V4L2_STD_SECAM) { | ||
358 | fmt=0xc; | ||
359 | } | ||
354 | } | 360 | } |
355 | 361 | ||
356 | cx25840_and_or(client, 0x400, ~0xf, fmt); | 362 | cx25840_and_or(client, 0x400, ~0xf, fmt); |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index ec11619f8ea9..0cfe75416ec6 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -39,7 +39,7 @@ MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); | |||
39 | #define em28xx_coredbg(fmt, arg...) do {\ | 39 | #define em28xx_coredbg(fmt, arg...) do {\ |
40 | if (core_debug) \ | 40 | if (core_debug) \ |
41 | printk(KERN_INFO "%s %s :"fmt, \ | 41 | printk(KERN_INFO "%s %s :"fmt, \ |
42 | dev->name, __FUNCTION__, ##arg); } while (0) | 42 | dev->name, __FUNCTION__ , ##arg); } while (0) |
43 | 43 | ||
44 | static unsigned int reg_debug; | 44 | static unsigned int reg_debug; |
45 | module_param(reg_debug,int,0644); | 45 | module_param(reg_debug,int,0644); |
@@ -48,7 +48,7 @@ MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); | |||
48 | #define em28xx_regdbg(fmt, arg...) do {\ | 48 | #define em28xx_regdbg(fmt, arg...) do {\ |
49 | if (reg_debug) \ | 49 | if (reg_debug) \ |
50 | printk(KERN_INFO "%s %s :"fmt, \ | 50 | printk(KERN_INFO "%s %s :"fmt, \ |
51 | dev->name, __FUNCTION__, ##arg); } while (0) | 51 | dev->name, __FUNCTION__ , ##arg); } while (0) |
52 | 52 | ||
53 | static unsigned int isoc_debug; | 53 | static unsigned int isoc_debug; |
54 | module_param(isoc_debug,int,0644); | 54 | module_param(isoc_debug,int,0644); |
@@ -57,7 +57,7 @@ MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]"); | |||
57 | #define em28xx_isocdbg(fmt, arg...) do {\ | 57 | #define em28xx_isocdbg(fmt, arg...) do {\ |
58 | if (isoc_debug) \ | 58 | if (isoc_debug) \ |
59 | printk(KERN_INFO "%s %s :"fmt, \ | 59 | printk(KERN_INFO "%s %s :"fmt, \ |
60 | dev->name, __FUNCTION__, ##arg); } while (0) | 60 | dev->name, __FUNCTION__ , ##arg); } while (0) |
61 | 61 | ||
62 | static int alt = EM28XX_PINOUT; | 62 | static int alt = EM28XX_PINOUT; |
63 | module_param(alt, int, 0644); | 63 | module_param(alt, int, 0644); |
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index 29e21ad187cc..7f5603054f02 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c | |||
@@ -44,7 +44,7 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | |||
44 | printk(fmt, ##args); } while (0) | 44 | printk(fmt, ##args); } while (0) |
45 | #define dprintk2(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \ | 45 | #define dprintk2(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \ |
46 | printk(KERN_DEBUG "%s at %s: " fmt, \ | 46 | printk(KERN_DEBUG "%s at %s: " fmt, \ |
47 | dev->name, __FUNCTION__, ##args); } while (0) | 47 | dev->name, __FUNCTION__ , ##args); } while (0) |
48 | 48 | ||
49 | /* | 49 | /* |
50 | * em2800_i2c_send_max4() | 50 | * em2800_i2c_send_max4() |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 8ecaa0803e08..3a56120397ae 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #define em28xx_videodbg(fmt, arg...) do {\ | 45 | #define em28xx_videodbg(fmt, arg...) do {\ |
46 | if (video_debug) \ | 46 | if (video_debug) \ |
47 | printk(KERN_INFO "%s %s :"fmt, \ | 47 | printk(KERN_INFO "%s %s :"fmt, \ |
48 | dev->name, __FUNCTION__, ##arg); } while (0) | 48 | dev->name, __FUNCTION__ , ##arg); } while (0) |
49 | 49 | ||
50 | MODULE_AUTHOR(DRIVER_AUTHOR); | 50 | MODULE_AUTHOR(DRIVER_AUTHOR); |
51 | MODULE_DESCRIPTION(DRIVER_DESC); | 51 | MODULE_DESCRIPTION(DRIVER_DESC); |
@@ -1884,7 +1884,6 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) | |||
1884 | } | 1884 | } |
1885 | 1885 | ||
1886 | static struct usb_driver em28xx_usb_driver = { | 1886 | static struct usb_driver em28xx_usb_driver = { |
1887 | .owner = THIS_MODULE, | ||
1888 | .name = "em28xx", | 1887 | .name = "em28xx", |
1889 | .probe = em28xx_usb_probe, | 1888 | .probe = em28xx_usb_probe, |
1890 | .disconnect = em28xx_usb_disconnect, | 1889 | .disconnect = em28xx_usb_disconnect, |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 1e2ee43db394..5c7a41ce69f3 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -392,18 +392,18 @@ extern const unsigned int em28xx_bcount; | |||
392 | /* printk macros */ | 392 | /* printk macros */ |
393 | 393 | ||
394 | #define em28xx_err(fmt, arg...) do {\ | 394 | #define em28xx_err(fmt, arg...) do {\ |
395 | printk(KERN_ERR fmt, ##arg); } while (0) | 395 | printk(KERN_ERR fmt , ##arg); } while (0) |
396 | 396 | ||
397 | #define em28xx_errdev(fmt, arg...) do {\ | 397 | #define em28xx_errdev(fmt, arg...) do {\ |
398 | printk(KERN_ERR "%s: "fmt,\ | 398 | printk(KERN_ERR "%s: "fmt,\ |
399 | dev->name, ##arg); } while (0) | 399 | dev->name , ##arg); } while (0) |
400 | 400 | ||
401 | #define em28xx_info(fmt, arg...) do {\ | 401 | #define em28xx_info(fmt, arg...) do {\ |
402 | printk(KERN_INFO "%s: "fmt,\ | 402 | printk(KERN_INFO "%s: "fmt,\ |
403 | dev->name, ##arg); } while (0) | 403 | dev->name , ##arg); } while (0) |
404 | #define em28xx_warn(fmt, arg...) do {\ | 404 | #define em28xx_warn(fmt, arg...) do {\ |
405 | printk(KERN_WARNING "%s: "fmt,\ | 405 | printk(KERN_WARNING "%s: "fmt,\ |
406 | dev->name, ##arg); } while (0) | 406 | dev->name , ##arg); } while (0) |
407 | 407 | ||
408 | inline static int em28xx_audio_source(struct em28xx *dev, int input) | 408 | inline static int em28xx_audio_source(struct em28xx *dev, int input) |
409 | { | 409 | { |
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index 3428e1ed0032..c36f014f1fdf 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c | |||
@@ -389,7 +389,7 @@ static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_dat | |||
389 | static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data *data) | 389 | static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data *data) |
390 | { | 390 | { |
391 | struct saa7127_state *state = i2c_get_clientdata(client); | 391 | struct saa7127_state *state = i2c_get_clientdata(client); |
392 | u16 cc = data->data[0] << 8 | data->data[1]; | 392 | u16 cc = data->data[1] << 8 | data->data[0]; |
393 | int enable = (data->line != 0); | 393 | int enable = (data->line != 0); |
394 | 394 | ||
395 | if (enable && (data->field != 0 || data->line != 21)) | 395 | if (enable && (data->field != 0 || data->line != 21)) |
@@ -397,7 +397,7 @@ static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data | |||
397 | if (state->cc_enable != enable) { | 397 | if (state->cc_enable != enable) { |
398 | saa7127_dbg("Turn CC %s\n", enable ? "on" : "off"); | 398 | saa7127_dbg("Turn CC %s\n", enable ? "on" : "off"); |
399 | saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, | 399 | saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, |
400 | (enable << 6) | 0x11); | 400 | (state->xds_enable << 7) | (enable << 6) | 0x11); |
401 | state->cc_enable = enable; | 401 | state->cc_enable = enable; |
402 | } | 402 | } |
403 | if (!enable) | 403 | if (!enable) |
@@ -423,7 +423,7 @@ static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_dat | |||
423 | if (state->xds_enable != enable) { | 423 | if (state->xds_enable != enable) { |
424 | saa7127_dbg("Turn XDS %s\n", enable ? "on" : "off"); | 424 | saa7127_dbg("Turn XDS %s\n", enable ? "on" : "off"); |
425 | saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, | 425 | saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, |
426 | (enable << 7) | 0x11); | 426 | (enable << 7) | (state->cc_enable << 6) | 0x11); |
427 | state->xds_enable = enable; | 427 | state->xds_enable = enable; |
428 | } | 428 | } |
429 | if (!enable) | 429 | if (!enable) |
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig index c512c4411b38..8a5c3e71b37d 100644 --- a/drivers/media/video/saa7134/Kconfig +++ b/drivers/media/video/saa7134/Kconfig | |||
@@ -1,11 +1,10 @@ | |||
1 | config VIDEO_SAA7134 | 1 | config VIDEO_SAA7134 |
2 | tristate "Philips SAA7134 support" | 2 | tristate "Philips SAA7134 support" |
3 | depends on VIDEO_DEV && PCI && I2C && SOUND && SND | 3 | depends on VIDEO_DEV && PCI && I2C |
4 | select VIDEO_BUF | 4 | select VIDEO_BUF |
5 | select VIDEO_IR | 5 | select VIDEO_IR |
6 | select VIDEO_TUNER | 6 | select VIDEO_TUNER |
7 | select CRC32 | 7 | select CRC32 |
8 | select SND_PCM_OSS | ||
9 | ---help--- | 8 | ---help--- |
10 | This is a video4linux driver for Philips SAA713x based | 9 | This is a video4linux driver for Philips SAA713x based |
11 | TV cards. | 10 | TV cards. |
@@ -13,6 +12,29 @@ config VIDEO_SAA7134 | |||
13 | To compile this driver as a module, choose M here: the | 12 | To compile this driver as a module, choose M here: the |
14 | module will be called saa7134. | 13 | module will be called saa7134. |
15 | 14 | ||
15 | config VIDEO_SAA7134_ALSA | ||
16 | tristate "Philips SAA7134 DMA audio support" | ||
17 | depends on VIDEO_SAA7134 && SND | ||
18 | select SND_PCM_OSS | ||
19 | ---help--- | ||
20 | This is a video4linux driver for direct (DMA) audio in | ||
21 | Philips SAA713x based TV cards using ALSA | ||
22 | |||
23 | To compile this driver as a module, choose M here: the | ||
24 | module will be called saa7134-alsa. | ||
25 | |||
26 | config VIDEO_SAA7134_OSS | ||
27 | tristate "Philips SAA7134 DMA audio support (OSS, DEPRECATED)" | ||
28 | depends on VIDEO_SAA7134 && SOUND_PRIME && !VIDEO_SAA7134_ALSA | ||
29 | ---help--- | ||
30 | This is a video4linux driver for direct (DMA) audio in | ||
31 | Philips SAA713x based TV cards using OSS | ||
32 | |||
33 | This is deprecated in favor of the ALSA module | ||
34 | |||
35 | To compile this driver as a module, choose M here: the | ||
36 | module will be called saa7134-oss. | ||
37 | |||
16 | config VIDEO_SAA7134_DVB | 38 | config VIDEO_SAA7134_DVB |
17 | tristate "DVB/ATSC Support for saa7134 based TV cards" | 39 | tristate "DVB/ATSC Support for saa7134 based TV cards" |
18 | depends on VIDEO_SAA7134 && DVB_CORE | 40 | depends on VIDEO_SAA7134 && DVB_CORE |
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile index 134f83a96218..1ba998424bbd 100644 --- a/drivers/media/video/saa7134/Makefile +++ b/drivers/media/video/saa7134/Makefile | |||
@@ -4,8 +4,11 @@ saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \ | |||
4 | saa7134-video.o saa7134-input.o | 4 | saa7134-video.o saa7134-input.o |
5 | 5 | ||
6 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \ | 6 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \ |
7 | saa6752hs.o saa7134-alsa.o \ | 7 | saa6752hs.o |
8 | saa7134-oss.o | 8 | |
9 | obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o | ||
10 | obj-$(CONFIG_VIDEO_SAA7134_OSS) += saa7134-oss.o | ||
11 | |||
9 | obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o | 12 | obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o |
10 | 13 | ||
11 | EXTRA_CFLAGS += -I$(src)/.. | 14 | EXTRA_CFLAGS += -I$(src)/.. |
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index b24a26b065c2..ade05f75fdb0 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c | |||
@@ -60,7 +60,7 @@ module_param_array(index, int, NULL, 0444); | |||
60 | MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s)."); | 60 | MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s)."); |
61 | 61 | ||
62 | #define dprintk(fmt, arg...) if (debug) \ | 62 | #define dprintk(fmt, arg...) if (debug) \ |
63 | printk(KERN_DEBUG "%s/alsa: " fmt, dev->name, ## arg) | 63 | printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ##arg) |
64 | 64 | ||
65 | 65 | ||
66 | 66 | ||
@@ -989,6 +989,14 @@ static int saa7134_alsa_init(void) | |||
989 | struct saa7134_dev *dev = NULL; | 989 | struct saa7134_dev *dev = NULL; |
990 | struct list_head *list; | 990 | struct list_head *list; |
991 | 991 | ||
992 | if (!dmasound_init && !dmasound_exit) { | ||
993 | dmasound_init = alsa_device_init; | ||
994 | dmasound_exit = alsa_device_exit; | ||
995 | } else { | ||
996 | printk(KERN_WARNING "saa7134 ALSA: can't load, DMA sound handler already assigned (probably to OSS)\n"); | ||
997 | return -EBUSY; | ||
998 | } | ||
999 | |||
992 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n"); | 1000 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n"); |
993 | 1001 | ||
994 | list_for_each(list,&saa7134_devlist) { | 1002 | list_for_each(list,&saa7134_devlist) { |
@@ -1001,9 +1009,6 @@ static int saa7134_alsa_init(void) | |||
1001 | } | 1009 | } |
1002 | } | 1010 | } |
1003 | 1011 | ||
1004 | dmasound_init = alsa_device_init; | ||
1005 | dmasound_exit = alsa_device_exit; | ||
1006 | |||
1007 | if (dev == NULL) | 1012 | if (dev == NULL) |
1008 | printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n"); | 1013 | printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n"); |
1009 | 1014 | ||
@@ -1023,12 +1028,15 @@ static void saa7134_alsa_exit(void) | |||
1023 | snd_card_free(snd_saa7134_cards[idx]); | 1028 | snd_card_free(snd_saa7134_cards[idx]); |
1024 | } | 1029 | } |
1025 | 1030 | ||
1031 | dmasound_init = NULL; | ||
1032 | dmasound_exit = NULL; | ||
1026 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n"); | 1033 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n"); |
1027 | 1034 | ||
1028 | return; | 1035 | return; |
1029 | } | 1036 | } |
1030 | 1037 | ||
1031 | module_init(saa7134_alsa_init); | 1038 | /* We initialize this late, to make sure the sound system is up and running */ |
1039 | late_initcall(saa7134_alsa_init); | ||
1032 | module_exit(saa7134_alsa_exit); | 1040 | module_exit(saa7134_alsa_exit); |
1033 | MODULE_LICENSE("GPL"); | 1041 | MODULE_LICENSE("GPL"); |
1034 | MODULE_AUTHOR("Ricardo Cerqueira"); | 1042 | MODULE_AUTHOR("Ricardo Cerqueira"); |
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c index 513a699a6df2..8badd2a9cb2f 100644 --- a/drivers/media/video/saa7134/saa7134-oss.c +++ b/drivers/media/video/saa7134/saa7134-oss.c | |||
@@ -959,8 +959,17 @@ static int saa7134_oss_init(void) | |||
959 | struct saa7134_dev *dev = NULL; | 959 | struct saa7134_dev *dev = NULL; |
960 | struct list_head *list; | 960 | struct list_head *list; |
961 | 961 | ||
962 | if (!dmasound_init && !dmasound_exit) { | ||
963 | dmasound_init = oss_device_init; | ||
964 | dmasound_exit = oss_device_exit; | ||
965 | } else { | ||
966 | printk(KERN_WARNING "saa7134 OSS: can't load, DMA sound handler already assigned (probably to ALSA)\n"); | ||
967 | return -EBUSY; | ||
968 | } | ||
969 | |||
962 | printk(KERN_INFO "saa7134 OSS driver for DMA sound loaded\n"); | 970 | printk(KERN_INFO "saa7134 OSS driver for DMA sound loaded\n"); |
963 | 971 | ||
972 | |||
964 | list_for_each(list,&saa7134_devlist) { | 973 | list_for_each(list,&saa7134_devlist) { |
965 | dev = list_entry(list, struct saa7134_dev, devlist); | 974 | dev = list_entry(list, struct saa7134_dev, devlist); |
966 | if (dev->dmasound.priv_data == NULL) { | 975 | if (dev->dmasound.priv_data == NULL) { |
@@ -974,9 +983,6 @@ static int saa7134_oss_init(void) | |||
974 | if (dev == NULL) | 983 | if (dev == NULL) |
975 | printk(KERN_INFO "saa7134 OSS: no saa7134 cards found\n"); | 984 | printk(KERN_INFO "saa7134 OSS: no saa7134 cards found\n"); |
976 | 985 | ||
977 | dmasound_init = oss_device_init; | ||
978 | dmasound_exit = oss_device_exit; | ||
979 | |||
980 | return 0; | 986 | return 0; |
981 | 987 | ||
982 | } | 988 | } |
@@ -997,12 +1003,16 @@ static void saa7134_oss_exit(void) | |||
997 | 1003 | ||
998 | } | 1004 | } |
999 | 1005 | ||
1006 | dmasound_init = NULL; | ||
1007 | dmasound_exit = NULL; | ||
1008 | |||
1000 | printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n"); | 1009 | printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n"); |
1001 | 1010 | ||
1002 | return; | 1011 | return; |
1003 | } | 1012 | } |
1004 | 1013 | ||
1005 | module_init(saa7134_oss_init); | 1014 | /* We initialize this late, to make sure the sound system is up and running */ |
1015 | late_initcall(saa7134_oss_init); | ||
1006 | module_exit(saa7134_oss_exit); | 1016 | module_exit(saa7134_oss_exit); |
1007 | MODULE_LICENSE("GPL"); | 1017 | MODULE_LICENSE("GPL"); |
1008 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 1018 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index cd7cf1bd12b4..5ac235365dd8 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c | |||
@@ -206,7 +206,7 @@ hauppauge_tuner[] = | |||
206 | { TUNER_ABSENT, "TCL 2002MI_3H"}, | 206 | { TUNER_ABSENT, "TCL 2002MI_3H"}, |
207 | { TUNER_TCL_2002N, "TCL 2002N 5H"}, | 207 | { TUNER_TCL_2002N, "TCL 2002N 5H"}, |
208 | /* 100-109 */ | 208 | /* 100-109 */ |
209 | { TUNER_ABSENT, "Philips FMD1216ME"}, | 209 | { TUNER_PHILIPS_FMD1216ME_MK3, "Philips FMD1216ME"}, |
210 | { TUNER_TEA5767, "Philips TEA5768HL FM Radio"}, | 210 | { TUNER_TEA5767, "Philips TEA5768HL FM Radio"}, |
211 | { TUNER_ABSENT, "Panasonic ENV57H12D5"}, | 211 | { TUNER_ABSENT, "Panasonic ENV57H12D5"}, |
212 | { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"}, | 212 | { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"}, |
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c index 81ef306cb124..ee7075fa1ec3 100644 --- a/drivers/message/i2o/pci.c +++ b/drivers/message/i2o/pci.c | |||
@@ -303,6 +303,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, | |||
303 | struct i2o_controller *c; | 303 | struct i2o_controller *c; |
304 | int rc; | 304 | int rc; |
305 | struct pci_dev *i960 = NULL; | 305 | struct pci_dev *i960 = NULL; |
306 | int pci_dev_busy = 0; | ||
306 | 307 | ||
307 | printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n"); | 308 | printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n"); |
308 | 309 | ||
@@ -395,6 +396,8 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, | |||
395 | if ((rc = i2o_pci_alloc(c))) { | 396 | if ((rc = i2o_pci_alloc(c))) { |
396 | printk(KERN_ERR "%s: DMA / IO allocation for I2O controller " | 397 | printk(KERN_ERR "%s: DMA / IO allocation for I2O controller " |
397 | " failed\n", c->name); | 398 | " failed\n", c->name); |
399 | if (rc == -ENODEV) | ||
400 | pci_dev_busy = 1; | ||
398 | goto free_controller; | 401 | goto free_controller; |
399 | } | 402 | } |
400 | 403 | ||
@@ -425,7 +428,8 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, | |||
425 | i2o_iop_free(c); | 428 | i2o_iop_free(c); |
426 | 429 | ||
427 | disable: | 430 | disable: |
428 | pci_disable_device(pdev); | 431 | if (!pci_dev_busy) |
432 | pci_disable_device(pdev); | ||
429 | 433 | ||
430 | return rc; | 434 | return rc; |
431 | } | 435 | } |
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index d91fcf7c3178..abcf19116d70 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c | |||
@@ -359,7 +359,12 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
359 | md->block_bits = card->csd.read_blkbits; | 359 | md->block_bits = card->csd.read_blkbits; |
360 | 360 | ||
361 | blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); | 361 | blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); |
362 | set_capacity(md->disk, card->csd.capacity); | 362 | |
363 | /* | ||
364 | * The CSD capacity field is in units of read_blkbits. | ||
365 | * set_capacity takes units of 512 bytes. | ||
366 | */ | ||
367 | set_capacity(md->disk, card->csd.capacity << (card->csd.read_blkbits - 9)); | ||
363 | } | 368 | } |
364 | out: | 369 | out: |
365 | return md; | 370 | return md; |
@@ -373,7 +378,7 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) | |||
373 | 378 | ||
374 | mmc_card_claim_host(card); | 379 | mmc_card_claim_host(card); |
375 | cmd.opcode = MMC_SET_BLOCKLEN; | 380 | cmd.opcode = MMC_SET_BLOCKLEN; |
376 | cmd.arg = 1 << card->csd.read_blkbits; | 381 | cmd.arg = 1 << md->block_bits; |
377 | cmd.flags = MMC_RSP_R1; | 382 | cmd.flags = MMC_RSP_R1; |
378 | err = mmc_wait_for_cmd(card->host, &cmd, 5); | 383 | err = mmc_wait_for_cmd(card->host, &cmd, 5); |
379 | mmc_card_release_host(card); | 384 | mmc_card_release_host(card); |
@@ -412,10 +417,9 @@ static int mmc_blk_probe(struct mmc_card *card) | |||
412 | if (err) | 417 | if (err) |
413 | goto out; | 418 | goto out; |
414 | 419 | ||
415 | printk(KERN_INFO "%s: %s %s %dKiB %s\n", | 420 | printk(KERN_INFO "%s: %s %s %luKiB %s\n", |
416 | md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), | 421 | md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), |
417 | (card->csd.capacity << card->csd.read_blkbits) / 1024, | 422 | get_capacity(md->disk) >> 1, mmc_blk_readonly(card)?"(ro)":""); |
418 | mmc_blk_readonly(card)?"(ro)":""); | ||
419 | 423 | ||
420 | mmc_set_drvdata(card, md); | 424 | mmc_set_drvdata(card, md); |
421 | add_disk(md->disk); | 425 | add_disk(md->disk); |
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 452ccd5037c3..b9b77cf39a18 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
@@ -62,7 +62,7 @@ config MTD_PHYSMAP_BANKWIDTH | |||
62 | 62 | ||
63 | config MTD_SUN_UFLASH | 63 | config MTD_SUN_UFLASH |
64 | tristate "Sun Microsystems userflash support" | 64 | tristate "Sun Microsystems userflash support" |
65 | depends on (SPARC32 || SPARC64) && MTD_CFI | 65 | depends on SPARC && MTD_CFI |
66 | help | 66 | help |
67 | This provides a 'mapping' driver which supports the way in | 67 | This provides a 'mapping' driver which supports the way in |
68 | which user-programmable flash chips are connected on various | 68 | which user-programmable flash chips are connected on various |
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c index 48cce431f89f..45c077d0f063 100644 --- a/drivers/mtd/onenand/generic.c +++ b/drivers/mtd/onenand/generic.c | |||
@@ -12,9 +12,9 @@ | |||
12 | * This is a device driver for the OneNAND flash for generic boards. | 12 | * This is a device driver for the OneNAND flash for generic boards. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/device.h> | ||
16 | #include <linux/module.h> | 15 | #include <linux/module.h> |
17 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/mtd/mtd.h> | 18 | #include <linux/mtd/mtd.h> |
19 | #include <linux/mtd/onenand.h> | 19 | #include <linux/mtd/onenand.h> |
20 | #include <linux/mtd/partitions.h> | 20 | #include <linux/mtd/partitions.h> |
@@ -39,7 +39,7 @@ static int __devinit generic_onenand_probe(struct device *dev) | |||
39 | { | 39 | { |
40 | struct onenand_info *info; | 40 | struct onenand_info *info; |
41 | struct platform_device *pdev = to_platform_device(dev); | 41 | struct platform_device *pdev = to_platform_device(dev); |
42 | struct onenand_platform_data *pdata = pdev->dev.platform_data; | 42 | struct flash_platform_data *pdata = pdev->dev.platform_data; |
43 | struct resource *res = pdev->resource; | 43 | struct resource *res = pdev->resource; |
44 | unsigned long size = res->end - res->start + 1; | 44 | unsigned long size = res->end - res->start + 1; |
45 | int err; | 45 | int err; |
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index f67d5d6eb9a6..a53a73fc2a5a 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
@@ -940,7 +940,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, | |||
940 | u_char *eccbuf, struct nand_oobinfo *oobsel) | 940 | u_char *eccbuf, struct nand_oobinfo *oobsel) |
941 | { | 941 | { |
942 | struct onenand_chip *this = mtd->priv; | 942 | struct onenand_chip *this = mtd->priv; |
943 | unsigned char buffer[MAX_ONENAND_PAGESIZE], *pbuf; | 943 | unsigned char *pbuf; |
944 | size_t total_len, len; | 944 | size_t total_len, len; |
945 | int i, written = 0; | 945 | int i, written = 0; |
946 | int ret = 0; | 946 | int ret = 0; |
@@ -975,7 +975,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, | |||
975 | /* Loop until all keve's data has been written */ | 975 | /* Loop until all keve's data has been written */ |
976 | len = 0; | 976 | len = 0; |
977 | while (count) { | 977 | while (count) { |
978 | pbuf = buffer; | 978 | pbuf = this->page_buf; |
979 | /* | 979 | /* |
980 | * If the given tuple is >= pagesize then | 980 | * If the given tuple is >= pagesize then |
981 | * write it out from the iov | 981 | * write it out from the iov |
@@ -995,7 +995,7 @@ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, | |||
995 | int cnt = 0, thislen; | 995 | int cnt = 0, thislen; |
996 | while (cnt < mtd->oobblock) { | 996 | while (cnt < mtd->oobblock) { |
997 | thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len); | 997 | thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len); |
998 | memcpy(buffer + cnt, vecs->iov_base + len, thislen); | 998 | memcpy(this->page_buf + cnt, vecs->iov_base + len, thislen); |
999 | cnt += thislen; | 999 | cnt += thislen; |
1000 | len += thislen; | 1000 | len += thislen; |
1001 | 1001 | ||
@@ -1296,6 +1296,12 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1296 | 1296 | ||
1297 | /* Block lock scheme */ | 1297 | /* Block lock scheme */ |
1298 | for (block = start; block < end; block++) { | 1298 | for (block = start; block < end; block++) { |
1299 | /* Set block address */ | ||
1300 | value = onenand_block_address(this, block); | ||
1301 | this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); | ||
1302 | /* Select DataRAM for DDP */ | ||
1303 | value = onenand_bufferram_address(this, block); | ||
1304 | this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); | ||
1299 | /* Set start block address */ | 1305 | /* Set start block address */ |
1300 | this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS); | 1306 | this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS); |
1301 | /* Write unlock command */ | 1307 | /* Write unlock command */ |
@@ -1309,10 +1315,6 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1309 | & ONENAND_CTRL_ONGO) | 1315 | & ONENAND_CTRL_ONGO) |
1310 | continue; | 1316 | continue; |
1311 | 1317 | ||
1312 | /* Set block address for read block status */ | ||
1313 | value = onenand_block_address(this, block); | ||
1314 | this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); | ||
1315 | |||
1316 | /* Check lock status */ | 1318 | /* Check lock status */ |
1317 | status = this->read_word(this->base + ONENAND_REG_WP_STATUS); | 1319 | status = this->read_word(this->base + ONENAND_REG_WP_STATUS); |
1318 | if (!(status & ONENAND_WP_US)) | 1320 | if (!(status & ONENAND_WP_US)) |
@@ -1346,7 +1348,6 @@ static void onenand_print_device_info(int device) | |||
1346 | 1348 | ||
1347 | static const struct onenand_manufacturers onenand_manuf_ids[] = { | 1349 | static const struct onenand_manufacturers onenand_manuf_ids[] = { |
1348 | {ONENAND_MFR_SAMSUNG, "Samsung"}, | 1350 | {ONENAND_MFR_SAMSUNG, "Samsung"}, |
1349 | {ONENAND_MFR_UNKNOWN, "Unknown"} | ||
1350 | }; | 1351 | }; |
1351 | 1352 | ||
1352 | /** | 1353 | /** |
@@ -1357,17 +1358,22 @@ static const struct onenand_manufacturers onenand_manuf_ids[] = { | |||
1357 | */ | 1358 | */ |
1358 | static int onenand_check_maf(int manuf) | 1359 | static int onenand_check_maf(int manuf) |
1359 | { | 1360 | { |
1361 | int size = ARRAY_SIZE(onenand_manuf_ids); | ||
1362 | char *name; | ||
1360 | int i; | 1363 | int i; |
1361 | 1364 | ||
1362 | for (i = 0; onenand_manuf_ids[i].id; i++) { | 1365 | for (i = 0; i < size; i++) |
1363 | if (manuf == onenand_manuf_ids[i].id) | 1366 | if (manuf == onenand_manuf_ids[i].id) |
1364 | break; | 1367 | break; |
1365 | } | ||
1366 | 1368 | ||
1367 | printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", | 1369 | if (i < size) |
1368 | onenand_manuf_ids[i].name, manuf); | 1370 | name = onenand_manuf_ids[i].name; |
1371 | else | ||
1372 | name = "Unknown"; | ||
1373 | |||
1374 | printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", name, manuf); | ||
1369 | 1375 | ||
1370 | return (i != ONENAND_MFR_UNKNOWN); | 1376 | return (i == size); |
1371 | } | 1377 | } |
1372 | 1378 | ||
1373 | /** | 1379 | /** |
@@ -1513,6 +1519,18 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) | |||
1513 | this->read_bufferram = onenand_sync_read_bufferram; | 1519 | this->read_bufferram = onenand_sync_read_bufferram; |
1514 | } | 1520 | } |
1515 | 1521 | ||
1522 | /* Allocate buffers, if necessary */ | ||
1523 | if (!this->page_buf) { | ||
1524 | size_t len; | ||
1525 | len = mtd->oobblock + mtd->oobsize; | ||
1526 | this->page_buf = kmalloc(len, GFP_KERNEL); | ||
1527 | if (!this->page_buf) { | ||
1528 | printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n"); | ||
1529 | return -ENOMEM; | ||
1530 | } | ||
1531 | this->options |= ONENAND_PAGEBUF_ALLOC; | ||
1532 | } | ||
1533 | |||
1516 | this->state = FL_READY; | 1534 | this->state = FL_READY; |
1517 | init_waitqueue_head(&this->wq); | 1535 | init_waitqueue_head(&this->wq); |
1518 | spin_lock_init(&this->chip_lock); | 1536 | spin_lock_init(&this->chip_lock); |
@@ -1574,12 +1592,21 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) | |||
1574 | */ | 1592 | */ |
1575 | void onenand_release(struct mtd_info *mtd) | 1593 | void onenand_release(struct mtd_info *mtd) |
1576 | { | 1594 | { |
1595 | struct onenand_chip *this = mtd->priv; | ||
1596 | |||
1577 | #ifdef CONFIG_MTD_PARTITIONS | 1597 | #ifdef CONFIG_MTD_PARTITIONS |
1578 | /* Deregister partitions */ | 1598 | /* Deregister partitions */ |
1579 | del_mtd_partitions (mtd); | 1599 | del_mtd_partitions (mtd); |
1580 | #endif | 1600 | #endif |
1581 | /* Deregister the device */ | 1601 | /* Deregister the device */ |
1582 | del_mtd_device (mtd); | 1602 | del_mtd_device (mtd); |
1603 | |||
1604 | /* Free bad block table memory, if allocated */ | ||
1605 | if (this->bbm) | ||
1606 | kfree(this->bbm); | ||
1607 | /* Buffer allocated by onenand_scan */ | ||
1608 | if (this->options & ONENAND_PAGEBUF_ALLOC) | ||
1609 | kfree(this->page_buf); | ||
1583 | } | 1610 | } |
1584 | 1611 | ||
1585 | EXPORT_SYMBOL_GPL(onenand_scan); | 1612 | EXPORT_SYMBOL_GPL(onenand_scan); |
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c index f40190f499e1..4510d3361eaa 100644 --- a/drivers/mtd/onenand/onenand_bbt.c +++ b/drivers/mtd/onenand/onenand_bbt.c | |||
@@ -118,10 +118,10 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr | |||
118 | */ | 118 | */ |
119 | static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) | 119 | static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) |
120 | { | 120 | { |
121 | unsigned char data_buf[MAX_ONENAND_PAGESIZE]; | 121 | struct onenand_chip *this = mtd->priv; |
122 | 122 | ||
123 | bd->options &= ~NAND_BBT_SCANEMPTY; | 123 | bd->options &= ~NAND_BBT_SCANEMPTY; |
124 | return create_bbt(mtd, data_buf, bd, -1); | 124 | return create_bbt(mtd, this->page_buf, bd, -1); |
125 | } | 125 | } |
126 | 126 | ||
127 | /** | 127 | /** |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 525624fc03b4..c39344adecce 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * trademarks of NVIDIA Corporation in the United States and other | 10 | * trademarks of NVIDIA Corporation in the United States and other |
11 | * countries. | 11 | * countries. |
12 | * | 12 | * |
13 | * Copyright (C) 2003,4 Manfred Spraul | 13 | * Copyright (C) 2003,4,5 Manfred Spraul |
14 | * Copyright (C) 2004 Andrew de Quincey (wol support) | 14 | * Copyright (C) 2004 Andrew de Quincey (wol support) |
15 | * Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane | 15 | * Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane |
16 | * IRQ rate fixes, bigendian fixes, cleanups, verification) | 16 | * IRQ rate fixes, bigendian fixes, cleanups, verification) |
@@ -100,6 +100,7 @@ | |||
100 | * 0.45: 18 Sep 2005: Remove nv_stop/start_rx from every link check | 100 | * 0.45: 18 Sep 2005: Remove nv_stop/start_rx from every link check |
101 | * 0.46: 20 Oct 2005: Add irq optimization modes. | 101 | * 0.46: 20 Oct 2005: Add irq optimization modes. |
102 | * 0.47: 26 Oct 2005: Add phyaddr 0 in phy scan. | 102 | * 0.47: 26 Oct 2005: Add phyaddr 0 in phy scan. |
103 | * 0.48: 24 Dec 2005: Disable TSO, bugfix for pci_map_single | ||
103 | * | 104 | * |
104 | * Known bugs: | 105 | * Known bugs: |
105 | * We suspect that on some hardware no TX done interrupts are generated. | 106 | * We suspect that on some hardware no TX done interrupts are generated. |
@@ -111,7 +112,7 @@ | |||
111 | * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few | 112 | * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few |
112 | * superfluous timer interrupts from the nic. | 113 | * superfluous timer interrupts from the nic. |
113 | */ | 114 | */ |
114 | #define FORCEDETH_VERSION "0.47" | 115 | #define FORCEDETH_VERSION "0.48" |
115 | #define DRV_NAME "forcedeth" | 116 | #define DRV_NAME "forcedeth" |
116 | 117 | ||
117 | #include <linux/module.h> | 118 | #include <linux/module.h> |
@@ -871,8 +872,8 @@ static int nv_alloc_rx(struct net_device *dev) | |||
871 | } else { | 872 | } else { |
872 | skb = np->rx_skbuff[nr]; | 873 | skb = np->rx_skbuff[nr]; |
873 | } | 874 | } |
874 | np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len, | 875 | np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, |
875 | PCI_DMA_FROMDEVICE); | 876 | skb->end-skb->data, PCI_DMA_FROMDEVICE); |
876 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { | 877 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { |
877 | np->rx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]); | 878 | np->rx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]); |
878 | wmb(); | 879 | wmb(); |
@@ -999,7 +1000,7 @@ static void nv_drain_rx(struct net_device *dev) | |||
999 | wmb(); | 1000 | wmb(); |
1000 | if (np->rx_skbuff[i]) { | 1001 | if (np->rx_skbuff[i]) { |
1001 | pci_unmap_single(np->pci_dev, np->rx_dma[i], | 1002 | pci_unmap_single(np->pci_dev, np->rx_dma[i], |
1002 | np->rx_skbuff[i]->len, | 1003 | np->rx_skbuff[i]->end-np->rx_skbuff[i]->data, |
1003 | PCI_DMA_FROMDEVICE); | 1004 | PCI_DMA_FROMDEVICE); |
1004 | dev_kfree_skb(np->rx_skbuff[i]); | 1005 | dev_kfree_skb(np->rx_skbuff[i]); |
1005 | np->rx_skbuff[i] = NULL; | 1006 | np->rx_skbuff[i] = NULL; |
@@ -1334,7 +1335,7 @@ static void nv_rx_process(struct net_device *dev) | |||
1334 | * the performance. | 1335 | * the performance. |
1335 | */ | 1336 | */ |
1336 | pci_unmap_single(np->pci_dev, np->rx_dma[i], | 1337 | pci_unmap_single(np->pci_dev, np->rx_dma[i], |
1337 | np->rx_skbuff[i]->len, | 1338 | np->rx_skbuff[i]->end-np->rx_skbuff[i]->data, |
1338 | PCI_DMA_FROMDEVICE); | 1339 | PCI_DMA_FROMDEVICE); |
1339 | 1340 | ||
1340 | { | 1341 | { |
@@ -2455,7 +2456,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
2455 | np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; | 2456 | np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; |
2456 | dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG; | 2457 | dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG; |
2457 | #ifdef NETIF_F_TSO | 2458 | #ifdef NETIF_F_TSO |
2458 | dev->features |= NETIF_F_TSO; | 2459 | /* disabled dev->features |= NETIF_F_TSO; */ |
2459 | #endif | 2460 | #endif |
2460 | } | 2461 | } |
2461 | 2462 | ||
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index c22c0517883c..fa176ffb4ad5 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c | |||
@@ -1539,7 +1539,6 @@ static void irda_usb_disconnect(struct usb_interface *intf) | |||
1539 | * USB device callbacks | 1539 | * USB device callbacks |
1540 | */ | 1540 | */ |
1541 | static struct usb_driver irda_driver = { | 1541 | static struct usb_driver irda_driver = { |
1542 | .owner = THIS_MODULE, | ||
1543 | .name = "irda-usb", | 1542 | .name = "irda-usb", |
1544 | .probe = irda_usb_probe, | 1543 | .probe = irda_usb_probe, |
1545 | .disconnect = irda_usb_disconnect, | 1544 | .disconnect = irda_usb_disconnect, |
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index 3961a754e920..31867e4b891b 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c | |||
@@ -1152,7 +1152,6 @@ static int stir_resume(struct usb_interface *intf) | |||
1152 | * USB device callbacks | 1152 | * USB device callbacks |
1153 | */ | 1153 | */ |
1154 | static struct usb_driver irda_driver = { | 1154 | static struct usb_driver irda_driver = { |
1155 | .owner = THIS_MODULE, | ||
1156 | .name = "stir4200", | 1155 | .name = "stir4200", |
1157 | .probe = stir_probe, | 1156 | .probe = stir_probe, |
1158 | .disconnect = stir_disconnect, | 1157 | .disconnect = stir_disconnect, |
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index f857ae94d261..b0c3b6ab6263 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c | |||
@@ -115,6 +115,7 @@ | |||
115 | #include <linux/ethtool.h> | 115 | #include <linux/ethtool.h> |
116 | #include <linux/timer.h> | 116 | #include <linux/timer.h> |
117 | #include <linux/if_vlan.h> | 117 | #include <linux/if_vlan.h> |
118 | #include <linux/rtnetlink.h> | ||
118 | 119 | ||
119 | #include <asm/io.h> | 120 | #include <asm/io.h> |
120 | #include <asm/uaccess.h> | 121 | #include <asm/uaccess.h> |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 16bebe7a7ce1..7da0e3dd5fe3 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -38,6 +38,10 @@ | |||
38 | #include <asm/irq.h> | 38 | #include <asm/irq.h> |
39 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
40 | 40 | ||
41 | MODULE_DESCRIPTION("PHY library"); | ||
42 | MODULE_AUTHOR("Andy Fleming"); | ||
43 | MODULE_LICENSE("GPL"); | ||
44 | |||
41 | static struct phy_driver genphy_driver; | 45 | static struct phy_driver genphy_driver; |
42 | extern int mdio_bus_init(void); | 46 | extern int mdio_bus_init(void); |
43 | extern void mdio_bus_exit(void); | 47 | extern void mdio_bus_exit(void); |
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 50430f79f8cf..1c6d328165bb 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -524,9 +524,6 @@ static int get_filter(void __user *arg, struct sock_filter **p) | |||
524 | if (copy_from_user(&uprog, arg, sizeof(uprog))) | 524 | if (copy_from_user(&uprog, arg, sizeof(uprog))) |
525 | return -EFAULT; | 525 | return -EFAULT; |
526 | 526 | ||
527 | if (uprog.len > BPF_MAXINSNS) | ||
528 | return -EINVAL; | ||
529 | |||
530 | if (!uprog.len) { | 527 | if (!uprog.len) { |
531 | *p = NULL; | 528 | *p = NULL; |
532 | return 0; | 529 | return 0; |
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index a842ecc60a34..9369f811075d 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c | |||
@@ -85,7 +85,7 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
85 | static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb); | 85 | static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb); |
86 | static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb); | 86 | static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb); |
87 | 87 | ||
88 | static struct proto_ops pppoe_ops; | 88 | static const struct proto_ops pppoe_ops; |
89 | static DEFINE_RWLOCK(pppoe_hash_lock); | 89 | static DEFINE_RWLOCK(pppoe_hash_lock); |
90 | 90 | ||
91 | static struct ppp_channel_ops pppoe_chan_ops; | 91 | static struct ppp_channel_ops pppoe_chan_ops; |
@@ -383,8 +383,6 @@ static int pppoe_rcv(struct sk_buff *skb, | |||
383 | { | 383 | { |
384 | struct pppoe_hdr *ph; | 384 | struct pppoe_hdr *ph; |
385 | struct pppox_sock *po; | 385 | struct pppox_sock *po; |
386 | struct sock *sk; | ||
387 | int ret; | ||
388 | 386 | ||
389 | if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) | 387 | if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) |
390 | goto drop; | 388 | goto drop; |
@@ -395,24 +393,8 @@ static int pppoe_rcv(struct sk_buff *skb, | |||
395 | ph = (struct pppoe_hdr *) skb->nh.raw; | 393 | ph = (struct pppoe_hdr *) skb->nh.raw; |
396 | 394 | ||
397 | po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source); | 395 | po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source); |
398 | if (!po) | 396 | if (po != NULL) |
399 | goto drop; | 397 | return sk_receive_skb(sk_pppox(po), skb); |
400 | |||
401 | sk = sk_pppox(po); | ||
402 | bh_lock_sock(sk); | ||
403 | |||
404 | /* Socket state is unknown, must put skb into backlog. */ | ||
405 | if (sock_owned_by_user(sk) != 0) { | ||
406 | sk_add_backlog(sk, skb); | ||
407 | ret = NET_RX_SUCCESS; | ||
408 | } else { | ||
409 | ret = pppoe_rcv_core(sk, skb); | ||
410 | } | ||
411 | |||
412 | bh_unlock_sock(sk); | ||
413 | sock_put(sk); | ||
414 | |||
415 | return ret; | ||
416 | drop: | 398 | drop: |
417 | kfree_skb(skb); | 399 | kfree_skb(skb); |
418 | out: | 400 | out: |
@@ -1081,9 +1063,7 @@ static int __init pppoe_proc_init(void) | |||
1081 | static inline int pppoe_proc_init(void) { return 0; } | 1063 | static inline int pppoe_proc_init(void) { return 0; } |
1082 | #endif /* CONFIG_PROC_FS */ | 1064 | #endif /* CONFIG_PROC_FS */ |
1083 | 1065 | ||
1084 | /* ->ioctl are set at pppox_create */ | 1066 | static const struct proto_ops pppoe_ops = { |
1085 | |||
1086 | static struct proto_ops pppoe_ops = { | ||
1087 | .family = AF_PPPOX, | 1067 | .family = AF_PPPOX, |
1088 | .owner = THIS_MODULE, | 1068 | .owner = THIS_MODULE, |
1089 | .release = pppoe_release, | 1069 | .release = pppoe_release, |
@@ -1099,7 +1079,8 @@ static struct proto_ops pppoe_ops = { | |||
1099 | .getsockopt = sock_no_getsockopt, | 1079 | .getsockopt = sock_no_getsockopt, |
1100 | .sendmsg = pppoe_sendmsg, | 1080 | .sendmsg = pppoe_sendmsg, |
1101 | .recvmsg = pppoe_recvmsg, | 1081 | .recvmsg = pppoe_recvmsg, |
1102 | .mmap = sock_no_mmap | 1082 | .mmap = sock_no_mmap, |
1083 | .ioctl = pppox_ioctl, | ||
1103 | }; | 1084 | }; |
1104 | 1085 | ||
1105 | static struct pppox_proto pppoe_proto = { | 1086 | static struct pppox_proto pppoe_proto = { |
diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c index 0c1e114527fb..9315046b3f55 100644 --- a/drivers/net/pppox.c +++ b/drivers/net/pppox.c | |||
@@ -68,8 +68,7 @@ EXPORT_SYMBOL(register_pppox_proto); | |||
68 | EXPORT_SYMBOL(unregister_pppox_proto); | 68 | EXPORT_SYMBOL(unregister_pppox_proto); |
69 | EXPORT_SYMBOL(pppox_unbind_sock); | 69 | EXPORT_SYMBOL(pppox_unbind_sock); |
70 | 70 | ||
71 | static int pppox_ioctl(struct socket* sock, unsigned int cmd, | 71 | int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
72 | unsigned long arg) | ||
73 | { | 72 | { |
74 | struct sock *sk = sock->sk; | 73 | struct sock *sk = sock->sk; |
75 | struct pppox_sock *po = pppox_sk(sk); | 74 | struct pppox_sock *po = pppox_sk(sk); |
@@ -105,6 +104,7 @@ static int pppox_ioctl(struct socket* sock, unsigned int cmd, | |||
105 | return rc; | 104 | return rc; |
106 | } | 105 | } |
107 | 106 | ||
107 | EXPORT_SYMBOL(pppox_ioctl); | ||
108 | 108 | ||
109 | static int pppox_create(struct socket *sock, int protocol) | 109 | static int pppox_create(struct socket *sock, int protocol) |
110 | { | 110 | { |
@@ -119,11 +119,7 @@ static int pppox_create(struct socket *sock, int protocol) | |||
119 | goto out; | 119 | goto out; |
120 | 120 | ||
121 | rc = pppox_protos[protocol]->create(sock); | 121 | rc = pppox_protos[protocol]->create(sock); |
122 | if (!rc) { | 122 | |
123 | /* We get to set the ioctl handler. */ | ||
124 | /* For everything else, pppox is just a shell. */ | ||
125 | sock->ops->ioctl = pppox_ioctl; | ||
126 | } | ||
127 | module_put(pppox_protos[protocol]->owner); | 123 | module_put(pppox_protos[protocol]->owner); |
128 | out: | 124 | out: |
129 | return rc; | 125 | return rc; |
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c index ae7343934758..e1a2d52cc1fe 100644 --- a/drivers/net/sk98lin/skge.c +++ b/drivers/net/sk98lin/skge.c | |||
@@ -107,6 +107,7 @@ | |||
107 | 107 | ||
108 | #include "h/skversion.h" | 108 | #include "h/skversion.h" |
109 | 109 | ||
110 | #include <linux/in.h> | ||
110 | #include <linux/module.h> | 111 | #include <linux/module.h> |
111 | #include <linux/moduleparam.h> | 112 | #include <linux/moduleparam.h> |
112 | #include <linux/init.h> | 113 | #include <linux/init.h> |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 00d683063c01..d8cc3aea032a 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -25,6 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/config.h> | 27 | #include <linux/config.h> |
28 | #include <linux/in.h> | ||
28 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
30 | #include <linux/moduleparam.h> | 31 | #include <linux/moduleparam.h> |
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 081717d01374..28ce47a02408 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c | |||
@@ -2907,7 +2907,7 @@ static int __devinit gem_get_device_address(struct gem *gp) | |||
2907 | return 0; | 2907 | return 0; |
2908 | } | 2908 | } |
2909 | 2909 | ||
2910 | static void __devexit gem_remove_one(struct pci_dev *pdev) | 2910 | static void gem_remove_one(struct pci_dev *pdev) |
2911 | { | 2911 | { |
2912 | struct net_device *dev = pci_get_drvdata(pdev); | 2912 | struct net_device *dev = pci_get_drvdata(pdev); |
2913 | 2913 | ||
@@ -3181,7 +3181,7 @@ static struct pci_driver gem_driver = { | |||
3181 | .name = GEM_MODULE_NAME, | 3181 | .name = GEM_MODULE_NAME, |
3182 | .id_table = gem_pci_tbl, | 3182 | .id_table = gem_pci_tbl, |
3183 | .probe = gem_init_one, | 3183 | .probe = gem_init_one, |
3184 | .remove = __devexit_p(gem_remove_one), | 3184 | .remove = gem_remove_one, |
3185 | #ifdef CONFIG_PM | 3185 | #ifdef CONFIG_PM |
3186 | .suspend = gem_suspend, | 3186 | .suspend = gem_suspend, |
3187 | .resume = gem_resume, | 3187 | .resume = gem_resume, |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index a23ed28a72b8..eb86b059809b 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/compiler.h> | 24 | #include <linux/compiler.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/in.h> | ||
27 | #include <linux/init.h> | 28 | #include <linux/init.h> |
28 | #include <linux/ioport.h> | 29 | #include <linux/ioport.h> |
29 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
@@ -68,8 +69,8 @@ | |||
68 | 69 | ||
69 | #define DRV_MODULE_NAME "tg3" | 70 | #define DRV_MODULE_NAME "tg3" |
70 | #define PFX DRV_MODULE_NAME ": " | 71 | #define PFX DRV_MODULE_NAME ": " |
71 | #define DRV_MODULE_VERSION "3.45" | 72 | #define DRV_MODULE_VERSION "3.47" |
72 | #define DRV_MODULE_RELDATE "Dec 13, 2005" | 73 | #define DRV_MODULE_RELDATE "Dec 28, 2005" |
73 | 74 | ||
74 | #define TG3_DEF_MAC_MODE 0 | 75 | #define TG3_DEF_MAC_MODE 0 |
75 | #define TG3_DEF_RX_MODE 0 | 76 | #define TG3_DEF_RX_MODE 0 |
@@ -341,6 +342,16 @@ static struct { | |||
341 | { "interrupt test (offline)" }, | 342 | { "interrupt test (offline)" }, |
342 | }; | 343 | }; |
343 | 344 | ||
345 | static void tg3_write32(struct tg3 *tp, u32 off, u32 val) | ||
346 | { | ||
347 | writel(val, tp->regs + off); | ||
348 | } | ||
349 | |||
350 | static u32 tg3_read32(struct tg3 *tp, u32 off) | ||
351 | { | ||
352 | return (readl(tp->regs + off)); | ||
353 | } | ||
354 | |||
344 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) | 355 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) |
345 | { | 356 | { |
346 | unsigned long flags; | 357 | unsigned long flags; |
@@ -411,13 +422,29 @@ static u32 tg3_read_indirect_mbox(struct tg3 *tp, u32 off) | |||
411 | return val; | 422 | return val; |
412 | } | 423 | } |
413 | 424 | ||
414 | static void _tw32_flush(struct tg3 *tp, u32 off, u32 val) | 425 | /* usec_wait specifies the wait time in usec when writing to certain registers |
426 | * where it is unsafe to read back the register without some delay. | ||
427 | * GRC_LOCAL_CTRL is one example if the GPIOs are toggled to switch power. | ||
428 | * TG3PCI_CLOCK_CTRL is another example if the clock frequencies are changed. | ||
429 | */ | ||
430 | static void _tw32_flush(struct tg3 *tp, u32 off, u32 val, u32 usec_wait) | ||
415 | { | 431 | { |
416 | tp->write32(tp, off, val); | 432 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) || |
417 | if (!(tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) && | 433 | (tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND)) |
418 | !(tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) && | 434 | /* Non-posted methods */ |
419 | !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND)) | 435 | tp->write32(tp, off, val); |
420 | tp->read32(tp, off); /* flush */ | 436 | else { |
437 | /* Posted method */ | ||
438 | tg3_write32(tp, off, val); | ||
439 | if (usec_wait) | ||
440 | udelay(usec_wait); | ||
441 | tp->read32(tp, off); | ||
442 | } | ||
443 | /* Wait again after the read for the posted method to guarantee that | ||
444 | * the wait time is met. | ||
445 | */ | ||
446 | if (usec_wait) | ||
447 | udelay(usec_wait); | ||
421 | } | 448 | } |
422 | 449 | ||
423 | static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val) | 450 | static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val) |
@@ -438,16 +465,6 @@ static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val) | |||
438 | readl(mbox); | 465 | readl(mbox); |
439 | } | 466 | } |
440 | 467 | ||
441 | static void tg3_write32(struct tg3 *tp, u32 off, u32 val) | ||
442 | { | ||
443 | writel(val, tp->regs + off); | ||
444 | } | ||
445 | |||
446 | static u32 tg3_read32(struct tg3 *tp, u32 off) | ||
447 | { | ||
448 | return (readl(tp->regs + off)); | ||
449 | } | ||
450 | |||
451 | #define tw32_mailbox(reg, val) tp->write32_mbox(tp, reg, val) | 468 | #define tw32_mailbox(reg, val) tp->write32_mbox(tp, reg, val) |
452 | #define tw32_mailbox_f(reg, val) tw32_mailbox_flush(tp, (reg), (val)) | 469 | #define tw32_mailbox_f(reg, val) tw32_mailbox_flush(tp, (reg), (val)) |
453 | #define tw32_rx_mbox(reg, val) tp->write32_rx_mbox(tp, reg, val) | 470 | #define tw32_rx_mbox(reg, val) tp->write32_rx_mbox(tp, reg, val) |
@@ -455,7 +472,8 @@ static u32 tg3_read32(struct tg3 *tp, u32 off) | |||
455 | #define tr32_mailbox(reg) tp->read32_mbox(tp, reg) | 472 | #define tr32_mailbox(reg) tp->read32_mbox(tp, reg) |
456 | 473 | ||
457 | #define tw32(reg,val) tp->write32(tp, reg, val) | 474 | #define tw32(reg,val) tp->write32(tp, reg, val) |
458 | #define tw32_f(reg,val) _tw32_flush(tp,(reg),(val)) | 475 | #define tw32_f(reg,val) _tw32_flush(tp,(reg),(val), 0) |
476 | #define tw32_wait_f(reg,val,us) _tw32_flush(tp,(reg),(val), (us)) | ||
459 | #define tr32(reg) tp->read32(tp, reg) | 477 | #define tr32(reg) tp->read32(tp, reg) |
460 | 478 | ||
461 | static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) | 479 | static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) |
@@ -595,21 +613,19 @@ static void tg3_switch_clocks(struct tg3 *tp) | |||
595 | 613 | ||
596 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { | 614 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { |
597 | if (orig_clock_ctrl & CLOCK_CTRL_625_CORE) { | 615 | if (orig_clock_ctrl & CLOCK_CTRL_625_CORE) { |
598 | tw32_f(TG3PCI_CLOCK_CTRL, | 616 | tw32_wait_f(TG3PCI_CLOCK_CTRL, |
599 | clock_ctrl | CLOCK_CTRL_625_CORE); | 617 | clock_ctrl | CLOCK_CTRL_625_CORE, 40); |
600 | udelay(40); | ||
601 | } | 618 | } |
602 | } else if ((orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE) != 0) { | 619 | } else if ((orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE) != 0) { |
603 | tw32_f(TG3PCI_CLOCK_CTRL, | 620 | tw32_wait_f(TG3PCI_CLOCK_CTRL, |
604 | clock_ctrl | | 621 | clock_ctrl | |
605 | (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK)); | 622 | (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK), |
606 | udelay(40); | 623 | 40); |
607 | tw32_f(TG3PCI_CLOCK_CTRL, | 624 | tw32_wait_f(TG3PCI_CLOCK_CTRL, |
608 | clock_ctrl | (CLOCK_CTRL_ALTCLK)); | 625 | clock_ctrl | (CLOCK_CTRL_ALTCLK), |
609 | udelay(40); | 626 | 40); |
610 | } | 627 | } |
611 | tw32_f(TG3PCI_CLOCK_CTRL, clock_ctrl); | 628 | tw32_wait_f(TG3PCI_CLOCK_CTRL, clock_ctrl, 40); |
612 | udelay(40); | ||
613 | } | 629 | } |
614 | 630 | ||
615 | #define PHY_BUSY_LOOPS 5000 | 631 | #define PHY_BUSY_LOOPS 5000 |
@@ -1017,39 +1033,50 @@ static void tg3_frob_aux_power(struct tg3 *tp) | |||
1017 | if ((tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) != 0) | 1033 | if ((tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) != 0) |
1018 | return; | 1034 | return; |
1019 | 1035 | ||
1020 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { | 1036 | if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || |
1021 | tp_peer = pci_get_drvdata(tp->pdev_peer); | 1037 | (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) { |
1022 | if (!tp_peer) | 1038 | struct net_device *dev_peer; |
1039 | |||
1040 | dev_peer = pci_get_drvdata(tp->pdev_peer); | ||
1041 | if (!dev_peer) | ||
1023 | BUG(); | 1042 | BUG(); |
1043 | tp_peer = netdev_priv(dev_peer); | ||
1024 | } | 1044 | } |
1025 | 1045 | ||
1026 | |||
1027 | if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 || | 1046 | if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 || |
1028 | (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0 || | 1047 | (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0 || |
1029 | (tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 || | 1048 | (tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 || |
1030 | (tp_peer->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) { | 1049 | (tp_peer->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) { |
1031 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || | 1050 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || |
1032 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { | 1051 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { |
1033 | tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | | 1052 | tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | |
1034 | (GRC_LCLCTRL_GPIO_OE0 | | 1053 | (GRC_LCLCTRL_GPIO_OE0 | |
1035 | GRC_LCLCTRL_GPIO_OE1 | | 1054 | GRC_LCLCTRL_GPIO_OE1 | |
1036 | GRC_LCLCTRL_GPIO_OE2 | | 1055 | GRC_LCLCTRL_GPIO_OE2 | |
1037 | GRC_LCLCTRL_GPIO_OUTPUT0 | | 1056 | GRC_LCLCTRL_GPIO_OUTPUT0 | |
1038 | GRC_LCLCTRL_GPIO_OUTPUT1)); | 1057 | GRC_LCLCTRL_GPIO_OUTPUT1), |
1039 | udelay(100); | 1058 | 100); |
1040 | } else { | 1059 | } else { |
1041 | u32 no_gpio2; | 1060 | u32 no_gpio2; |
1042 | u32 grc_local_ctrl; | 1061 | u32 grc_local_ctrl = 0; |
1043 | 1062 | ||
1044 | if (tp_peer != tp && | 1063 | if (tp_peer != tp && |
1045 | (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0) | 1064 | (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0) |
1046 | return; | 1065 | return; |
1047 | 1066 | ||
1067 | /* Workaround to prevent overdrawing Amps. */ | ||
1068 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == | ||
1069 | ASIC_REV_5714) { | ||
1070 | grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3; | ||
1071 | tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | | ||
1072 | grc_local_ctrl, 100); | ||
1073 | } | ||
1074 | |||
1048 | /* On 5753 and variants, GPIO2 cannot be used. */ | 1075 | /* On 5753 and variants, GPIO2 cannot be used. */ |
1049 | no_gpio2 = tp->nic_sram_data_cfg & | 1076 | no_gpio2 = tp->nic_sram_data_cfg & |
1050 | NIC_SRAM_DATA_CFG_NO_GPIO2; | 1077 | NIC_SRAM_DATA_CFG_NO_GPIO2; |
1051 | 1078 | ||
1052 | grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 | | 1079 | grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE0 | |
1053 | GRC_LCLCTRL_GPIO_OE1 | | 1080 | GRC_LCLCTRL_GPIO_OE1 | |
1054 | GRC_LCLCTRL_GPIO_OE2 | | 1081 | GRC_LCLCTRL_GPIO_OE2 | |
1055 | GRC_LCLCTRL_GPIO_OUTPUT1 | | 1082 | GRC_LCLCTRL_GPIO_OUTPUT1 | |
@@ -1058,21 +1085,18 @@ static void tg3_frob_aux_power(struct tg3 *tp) | |||
1058 | grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 | | 1085 | grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 | |
1059 | GRC_LCLCTRL_GPIO_OUTPUT2); | 1086 | GRC_LCLCTRL_GPIO_OUTPUT2); |
1060 | } | 1087 | } |
1061 | tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | | 1088 | tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | |
1062 | grc_local_ctrl); | 1089 | grc_local_ctrl, 100); |
1063 | udelay(100); | ||
1064 | 1090 | ||
1065 | grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0; | 1091 | grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0; |
1066 | 1092 | ||
1067 | tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | | 1093 | tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | |
1068 | grc_local_ctrl); | 1094 | grc_local_ctrl, 100); |
1069 | udelay(100); | ||
1070 | 1095 | ||
1071 | if (!no_gpio2) { | 1096 | if (!no_gpio2) { |
1072 | grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2; | 1097 | grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2; |
1073 | tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | | 1098 | tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | |
1074 | grc_local_ctrl); | 1099 | grc_local_ctrl, 100); |
1075 | udelay(100); | ||
1076 | } | 1100 | } |
1077 | } | 1101 | } |
1078 | } else { | 1102 | } else { |
@@ -1082,19 +1106,16 @@ static void tg3_frob_aux_power(struct tg3 *tp) | |||
1082 | (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0) | 1106 | (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0) |
1083 | return; | 1107 | return; |
1084 | 1108 | ||
1085 | tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | | 1109 | tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | |
1086 | (GRC_LCLCTRL_GPIO_OE1 | | 1110 | (GRC_LCLCTRL_GPIO_OE1 | |
1087 | GRC_LCLCTRL_GPIO_OUTPUT1)); | 1111 | GRC_LCLCTRL_GPIO_OUTPUT1), 100); |
1088 | udelay(100); | ||
1089 | 1112 | ||
1090 | tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | | 1113 | tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | |
1091 | (GRC_LCLCTRL_GPIO_OE1)); | 1114 | GRC_LCLCTRL_GPIO_OE1, 100); |
1092 | udelay(100); | ||
1093 | 1115 | ||
1094 | tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | | 1116 | tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | |
1095 | (GRC_LCLCTRL_GPIO_OE1 | | 1117 | (GRC_LCLCTRL_GPIO_OE1 | |
1096 | GRC_LCLCTRL_GPIO_OUTPUT1)); | 1118 | GRC_LCLCTRL_GPIO_OUTPUT1), 100); |
1097 | udelay(100); | ||
1098 | } | 1119 | } |
1099 | } | 1120 | } |
1100 | } | 1121 | } |
@@ -1137,10 +1158,8 @@ static int tg3_set_power_state(struct tg3 *tp, int state) | |||
1137 | udelay(100); /* Delay after power state change */ | 1158 | udelay(100); /* Delay after power state change */ |
1138 | 1159 | ||
1139 | /* Switch out of Vaux if it is not a LOM */ | 1160 | /* Switch out of Vaux if it is not a LOM */ |
1140 | if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT)) { | 1161 | if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT)) |
1141 | tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); | 1162 | tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100); |
1142 | udelay(100); | ||
1143 | } | ||
1144 | 1163 | ||
1145 | return 0; | 1164 | return 0; |
1146 | 1165 | ||
@@ -1239,10 +1258,8 @@ static int tg3_set_power_state(struct tg3 *tp, int state) | |||
1239 | base_val |= (CLOCK_CTRL_RXCLK_DISABLE | | 1258 | base_val |= (CLOCK_CTRL_RXCLK_DISABLE | |
1240 | CLOCK_CTRL_TXCLK_DISABLE); | 1259 | CLOCK_CTRL_TXCLK_DISABLE); |
1241 | 1260 | ||
1242 | tw32_f(TG3PCI_CLOCK_CTRL, base_val | | 1261 | tw32_wait_f(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK | |
1243 | CLOCK_CTRL_ALTCLK | | 1262 | CLOCK_CTRL_PWRDOWN_PLL133, 40); |
1244 | CLOCK_CTRL_PWRDOWN_PLL133); | ||
1245 | udelay(40); | ||
1246 | } else if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { | 1263 | } else if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { |
1247 | /* do nothing */ | 1264 | /* do nothing */ |
1248 | } else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && | 1265 | } else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && |
@@ -1263,11 +1280,11 @@ static int tg3_set_power_state(struct tg3 *tp, int state) | |||
1263 | newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE; | 1280 | newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE; |
1264 | } | 1281 | } |
1265 | 1282 | ||
1266 | tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits1); | 1283 | tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits1, |
1267 | udelay(40); | 1284 | 40); |
1268 | 1285 | ||
1269 | tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2); | 1286 | tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2, |
1270 | udelay(40); | 1287 | 40); |
1271 | 1288 | ||
1272 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { | 1289 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { |
1273 | u32 newbits3; | 1290 | u32 newbits3; |
@@ -1281,9 +1298,8 @@ static int tg3_set_power_state(struct tg3 *tp, int state) | |||
1281 | newbits3 = CLOCK_CTRL_44MHZ_CORE; | 1298 | newbits3 = CLOCK_CTRL_44MHZ_CORE; |
1282 | } | 1299 | } |
1283 | 1300 | ||
1284 | tw32_f(TG3PCI_CLOCK_CTRL, | 1301 | tw32_wait_f(TG3PCI_CLOCK_CTRL, |
1285 | tp->pci_clock_ctrl | newbits3); | 1302 | tp->pci_clock_ctrl | newbits3, 40); |
1286 | udelay(40); | ||
1287 | } | 1303 | } |
1288 | } | 1304 | } |
1289 | 1305 | ||
@@ -1294,7 +1310,8 @@ static int tg3_set_power_state(struct tg3 *tp, int state) | |||
1294 | tg3_writephy(tp, MII_TG3_EXT_CTRL, | 1310 | tg3_writephy(tp, MII_TG3_EXT_CTRL, |
1295 | MII_TG3_EXT_CTRL_FORCE_LED_OFF); | 1311 | MII_TG3_EXT_CTRL_FORCE_LED_OFF); |
1296 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); | 1312 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); |
1297 | tg3_writephy(tp, MII_BMCR, BMCR_PDOWN); | 1313 | if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) |
1314 | tg3_writephy(tp, MII_BMCR, BMCR_PDOWN); | ||
1298 | } | 1315 | } |
1299 | } | 1316 | } |
1300 | 1317 | ||
@@ -3634,7 +3651,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3634 | TXD_FLAG_CPU_POST_DMA); | 3651 | TXD_FLAG_CPU_POST_DMA); |
3635 | 3652 | ||
3636 | skb->nh.iph->check = 0; | 3653 | skb->nh.iph->check = 0; |
3637 | skb->nh.iph->tot_len = ntohs(mss + ip_tcp_len + tcp_opt_len); | 3654 | skb->nh.iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len); |
3638 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { | 3655 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { |
3639 | skb->h.th->check = 0; | 3656 | skb->h.th->check = 0; |
3640 | base_flags &= ~TXD_FLAG_TCPUDP_CSUM; | 3657 | base_flags &= ~TXD_FLAG_TCPUDP_CSUM; |
@@ -7135,8 +7152,13 @@ do { p = (u32 *)(orig_p + (reg)); \ | |||
7135 | GET_REG32_LOOP(BUFMGR_MODE, 0x58); | 7152 | GET_REG32_LOOP(BUFMGR_MODE, 0x58); |
7136 | GET_REG32_LOOP(RDMAC_MODE, 0x08); | 7153 | GET_REG32_LOOP(RDMAC_MODE, 0x08); |
7137 | GET_REG32_LOOP(WDMAC_MODE, 0x08); | 7154 | GET_REG32_LOOP(WDMAC_MODE, 0x08); |
7138 | GET_REG32_LOOP(RX_CPU_BASE, 0x280); | 7155 | GET_REG32_1(RX_CPU_MODE); |
7139 | GET_REG32_LOOP(TX_CPU_BASE, 0x280); | 7156 | GET_REG32_1(RX_CPU_STATE); |
7157 | GET_REG32_1(RX_CPU_PGMCTR); | ||
7158 | GET_REG32_1(RX_CPU_HWBKPT); | ||
7159 | GET_REG32_1(TX_CPU_MODE); | ||
7160 | GET_REG32_1(TX_CPU_STATE); | ||
7161 | GET_REG32_1(TX_CPU_PGMCTR); | ||
7140 | GET_REG32_LOOP(GRCMBOX_INTERRUPT_0, 0x110); | 7162 | GET_REG32_LOOP(GRCMBOX_INTERRUPT_0, 0x110); |
7141 | GET_REG32_LOOP(FTQ_RESET, 0x120); | 7163 | GET_REG32_LOOP(FTQ_RESET, 0x120); |
7142 | GET_REG32_LOOP(MSGINT_MODE, 0x0c); | 7164 | GET_REG32_LOOP(MSGINT_MODE, 0x0c); |
@@ -7959,13 +7981,12 @@ static int tg3_test_memory(struct tg3 *tp) | |||
7959 | u32 offset; | 7981 | u32 offset; |
7960 | u32 len; | 7982 | u32 len; |
7961 | } mem_tbl_570x[] = { | 7983 | } mem_tbl_570x[] = { |
7962 | { 0x00000000, 0x01000}, | 7984 | { 0x00000000, 0x00b50}, |
7963 | { 0x00002000, 0x1c000}, | 7985 | { 0x00002000, 0x1c000}, |
7964 | { 0xffffffff, 0x00000} | 7986 | { 0xffffffff, 0x00000} |
7965 | }, mem_tbl_5705[] = { | 7987 | }, mem_tbl_5705[] = { |
7966 | { 0x00000100, 0x0000c}, | 7988 | { 0x00000100, 0x0000c}, |
7967 | { 0x00000200, 0x00008}, | 7989 | { 0x00000200, 0x00008}, |
7968 | { 0x00000b50, 0x00400}, | ||
7969 | { 0x00004000, 0x00800}, | 7990 | { 0x00004000, 0x00800}, |
7970 | { 0x00006000, 0x01000}, | 7991 | { 0x00006000, 0x01000}, |
7971 | { 0x00008000, 0x02000}, | 7992 | { 0x00008000, 0x02000}, |
@@ -10466,7 +10487,7 @@ static char * __devinit tg3_bus_string(struct tg3 *tp, char *str) | |||
10466 | return str; | 10487 | return str; |
10467 | } | 10488 | } |
10468 | 10489 | ||
10469 | static struct pci_dev * __devinit tg3_find_5704_peer(struct tg3 *tp) | 10490 | static struct pci_dev * __devinit tg3_find_peer(struct tg3 *tp) |
10470 | { | 10491 | { |
10471 | struct pci_dev *peer; | 10492 | struct pci_dev *peer; |
10472 | unsigned int func, devnr = tp->pdev->devfn & ~7; | 10493 | unsigned int func, devnr = tp->pdev->devfn & ~7; |
@@ -10719,8 +10740,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10719 | tp->rx_pending = 63; | 10740 | tp->rx_pending = 63; |
10720 | } | 10741 | } |
10721 | 10742 | ||
10722 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) | 10743 | if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || |
10723 | tp->pdev_peer = tg3_find_5704_peer(tp); | 10744 | (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) |
10745 | tp->pdev_peer = tg3_find_peer(tp); | ||
10724 | 10746 | ||
10725 | err = tg3_get_device_address(tp); | 10747 | err = tg3_get_device_address(tp); |
10726 | if (err) { | 10748 | if (err) { |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 94dbcf3537ec..890e1635996b 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
@@ -1124,7 +1124,14 @@ | |||
1124 | /* 0x280 --> 0x400 unused */ | 1124 | /* 0x280 --> 0x400 unused */ |
1125 | 1125 | ||
1126 | #define RX_CPU_BASE 0x00005000 | 1126 | #define RX_CPU_BASE 0x00005000 |
1127 | #define RX_CPU_MODE 0x00005000 | ||
1128 | #define RX_CPU_STATE 0x00005004 | ||
1129 | #define RX_CPU_PGMCTR 0x0000501c | ||
1130 | #define RX_CPU_HWBKPT 0x00005034 | ||
1127 | #define TX_CPU_BASE 0x00005400 | 1131 | #define TX_CPU_BASE 0x00005400 |
1132 | #define TX_CPU_MODE 0x00005400 | ||
1133 | #define TX_CPU_STATE 0x00005404 | ||
1134 | #define TX_CPU_PGMCTR 0x0000541c | ||
1128 | 1135 | ||
1129 | /* Mailboxes */ | 1136 | /* Mailboxes */ |
1130 | #define GRCMBOX_INTERRUPT_0 0x00005800 /* 64-bit */ | 1137 | #define GRCMBOX_INTERRUPT_0 0x00005800 /* 64-bit */ |
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 5e7c7e944c9d..64f6d1f25753 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -7456,8 +7456,7 @@ static void ipw_handle_data_packet(struct ipw_priv *priv, | |||
7456 | /* HW decrypt will not clear the WEP bit, MIC, PN, etc. */ | 7456 | /* HW decrypt will not clear the WEP bit, MIC, PN, etc. */ |
7457 | hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data; | 7457 | hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data; |
7458 | if (priv->ieee->iw_mode != IW_MODE_MONITOR && | 7458 | if (priv->ieee->iw_mode != IW_MODE_MONITOR && |
7459 | ((is_multicast_ether_addr(hdr->addr1) || | 7459 | (is_multicast_ether_addr(hdr->addr1) ? |
7460 | is_broadcast_ether_addr(hdr->addr1)) ? | ||
7461 | !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt)) | 7460 | !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt)) |
7462 | ipw_rebuild_decrypted_skb(priv, rxb->skb); | 7461 | ipw_rebuild_decrypted_skb(priv, rxb->skb); |
7463 | 7462 | ||
@@ -7648,8 +7647,7 @@ static inline int is_network_packet(struct ipw_priv *priv, | |||
7648 | return 0; | 7647 | return 0; |
7649 | 7648 | ||
7650 | /* {broad,multi}cast packets to our BSSID go through */ | 7649 | /* {broad,multi}cast packets to our BSSID go through */ |
7651 | if (is_multicast_ether_addr(header->addr1) || | 7650 | if (is_multicast_ether_addr(header->addr1)) |
7652 | is_broadcast_ether_addr(header->addr1)) | ||
7653 | return !memcmp(header->addr3, priv->bssid, ETH_ALEN); | 7651 | return !memcmp(header->addr3, priv->bssid, ETH_ALEN); |
7654 | 7652 | ||
7655 | /* packets to our adapter go through */ | 7653 | /* packets to our adapter go through */ |
@@ -7662,8 +7660,7 @@ static inline int is_network_packet(struct ipw_priv *priv, | |||
7662 | return 0; | 7660 | return 0; |
7663 | 7661 | ||
7664 | /* {broad,multi}cast packets to our BSS go through */ | 7662 | /* {broad,multi}cast packets to our BSS go through */ |
7665 | if (is_multicast_ether_addr(header->addr1) || | 7663 | if (is_multicast_ether_addr(header->addr1)) |
7666 | is_broadcast_ether_addr(header->addr1)) | ||
7667 | return !memcmp(header->addr2, priv->bssid, ETH_ALEN); | 7664 | return !memcmp(header->addr2, priv->bssid, ETH_ALEN); |
7668 | 7665 | ||
7669 | /* packets to our adapter go through */ | 7666 | /* packets to our adapter go through */ |
@@ -9657,8 +9654,7 @@ static inline int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | |||
9657 | switch (priv->ieee->iw_mode) { | 9654 | switch (priv->ieee->iw_mode) { |
9658 | case IW_MODE_ADHOC: | 9655 | case IW_MODE_ADHOC: |
9659 | hdr_len = IEEE80211_3ADDR_LEN; | 9656 | hdr_len = IEEE80211_3ADDR_LEN; |
9660 | unicast = !(is_multicast_ether_addr(hdr->addr1) || | 9657 | unicast = !is_multicast_ether_addr(hdr->addr1); |
9661 | is_broadcast_ether_addr(hdr->addr1)); | ||
9662 | id = ipw_find_station(priv, hdr->addr1); | 9658 | id = ipw_find_station(priv, hdr->addr1); |
9663 | if (id == IPW_INVALID_STATION) { | 9659 | if (id == IPW_INVALID_STATION) { |
9664 | id = ipw_add_station(priv, hdr->addr1); | 9660 | id = ipw_add_station(priv, hdr->addr1); |
@@ -9673,8 +9669,7 @@ static inline int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | |||
9673 | 9669 | ||
9674 | case IW_MODE_INFRA: | 9670 | case IW_MODE_INFRA: |
9675 | default: | 9671 | default: |
9676 | unicast = !(is_multicast_ether_addr(hdr->addr3) || | 9672 | unicast = !is_multicast_ether_addr(hdr->addr3); |
9677 | is_broadcast_ether_addr(hdr->addr3)); | ||
9678 | hdr_len = IEEE80211_3ADDR_LEN; | 9673 | hdr_len = IEEE80211_3ADDR_LEN; |
9679 | id = 0; | 9674 | id = 0; |
9680 | break; | 9675 | break; |
diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c index d8afd51ff8a5..d1a670b35338 100644 --- a/drivers/net/wireless/orinoco_nortel.c +++ b/drivers/net/wireless/orinoco_nortel.c | |||
@@ -1,6 +1,8 @@ | |||
1 | /* orinoco_nortel.c | 1 | /* orinoco_nortel.c |
2 | * | 2 | * |
3 | * Driver for Prism II devices which would usually be driven by orinoco_cs, | 3 | * Driver for Prism II devices which would usually be driven by orinoco_cs, |
4 | * but are connected to the PCI bus by a PCI-to-PCMCIA adapter used in | ||
5 | * Nortel emobility, Symbol LA-4113 and Symbol LA-4123. | ||
4 | * but are connected to the PCI bus by a Nortel PCI-PCMCIA-Adapter. | 6 | * but are connected to the PCI bus by a Nortel PCI-PCMCIA-Adapter. |
5 | * | 7 | * |
6 | * Copyright (C) 2002 Tobias Hoffmann | 8 | * Copyright (C) 2002 Tobias Hoffmann |
@@ -165,7 +167,7 @@ static int nortel_pci_init_one(struct pci_dev *pdev, | |||
165 | goto fail_resources; | 167 | goto fail_resources; |
166 | } | 168 | } |
167 | 169 | ||
168 | iomem = pci_iomap(pdev, 3, 0); | 170 | iomem = pci_iomap(pdev, 2, 0); |
169 | if (!iomem) { | 171 | if (!iomem) { |
170 | err = -ENOMEM; | 172 | err = -ENOMEM; |
171 | goto fail_map_io; | 173 | goto fail_map_io; |
@@ -265,6 +267,8 @@ static void __devexit nortel_pci_remove_one(struct pci_dev *pdev) | |||
265 | static struct pci_device_id nortel_pci_id_table[] = { | 267 | static struct pci_device_id nortel_pci_id_table[] = { |
266 | /* Nortel emobility PCI */ | 268 | /* Nortel emobility PCI */ |
267 | {0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,}, | 269 | {0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,}, |
270 | /* Symbol LA-4123 PCI */ | ||
271 | {0x1562, 0x0001, PCI_ANY_ID, PCI_ANY_ID,}, | ||
268 | {0,}, | 272 | {0,}, |
269 | }; | 273 | }; |
270 | 274 | ||
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 716df015f8d0..6707df968934 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -6,6 +6,9 @@ obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \ | |||
6 | pci-driver.o search.o pci-sysfs.o rom.o setup-res.o | 6 | pci-driver.o search.o pci-sysfs.o rom.o setup-res.o |
7 | obj-$(CONFIG_PROC_FS) += proc.o | 7 | obj-$(CONFIG_PROC_FS) += proc.o |
8 | 8 | ||
9 | # Build PCI Express stuff if needed | ||
10 | obj-$(CONFIG_PCIEPORTBUS) += pcie/ | ||
11 | |||
9 | obj-$(CONFIG_HOTPLUG) += hotplug.o | 12 | obj-$(CONFIG_HOTPLUG) += hotplug.o |
10 | 13 | ||
11 | # Build the PCI Hotplug drivers if we were asked to | 14 | # Build the PCI Hotplug drivers if we were asked to |
@@ -40,7 +43,3 @@ endif | |||
40 | ifeq ($(CONFIG_PCI_DEBUG),y) | 43 | ifeq ($(CONFIG_PCI_DEBUG),y) |
41 | EXTRA_CFLAGS += -DDEBUG | 44 | EXTRA_CFLAGS += -DDEBUG |
42 | endif | 45 | endif |
43 | |||
44 | # Build PCI Express stuff if needed | ||
45 | obj-$(CONFIG_PCIEPORTBUS) += pcie/ | ||
46 | |||
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c index 011915d5e243..f94f1f25eec6 100644 --- a/drivers/s390/net/qeth_eddp.c +++ b/drivers/s390/net/qeth_eddp.c | |||
@@ -62,7 +62,8 @@ qeth_eddp_free_context(struct qeth_eddp_context *ctx) | |||
62 | for (i = 0; i < ctx->num_pages; ++i) | 62 | for (i = 0; i < ctx->num_pages; ++i) |
63 | free_page((unsigned long)ctx->pages[i]); | 63 | free_page((unsigned long)ctx->pages[i]); |
64 | kfree(ctx->pages); | 64 | kfree(ctx->pages); |
65 | kfree(ctx->elements); | 65 | if (ctx->elements != NULL) |
66 | kfree(ctx->elements); | ||
66 | kfree(ctx); | 67 | kfree(ctx); |
67 | } | 68 | } |
68 | 69 | ||
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 99cceb242ec4..f8f55cc468ba 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * | 2 | * |
3 | * linux/drivers/s390/net/qeth_main.c ($Revision: 1.242 $) | 3 | * linux/drivers/s390/net/qeth_main.c ($Revision: 1.251 $) |
4 | * | 4 | * |
5 | * Linux on zSeries OSA Express and HiperSockets support | 5 | * Linux on zSeries OSA Express and HiperSockets support |
6 | * | 6 | * |
@@ -12,7 +12,7 @@ | |||
12 | * Frank Pavlic (fpavlic@de.ibm.com) and | 12 | * Frank Pavlic (fpavlic@de.ibm.com) and |
13 | * Thomas Spatzier <tspat@de.ibm.com> | 13 | * Thomas Spatzier <tspat@de.ibm.com> |
14 | * | 14 | * |
15 | * $Revision: 1.242 $ $Date: 2005/05/04 20:19:18 $ | 15 | * $Revision: 1.251 $ $Date: 2005/05/04 20:19:18 $ |
16 | * | 16 | * |
17 | * This program is free software; you can redistribute it and/or modify | 17 | * This program is free software; you can redistribute it and/or modify |
18 | * it under the terms of the GNU General Public License as published by | 18 | * it under the terms of the GNU General Public License as published by |
@@ -72,7 +72,7 @@ | |||
72 | #include "qeth_eddp.h" | 72 | #include "qeth_eddp.h" |
73 | #include "qeth_tso.h" | 73 | #include "qeth_tso.h" |
74 | 74 | ||
75 | #define VERSION_QETH_C "$Revision: 1.242 $" | 75 | #define VERSION_QETH_C "$Revision: 1.251 $" |
76 | static const char *version = "qeth S/390 OSA-Express driver"; | 76 | static const char *version = "qeth S/390 OSA-Express driver"; |
77 | 77 | ||
78 | /** | 78 | /** |
@@ -518,7 +518,8 @@ __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode) | |||
518 | 518 | ||
519 | QETH_DBF_TEXT(setup, 3, "setoffl"); | 519 | QETH_DBF_TEXT(setup, 3, "setoffl"); |
520 | QETH_DBF_HEX(setup, 3, &card, sizeof(void *)); | 520 | QETH_DBF_HEX(setup, 3, &card, sizeof(void *)); |
521 | 521 | ||
522 | netif_carrier_off(card->dev); | ||
522 | recover_flag = card->state; | 523 | recover_flag = card->state; |
523 | if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){ | 524 | if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){ |
524 | PRINT_WARN("Stopping card %s interrupted by user!\n", | 525 | PRINT_WARN("Stopping card %s interrupted by user!\n", |
@@ -1020,7 +1021,6 @@ void | |||
1020 | qeth_schedule_recovery(struct qeth_card *card) | 1021 | qeth_schedule_recovery(struct qeth_card *card) |
1021 | { | 1022 | { |
1022 | QETH_DBF_TEXT(trace,2,"startrec"); | 1023 | QETH_DBF_TEXT(trace,2,"startrec"); |
1023 | |||
1024 | if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0) | 1024 | if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0) |
1025 | schedule_work(&card->kernel_thread_starter); | 1025 | schedule_work(&card->kernel_thread_starter); |
1026 | } | 1026 | } |
@@ -1710,7 +1710,6 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) | |||
1710 | "IP address reset.\n", | 1710 | "IP address reset.\n", |
1711 | QETH_CARD_IFNAME(card), | 1711 | QETH_CARD_IFNAME(card), |
1712 | card->info.chpid); | 1712 | card->info.chpid); |
1713 | netif_carrier_on(card->dev); | ||
1714 | qeth_schedule_recovery(card); | 1713 | qeth_schedule_recovery(card); |
1715 | return NULL; | 1714 | return NULL; |
1716 | case IPA_CMD_MODCCID: | 1715 | case IPA_CMD_MODCCID: |
@@ -1959,7 +1958,7 @@ qeth_osn_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, | |||
1959 | { | 1958 | { |
1960 | u16 s1, s2; | 1959 | u16 s1, s2; |
1961 | 1960 | ||
1962 | QETH_DBF_TEXT(trace,4,"osndipa"); | 1961 | QETH_DBF_TEXT(trace,4,"osndipa"); |
1963 | 1962 | ||
1964 | qeth_prepare_ipa_cmd(card, iob, QETH_PROT_OSN2); | 1963 | qeth_prepare_ipa_cmd(card, iob, QETH_PROT_OSN2); |
1965 | s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len); | 1964 | s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len); |
@@ -2203,24 +2202,21 @@ qeth_ulp_setup(struct qeth_card *card) | |||
2203 | } | 2202 | } |
2204 | 2203 | ||
2205 | static inline int | 2204 | static inline int |
2206 | qeth_check_for_inbound_error(struct qeth_qdio_buffer *buf, | 2205 | qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error, |
2207 | unsigned int qdio_error, | 2206 | unsigned int siga_error, const char *dbftext) |
2208 | unsigned int siga_error) | ||
2209 | { | 2207 | { |
2210 | int rc = 0; | ||
2211 | |||
2212 | if (qdio_error || siga_error) { | 2208 | if (qdio_error || siga_error) { |
2213 | QETH_DBF_TEXT(trace, 2, "qdinerr"); | 2209 | QETH_DBF_TEXT(trace, 2, dbftext); |
2214 | QETH_DBF_TEXT(qerr, 2, "qdinerr"); | 2210 | QETH_DBF_TEXT(qerr, 2, dbftext); |
2215 | QETH_DBF_TEXT_(qerr, 2, " F15=%02X", | 2211 | QETH_DBF_TEXT_(qerr, 2, " F15=%02X", |
2216 | buf->buffer->element[15].flags & 0xff); | 2212 | buf->element[15].flags & 0xff); |
2217 | QETH_DBF_TEXT_(qerr, 2, " F14=%02X", | 2213 | QETH_DBF_TEXT_(qerr, 2, " F14=%02X", |
2218 | buf->buffer->element[14].flags & 0xff); | 2214 | buf->element[14].flags & 0xff); |
2219 | QETH_DBF_TEXT_(qerr, 2, " qerr=%X", qdio_error); | 2215 | QETH_DBF_TEXT_(qerr, 2, " qerr=%X", qdio_error); |
2220 | QETH_DBF_TEXT_(qerr, 2, " serr=%X", siga_error); | 2216 | QETH_DBF_TEXT_(qerr, 2, " serr=%X", siga_error); |
2221 | rc = 1; | 2217 | return 1; |
2222 | } | 2218 | } |
2223 | return rc; | 2219 | return 0; |
2224 | } | 2220 | } |
2225 | 2221 | ||
2226 | static inline struct sk_buff * | 2222 | static inline struct sk_buff * |
@@ -2769,8 +2765,9 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status, | |||
2769 | for (i = first_element; i < (first_element + count); ++i) { | 2765 | for (i = first_element; i < (first_element + count); ++i) { |
2770 | index = i % QDIO_MAX_BUFFERS_PER_Q; | 2766 | index = i % QDIO_MAX_BUFFERS_PER_Q; |
2771 | buffer = &card->qdio.in_q->bufs[index]; | 2767 | buffer = &card->qdio.in_q->bufs[index]; |
2772 | if (!((status == QDIO_STATUS_LOOK_FOR_ERROR) && | 2768 | if (!((status & QDIO_STATUS_LOOK_FOR_ERROR) && |
2773 | qeth_check_for_inbound_error(buffer, qdio_err, siga_err))) | 2769 | qeth_check_qdio_errors(buffer->buffer, |
2770 | qdio_err, siga_err,"qinerr"))) | ||
2774 | qeth_process_inbound_buffer(card, buffer, index); | 2771 | qeth_process_inbound_buffer(card, buffer, index); |
2775 | /* clear buffer and give back to hardware */ | 2772 | /* clear buffer and give back to hardware */ |
2776 | qeth_put_buffer_pool_entry(card, buffer->pool_entry); | 2773 | qeth_put_buffer_pool_entry(card, buffer->pool_entry); |
@@ -2785,12 +2782,13 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status, | |||
2785 | static inline int | 2782 | static inline int |
2786 | qeth_handle_send_error(struct qeth_card *card, | 2783 | qeth_handle_send_error(struct qeth_card *card, |
2787 | struct qeth_qdio_out_buffer *buffer, | 2784 | struct qeth_qdio_out_buffer *buffer, |
2788 | int qdio_err, int siga_err) | 2785 | unsigned int qdio_err, unsigned int siga_err) |
2789 | { | 2786 | { |
2790 | int sbalf15 = buffer->buffer->element[15].flags & 0xff; | 2787 | int sbalf15 = buffer->buffer->element[15].flags & 0xff; |
2791 | int cc = siga_err & 3; | 2788 | int cc = siga_err & 3; |
2792 | 2789 | ||
2793 | QETH_DBF_TEXT(trace, 6, "hdsnderr"); | 2790 | QETH_DBF_TEXT(trace, 6, "hdsnderr"); |
2791 | qeth_check_qdio_errors(buffer->buffer, qdio_err, siga_err, "qouterr"); | ||
2794 | switch (cc) { | 2792 | switch (cc) { |
2795 | case 0: | 2793 | case 0: |
2796 | if (qdio_err){ | 2794 | if (qdio_err){ |
@@ -3047,7 +3045,8 @@ qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status, | |||
3047 | for(i = first_element; i < (first_element + count); ++i){ | 3045 | for(i = first_element; i < (first_element + count); ++i){ |
3048 | buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]; | 3046 | buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]; |
3049 | /*we only handle the KICK_IT error by doing a recovery */ | 3047 | /*we only handle the KICK_IT error by doing a recovery */ |
3050 | if (qeth_handle_send_error(card, buffer, qdio_error, siga_error) | 3048 | if (qeth_handle_send_error(card, buffer, |
3049 | qdio_error, siga_error) | ||
3051 | == QETH_SEND_ERROR_KICK_IT){ | 3050 | == QETH_SEND_ERROR_KICK_IT){ |
3052 | netif_stop_queue(card->dev); | 3051 | netif_stop_queue(card->dev); |
3053 | qeth_schedule_recovery(card); | 3052 | qeth_schedule_recovery(card); |
@@ -3289,7 +3288,6 @@ qeth_init_qdio_info(struct qeth_card *card) | |||
3289 | card->qdio.in_buf_pool.buf_count = card->qdio.init_pool.buf_count; | 3288 | card->qdio.in_buf_pool.buf_count = card->qdio.init_pool.buf_count; |
3290 | INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list); | 3289 | INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list); |
3291 | INIT_LIST_HEAD(&card->qdio.init_pool.entry_list); | 3290 | INIT_LIST_HEAD(&card->qdio.init_pool.entry_list); |
3292 | /* outbound */ | ||
3293 | } | 3291 | } |
3294 | 3292 | ||
3295 | static int | 3293 | static int |
@@ -3731,6 +3729,9 @@ qeth_verify_vlan_dev(struct net_device *dev, struct qeth_card *card) | |||
3731 | break; | 3729 | break; |
3732 | } | 3730 | } |
3733 | } | 3731 | } |
3732 | if (rc && !(VLAN_DEV_INFO(dev)->real_dev->priv == (void *)card)) | ||
3733 | return 0; | ||
3734 | |||
3734 | #endif | 3735 | #endif |
3735 | return rc; | 3736 | return rc; |
3736 | } | 3737 | } |
@@ -3807,10 +3808,8 @@ qeth_open(struct net_device *dev) | |||
3807 | card->data.state = CH_STATE_UP; | 3808 | card->data.state = CH_STATE_UP; |
3808 | card->state = CARD_STATE_UP; | 3809 | card->state = CARD_STATE_UP; |
3809 | 3810 | ||
3810 | if (!card->lan_online){ | 3811 | if (!card->lan_online && netif_carrier_ok(dev)) |
3811 | if (netif_carrier_ok(dev)) | 3812 | netif_carrier_off(dev); |
3812 | netif_carrier_off(dev); | ||
3813 | } | ||
3814 | return 0; | 3813 | return 0; |
3815 | } | 3814 | } |
3816 | 3815 | ||
@@ -5870,10 +5869,8 @@ qeth_add_multicast_ipv6(struct qeth_card *card) | |||
5870 | struct inet6_dev *in6_dev; | 5869 | struct inet6_dev *in6_dev; |
5871 | 5870 | ||
5872 | QETH_DBF_TEXT(trace,4,"chkmcv6"); | 5871 | QETH_DBF_TEXT(trace,4,"chkmcv6"); |
5873 | if ((card->options.layer2 == 0) && | 5872 | if (!qeth_is_supported(card, IPA_IPV6)) |
5874 | (!qeth_is_supported(card, IPA_IPV6)) ) | ||
5875 | return ; | 5873 | return ; |
5876 | |||
5877 | in6_dev = in6_dev_get(card->dev); | 5874 | in6_dev = in6_dev_get(card->dev); |
5878 | if (in6_dev == NULL) | 5875 | if (in6_dev == NULL) |
5879 | return; | 5876 | return; |
@@ -7936,8 +7933,8 @@ __qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
7936 | QETH_DBF_TEXT_(setup, 2, "6err%d", rc); | 7933 | QETH_DBF_TEXT_(setup, 2, "6err%d", rc); |
7937 | goto out_remove; | 7934 | goto out_remove; |
7938 | } | 7935 | } |
7939 | /*maybe it was set offline without ifconfig down | 7936 | netif_carrier_on(card->dev); |
7940 | * we can also use this state for recovery purposes*/ | 7937 | |
7941 | qeth_set_allowed_threads(card, 0xffffffff, 0); | 7938 | qeth_set_allowed_threads(card, 0xffffffff, 0); |
7942 | if (recover_flag == CARD_STATE_RECOVER) | 7939 | if (recover_flag == CARD_STATE_RECOVER) |
7943 | qeth_start_again(card, recovery_mode); | 7940 | qeth_start_again(card, recovery_mode); |
diff --git a/drivers/s390/net/qeth_mpc.c b/drivers/s390/net/qeth_mpc.c index f0a080a9e515..5f8754addc14 100644 --- a/drivers/s390/net/qeth_mpc.c +++ b/drivers/s390/net/qeth_mpc.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #include <asm/cio.h> | 11 | #include <asm/cio.h> |
12 | #include "qeth_mpc.h" | 12 | #include "qeth_mpc.h" |
13 | 13 | ||
14 | const char *VERSION_QETH_MPC_C = "$Revision: 1.12 $"; | 14 | const char *VERSION_QETH_MPC_C = "$Revision: 1.13 $"; |
15 | 15 | ||
16 | unsigned char IDX_ACTIVATE_READ[]={ | 16 | unsigned char IDX_ACTIVATE_READ[]={ |
17 | 0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00, | 17 | 0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00, |
diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_mpc.h index 5f71486e708c..864cec5f6c62 100644 --- a/drivers/s390/net/qeth_mpc.h +++ b/drivers/s390/net/qeth_mpc.h | |||
@@ -14,14 +14,14 @@ | |||
14 | 14 | ||
15 | #include <asm/qeth.h> | 15 | #include <asm/qeth.h> |
16 | 16 | ||
17 | #define VERSION_QETH_MPC_H "$Revision: 1.44 $" | 17 | #define VERSION_QETH_MPC_H "$Revision: 1.46 $" |
18 | 18 | ||
19 | extern const char *VERSION_QETH_MPC_C; | 19 | extern const char *VERSION_QETH_MPC_C; |
20 | 20 | ||
21 | #define IPA_PDU_HEADER_SIZE 0x40 | 21 | #define IPA_PDU_HEADER_SIZE 0x40 |
22 | #define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer+0x0e) | 22 | #define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer+0x0e) |
23 | #define QETH_IPA_PDU_LEN_PDU1(buffer) (buffer+0x26) | 23 | #define QETH_IPA_PDU_LEN_PDU1(buffer) (buffer+0x26) |
24 | #define QETH_IPA_PDU_LEN_PDU2(buffer) (buffer+0x2a) | 24 | #define QETH_IPA_PDU_LEN_PDU2(buffer) (buffer+0x29) |
25 | #define QETH_IPA_PDU_LEN_PDU3(buffer) (buffer+0x3a) | 25 | #define QETH_IPA_PDU_LEN_PDU3(buffer) (buffer+0x3a) |
26 | 26 | ||
27 | extern unsigned char IPA_PDU_HEADER[]; | 27 | extern unsigned char IPA_PDU_HEADER[]; |
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c index f2ccfea8fdb8..7bf35098831e 100644 --- a/drivers/s390/net/qeth_proc.c +++ b/drivers/s390/net/qeth_proc.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * | 2 | * |
3 | * linux/drivers/s390/net/qeth_fs.c ($Revision: 1.13 $) | 3 | * linux/drivers/s390/net/qeth_fs.c ($Revision: 1.16 $) |
4 | * | 4 | * |
5 | * Linux on zSeries OSA Express and HiperSockets support | 5 | * Linux on zSeries OSA Express and HiperSockets support |
6 | * This file contains code related to procfs. | 6 | * This file contains code related to procfs. |
@@ -21,7 +21,7 @@ | |||
21 | #include "qeth_mpc.h" | 21 | #include "qeth_mpc.h" |
22 | #include "qeth_fs.h" | 22 | #include "qeth_fs.h" |
23 | 23 | ||
24 | const char *VERSION_QETH_PROC_C = "$Revision: 1.13 $"; | 24 | const char *VERSION_QETH_PROC_C = "$Revision: 1.16 $"; |
25 | 25 | ||
26 | /***** /proc/qeth *****/ | 26 | /***** /proc/qeth *****/ |
27 | #define QETH_PROCFILE_NAME "qeth" | 27 | #define QETH_PROCFILE_NAME "qeth" |
@@ -30,30 +30,26 @@ static struct proc_dir_entry *qeth_procfile; | |||
30 | static int | 30 | static int |
31 | qeth_procfile_seq_match(struct device *dev, void *data) | 31 | qeth_procfile_seq_match(struct device *dev, void *data) |
32 | { | 32 | { |
33 | return 1; | 33 | return(dev ? 1 : 0); |
34 | } | 34 | } |
35 | 35 | ||
36 | static void * | 36 | static void * |
37 | qeth_procfile_seq_start(struct seq_file *s, loff_t *offset) | 37 | qeth_procfile_seq_start(struct seq_file *s, loff_t *offset) |
38 | { | 38 | { |
39 | struct device *dev; | 39 | struct device *dev = NULL; |
40 | loff_t nr; | 40 | loff_t nr = 0; |
41 | 41 | ||
42 | down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); | 42 | down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); |
43 | 43 | if (*offset == 0) | |
44 | nr = *offset; | ||
45 | if (nr == 0) | ||
46 | return SEQ_START_TOKEN; | 44 | return SEQ_START_TOKEN; |
47 | 45 | while (1) { | |
48 | dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL, | ||
49 | NULL, qeth_procfile_seq_match); | ||
50 | |||
51 | /* get card at pos *offset */ | ||
52 | nr = *offset; | ||
53 | while (nr-- > 1 && dev) | ||
54 | dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev, | 46 | dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev, |
55 | NULL, qeth_procfile_seq_match); | 47 | NULL, qeth_procfile_seq_match); |
56 | return (void *) dev; | 48 | if (++nr == *offset) |
49 | break; | ||
50 | put_device(dev); | ||
51 | } | ||
52 | return dev; | ||
57 | } | 53 | } |
58 | 54 | ||
59 | static void | 55 | static void |
@@ -66,19 +62,14 @@ static void * | |||
66 | qeth_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset) | 62 | qeth_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset) |
67 | { | 63 | { |
68 | struct device *prev, *next; | 64 | struct device *prev, *next; |
69 | 65 | ||
70 | if (it == SEQ_START_TOKEN) { | 66 | if (it == SEQ_START_TOKEN) |
71 | next = driver_find_device(&qeth_ccwgroup_driver.driver, | 67 | prev = NULL; |
72 | NULL, NULL, qeth_procfile_seq_match); | 68 | else |
73 | if (next) | 69 | prev = (struct device *) it; |
74 | (*offset)++; | ||
75 | return (void *) next; | ||
76 | } | ||
77 | prev = (struct device *) it; | ||
78 | next = driver_find_device(&qeth_ccwgroup_driver.driver, | 70 | next = driver_find_device(&qeth_ccwgroup_driver.driver, |
79 | prev, NULL, qeth_procfile_seq_match); | 71 | prev, NULL, qeth_procfile_seq_match); |
80 | if (next) | 72 | (*offset)++; |
81 | (*offset)++; | ||
82 | return (void *) next; | 73 | return (void *) next; |
83 | } | 74 | } |
84 | 75 | ||
@@ -87,7 +78,7 @@ qeth_get_router_str(struct qeth_card *card, int ipv) | |||
87 | { | 78 | { |
88 | int routing_type = 0; | 79 | int routing_type = 0; |
89 | 80 | ||
90 | if (ipv == 4){ | 81 | if (ipv == 4) { |
91 | routing_type = card->options.route4.type; | 82 | routing_type = card->options.route4.type; |
92 | } else { | 83 | } else { |
93 | #ifdef CONFIG_QETH_IPV6 | 84 | #ifdef CONFIG_QETH_IPV6 |
@@ -154,6 +145,7 @@ qeth_procfile_seq_show(struct seq_file *s, void *it) | |||
154 | card->qdio.in_buf_pool.buf_count); | 145 | card->qdio.in_buf_pool.buf_count); |
155 | else | 146 | else |
156 | seq_printf(s, " +++ LAN OFFLINE +++\n"); | 147 | seq_printf(s, " +++ LAN OFFLINE +++\n"); |
148 | put_device(device); | ||
157 | } | 149 | } |
158 | return 0; | 150 | return 0; |
159 | } | 151 | } |
@@ -184,51 +176,16 @@ static struct file_operations qeth_procfile_fops = { | |||
184 | static struct proc_dir_entry *qeth_perf_procfile; | 176 | static struct proc_dir_entry *qeth_perf_procfile; |
185 | 177 | ||
186 | #ifdef CONFIG_QETH_PERF_STATS | 178 | #ifdef CONFIG_QETH_PERF_STATS |
187 | |||
188 | static void * | ||
189 | qeth_perf_procfile_seq_start(struct seq_file *s, loff_t *offset) | ||
190 | { | ||
191 | struct device *dev = NULL; | ||
192 | int nr; | ||
193 | |||
194 | down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); | ||
195 | /* get card at pos *offset */ | ||
196 | dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL, NULL, | ||
197 | qeth_procfile_seq_match); | ||
198 | |||
199 | /* get card at pos *offset */ | ||
200 | nr = *offset; | ||
201 | while (nr-- > 1 && dev) | ||
202 | dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev, | ||
203 | NULL, qeth_procfile_seq_match); | ||
204 | return (void *) dev; | ||
205 | } | ||
206 | |||
207 | static void | ||
208 | qeth_perf_procfile_seq_stop(struct seq_file *s, void* it) | ||
209 | { | ||
210 | up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); | ||
211 | } | ||
212 | |||
213 | static void * | ||
214 | qeth_perf_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset) | ||
215 | { | ||
216 | struct device *prev, *next; | ||
217 | |||
218 | prev = (struct device *) it; | ||
219 | next = driver_find_device(&qeth_ccwgroup_driver.driver, prev, | ||
220 | NULL, qeth_procfile_seq_match); | ||
221 | if (next) | ||
222 | (*offset)++; | ||
223 | return (void *) next; | ||
224 | } | ||
225 | |||
226 | static int | 179 | static int |
227 | qeth_perf_procfile_seq_show(struct seq_file *s, void *it) | 180 | qeth_perf_procfile_seq_show(struct seq_file *s, void *it) |
228 | { | 181 | { |
229 | struct device *device; | 182 | struct device *device; |
230 | struct qeth_card *card; | 183 | struct qeth_card *card; |
231 | 184 | ||
185 | |||
186 | if (it == SEQ_START_TOKEN) | ||
187 | return 0; | ||
188 | |||
232 | device = (struct device *) it; | 189 | device = (struct device *) it; |
233 | card = device->driver_data; | 190 | card = device->driver_data; |
234 | seq_printf(s, "For card with devnos %s/%s/%s (%s):\n", | 191 | seq_printf(s, "For card with devnos %s/%s/%s (%s):\n", |
@@ -295,13 +252,14 @@ qeth_perf_procfile_seq_show(struct seq_file *s, void *it) | |||
295 | card->perf_stats.outbound_do_qdio_time, | 252 | card->perf_stats.outbound_do_qdio_time, |
296 | card->perf_stats.outbound_do_qdio_cnt | 253 | card->perf_stats.outbound_do_qdio_cnt |
297 | ); | 254 | ); |
255 | put_device(device); | ||
298 | return 0; | 256 | return 0; |
299 | } | 257 | } |
300 | 258 | ||
301 | static struct seq_operations qeth_perf_procfile_seq_ops = { | 259 | static struct seq_operations qeth_perf_procfile_seq_ops = { |
302 | .start = qeth_perf_procfile_seq_start, | 260 | .start = qeth_procfile_seq_start, |
303 | .stop = qeth_perf_procfile_seq_stop, | 261 | .stop = qeth_procfile_seq_stop, |
304 | .next = qeth_perf_procfile_seq_next, | 262 | .next = qeth_procfile_seq_next, |
305 | .show = qeth_perf_procfile_seq_show, | 263 | .show = qeth_perf_procfile_seq_show, |
306 | }; | 264 | }; |
307 | 265 | ||
@@ -324,93 +282,6 @@ static struct file_operations qeth_perf_procfile_fops = { | |||
324 | #define qeth_perf_procfile_created 1 | 282 | #define qeth_perf_procfile_created 1 |
325 | #endif /* CONFIG_QETH_PERF_STATS */ | 283 | #endif /* CONFIG_QETH_PERF_STATS */ |
326 | 284 | ||
327 | /***** /proc/qeth_ipa_takeover *****/ | ||
328 | #define QETH_IPATO_PROCFILE_NAME "qeth_ipa_takeover" | ||
329 | static struct proc_dir_entry *qeth_ipato_procfile; | ||
330 | |||
331 | static void * | ||
332 | qeth_ipato_procfile_seq_start(struct seq_file *s, loff_t *offset) | ||
333 | { | ||
334 | struct device *dev; | ||
335 | loff_t nr; | ||
336 | |||
337 | down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); | ||
338 | /* TODO: finish this */ | ||
339 | /* | ||
340 | * maybe SEQ_SATRT_TOKEN can be returned for offset 0 | ||
341 | * output driver settings then; | ||
342 | * else output setting for respective card | ||
343 | */ | ||
344 | |||
345 | dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL, NULL, | ||
346 | qeth_procfile_seq_match); | ||
347 | |||
348 | /* get card at pos *offset */ | ||
349 | nr = *offset; | ||
350 | while (nr-- > 1 && dev) | ||
351 | dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev, | ||
352 | NULL, qeth_procfile_seq_match); | ||
353 | return (void *) dev; | ||
354 | } | ||
355 | |||
356 | static void | ||
357 | qeth_ipato_procfile_seq_stop(struct seq_file *s, void* it) | ||
358 | { | ||
359 | up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); | ||
360 | } | ||
361 | |||
362 | static void * | ||
363 | qeth_ipato_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset) | ||
364 | { | ||
365 | struct device *prev, *next; | ||
366 | |||
367 | prev = (struct device *) it; | ||
368 | next = driver_find_device(&qeth_ccwgroup_driver.driver, prev, | ||
369 | NULL, qeth_procfile_seq_match); | ||
370 | if (next) | ||
371 | (*offset)++; | ||
372 | return (void *) next; | ||
373 | } | ||
374 | |||
375 | static int | ||
376 | qeth_ipato_procfile_seq_show(struct seq_file *s, void *it) | ||
377 | { | ||
378 | struct device *device; | ||
379 | struct qeth_card *card; | ||
380 | |||
381 | /* TODO: finish this */ | ||
382 | /* | ||
383 | * maybe SEQ_SATRT_TOKEN can be returned for offset 0 | ||
384 | * output driver settings then; | ||
385 | * else output setting for respective card | ||
386 | */ | ||
387 | device = (struct device *) it; | ||
388 | card = device->driver_data; | ||
389 | |||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static struct seq_operations qeth_ipato_procfile_seq_ops = { | ||
394 | .start = qeth_ipato_procfile_seq_start, | ||
395 | .stop = qeth_ipato_procfile_seq_stop, | ||
396 | .next = qeth_ipato_procfile_seq_next, | ||
397 | .show = qeth_ipato_procfile_seq_show, | ||
398 | }; | ||
399 | |||
400 | static int | ||
401 | qeth_ipato_procfile_open(struct inode *inode, struct file *file) | ||
402 | { | ||
403 | return seq_open(file, &qeth_ipato_procfile_seq_ops); | ||
404 | } | ||
405 | |||
406 | static struct file_operations qeth_ipato_procfile_fops = { | ||
407 | .owner = THIS_MODULE, | ||
408 | .open = qeth_ipato_procfile_open, | ||
409 | .read = seq_read, | ||
410 | .llseek = seq_lseek, | ||
411 | .release = seq_release, | ||
412 | }; | ||
413 | |||
414 | int __init | 285 | int __init |
415 | qeth_create_procfs_entries(void) | 286 | qeth_create_procfs_entries(void) |
416 | { | 287 | { |
@@ -426,13 +297,7 @@ qeth_create_procfs_entries(void) | |||
426 | qeth_perf_procfile->proc_fops = &qeth_perf_procfile_fops; | 297 | qeth_perf_procfile->proc_fops = &qeth_perf_procfile_fops; |
427 | #endif /* CONFIG_QETH_PERF_STATS */ | 298 | #endif /* CONFIG_QETH_PERF_STATS */ |
428 | 299 | ||
429 | qeth_ipato_procfile = create_proc_entry(QETH_IPATO_PROCFILE_NAME, | ||
430 | S_IFREG | 0444, NULL); | ||
431 | if (qeth_ipato_procfile) | ||
432 | qeth_ipato_procfile->proc_fops = &qeth_ipato_procfile_fops; | ||
433 | |||
434 | if (qeth_procfile && | 300 | if (qeth_procfile && |
435 | qeth_ipato_procfile && | ||
436 | qeth_perf_procfile_created) | 301 | qeth_perf_procfile_created) |
437 | return 0; | 302 | return 0; |
438 | else | 303 | else |
@@ -446,62 +311,5 @@ qeth_remove_procfs_entries(void) | |||
446 | remove_proc_entry(QETH_PROCFILE_NAME, NULL); | 311 | remove_proc_entry(QETH_PROCFILE_NAME, NULL); |
447 | if (qeth_perf_procfile) | 312 | if (qeth_perf_procfile) |
448 | remove_proc_entry(QETH_PERF_PROCFILE_NAME, NULL); | 313 | remove_proc_entry(QETH_PERF_PROCFILE_NAME, NULL); |
449 | if (qeth_ipato_procfile) | ||
450 | remove_proc_entry(QETH_IPATO_PROCFILE_NAME, NULL); | ||
451 | } | 314 | } |
452 | 315 | ||
453 | |||
454 | /* ONLY FOR DEVELOPMENT! -> make it as module */ | ||
455 | /* | ||
456 | static void | ||
457 | qeth_create_sysfs_entries(void) | ||
458 | { | ||
459 | struct device *dev; | ||
460 | |||
461 | down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); | ||
462 | |||
463 | list_for_each_entry(dev, &qeth_ccwgroup_driver.driver.devices, | ||
464 | driver_list) | ||
465 | qeth_create_device_attributes(dev); | ||
466 | |||
467 | up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); | ||
468 | } | ||
469 | |||
470 | static void | ||
471 | qeth_remove_sysfs_entries(void) | ||
472 | { | ||
473 | struct device *dev; | ||
474 | |||
475 | down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); | ||
476 | |||
477 | list_for_each_entry(dev, &qeth_ccwgroup_driver.driver.devices, | ||
478 | driver_list) | ||
479 | qeth_remove_device_attributes(dev); | ||
480 | |||
481 | up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); | ||
482 | } | ||
483 | |||
484 | static int __init | ||
485 | qeth_fs_init(void) | ||
486 | { | ||
487 | printk(KERN_INFO "qeth_fs_init\n"); | ||
488 | qeth_create_procfs_entries(); | ||
489 | qeth_create_sysfs_entries(); | ||
490 | |||
491 | return 0; | ||
492 | } | ||
493 | |||
494 | static void __exit | ||
495 | qeth_fs_exit(void) | ||
496 | { | ||
497 | printk(KERN_INFO "qeth_fs_exit\n"); | ||
498 | qeth_remove_procfs_entries(); | ||
499 | qeth_remove_sysfs_entries(); | ||
500 | } | ||
501 | |||
502 | |||
503 | module_init(qeth_fs_init); | ||
504 | module_exit(qeth_fs_exit); | ||
505 | |||
506 | MODULE_LICENSE("GPL"); | ||
507 | */ | ||
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c index ddd6019ba092..0ea185f70f75 100644 --- a/drivers/s390/net/qeth_sys.c +++ b/drivers/s390/net/qeth_sys.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * | 2 | * |
3 | * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.58 $) | 3 | * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.60 $) |
4 | * | 4 | * |
5 | * Linux on zSeries OSA Express and HiperSockets support | 5 | * Linux on zSeries OSA Express and HiperSockets support |
6 | * This file contains code related to sysfs. | 6 | * This file contains code related to sysfs. |
@@ -20,7 +20,7 @@ | |||
20 | #include "qeth_mpc.h" | 20 | #include "qeth_mpc.h" |
21 | #include "qeth_fs.h" | 21 | #include "qeth_fs.h" |
22 | 22 | ||
23 | const char *VERSION_QETH_SYS_C = "$Revision: 1.58 $"; | 23 | const char *VERSION_QETH_SYS_C = "$Revision: 1.60 $"; |
24 | 24 | ||
25 | /*****************************************************************************/ | 25 | /*****************************************************************************/ |
26 | /* */ | 26 | /* */ |
@@ -160,7 +160,7 @@ qeth_dev_portname_store(struct device *dev, struct device_attribute *attr, const | |||
160 | return -EPERM; | 160 | return -EPERM; |
161 | 161 | ||
162 | tmp = strsep((char **) &buf, "\n"); | 162 | tmp = strsep((char **) &buf, "\n"); |
163 | if ((strlen(tmp) > 8) || (strlen(tmp) < 2)) | 163 | if ((strlen(tmp) > 8) || (strlen(tmp) == 0)) |
164 | return -EINVAL; | 164 | return -EINVAL; |
165 | 165 | ||
166 | card->info.portname[0] = strlen(tmp); | 166 | card->info.portname[0] = strlen(tmp); |
diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h index e245af3c4cbd..3c50b6f24f51 100644 --- a/drivers/s390/net/qeth_tso.h +++ b/drivers/s390/net/qeth_tso.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.7 $) | 2 | * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.8 $) |
3 | * | 3 | * |
4 | * Header file for qeth TCP Segmentation Offload support. | 4 | * Header file for qeth TCP Segmentation Offload support. |
5 | * | 5 | * |
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Author(s): Frank Pavlic <fpavlic@de.ibm.com> | 8 | * Author(s): Frank Pavlic <fpavlic@de.ibm.com> |
9 | * | 9 | * |
10 | * $Revision: 1.7 $ $Date: 2005/05/04 20:19:18 $ | 10 | * $Revision: 1.8 $ $Date: 2005/05/04 20:19:18 $ |
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | #ifndef __QETH_TSO_H__ | 13 | #ifndef __QETH_TSO_H__ |
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 418fc7b896ac..6252b9ddc01e 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c | |||
@@ -660,7 +660,12 @@ static int adpt_abort(struct scsi_cmnd * cmd) | |||
660 | msg[2] = 0; | 660 | msg[2] = 0; |
661 | msg[3]= 0; | 661 | msg[3]= 0; |
662 | msg[4] = (u32)cmd; | 662 | msg[4] = (u32)cmd; |
663 | if( (rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER)) != 0){ | 663 | if (pHba->host) |
664 | spin_lock_irq(pHba->host->host_lock); | ||
665 | rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER); | ||
666 | if (pHba->host) | ||
667 | spin_unlock_irq(pHba->host->host_lock); | ||
668 | if (rcode != 0) { | ||
664 | if(rcode == -EOPNOTSUPP ){ | 669 | if(rcode == -EOPNOTSUPP ){ |
665 | printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name); | 670 | printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name); |
666 | return FAILED; | 671 | return FAILED; |
@@ -697,10 +702,15 @@ static int adpt_device_reset(struct scsi_cmnd* cmd) | |||
697 | msg[2] = 0; | 702 | msg[2] = 0; |
698 | msg[3] = 0; | 703 | msg[3] = 0; |
699 | 704 | ||
705 | if (pHba->host) | ||
706 | spin_lock_irq(pHba->host->host_lock); | ||
700 | old_state = d->state; | 707 | old_state = d->state; |
701 | d->state |= DPTI_DEV_RESET; | 708 | d->state |= DPTI_DEV_RESET; |
702 | if( (rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER)) ){ | 709 | rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER); |
703 | d->state = old_state; | 710 | d->state = old_state; |
711 | if (pHba->host) | ||
712 | spin_unlock_irq(pHba->host->host_lock); | ||
713 | if (rcode != 0) { | ||
704 | if(rcode == -EOPNOTSUPP ){ | 714 | if(rcode == -EOPNOTSUPP ){ |
705 | printk(KERN_INFO"%s: Device reset not supported\n",pHba->name); | 715 | printk(KERN_INFO"%s: Device reset not supported\n",pHba->name); |
706 | return FAILED; | 716 | return FAILED; |
@@ -708,7 +718,6 @@ static int adpt_device_reset(struct scsi_cmnd* cmd) | |||
708 | printk(KERN_INFO"%s: Device reset failed\n",pHba->name); | 718 | printk(KERN_INFO"%s: Device reset failed\n",pHba->name); |
709 | return FAILED; | 719 | return FAILED; |
710 | } else { | 720 | } else { |
711 | d->state = old_state; | ||
712 | printk(KERN_INFO"%s: Device reset successful\n",pHba->name); | 721 | printk(KERN_INFO"%s: Device reset successful\n",pHba->name); |
713 | return SUCCESS; | 722 | return SUCCESS; |
714 | } | 723 | } |
@@ -721,6 +730,7 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd) | |||
721 | { | 730 | { |
722 | adpt_hba* pHba; | 731 | adpt_hba* pHba; |
723 | u32 msg[4]; | 732 | u32 msg[4]; |
733 | u32 rcode; | ||
724 | 734 | ||
725 | pHba = (adpt_hba*)cmd->device->host->hostdata[0]; | 735 | pHba = (adpt_hba*)cmd->device->host->hostdata[0]; |
726 | memset(msg, 0, sizeof(msg)); | 736 | memset(msg, 0, sizeof(msg)); |
@@ -729,7 +739,12 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd) | |||
729 | msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid); | 739 | msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid); |
730 | msg[2] = 0; | 740 | msg[2] = 0; |
731 | msg[3] = 0; | 741 | msg[3] = 0; |
732 | if(adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER) ){ | 742 | if (pHba->host) |
743 | spin_lock_irq(pHba->host->host_lock); | ||
744 | rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER); | ||
745 | if (pHba->host) | ||
746 | spin_unlock_irq(pHba->host->host_lock); | ||
747 | if (rcode != 0) { | ||
733 | printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name); | 748 | printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name); |
734 | return FAILED; | 749 | return FAILED; |
735 | } else { | 750 | } else { |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 72ddba98f8fb..2282c04fee46 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -2044,7 +2044,7 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) | |||
2044 | else { | 2044 | else { |
2045 | u8 *scsicmd = cmd->cmnd; | 2045 | u8 *scsicmd = cmd->cmnd; |
2046 | 2046 | ||
2047 | if (scsicmd[0] == INQUIRY) { | 2047 | if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) { |
2048 | u8 *buf = NULL; | 2048 | u8 *buf = NULL; |
2049 | unsigned int buflen; | 2049 | unsigned int buflen; |
2050 | 2050 | ||
@@ -2058,9 +2058,6 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) | |||
2058 | * device. 2) Ensure response data format / ATAPI information | 2058 | * device. 2) Ensure response data format / ATAPI information |
2059 | * are always correct. | 2059 | * are always correct. |
2060 | */ | 2060 | */ |
2061 | /* FIXME: do we ever override EVPD pages and the like, with | ||
2062 | * this code? | ||
2063 | */ | ||
2064 | if (buf[2] == 0) { | 2061 | if (buf[2] == 0) { |
2065 | buf[2] = 0x5; | 2062 | buf[2] = 0x5; |
2066 | buf[3] = 0x32; | 2063 | buf[3] = 0x32; |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 950b087e4ca2..05ebb9cef961 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -400,6 +400,36 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, | |||
400 | return found_target; | 400 | return found_target; |
401 | } | 401 | } |
402 | 402 | ||
403 | struct work_queue_wrapper { | ||
404 | struct work_struct work; | ||
405 | struct scsi_target *starget; | ||
406 | }; | ||
407 | |||
408 | static void scsi_target_reap_work(void *data) { | ||
409 | struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; | ||
410 | struct scsi_target *starget = wqw->starget; | ||
411 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | ||
412 | unsigned long flags; | ||
413 | |||
414 | kfree(wqw); | ||
415 | |||
416 | spin_lock_irqsave(shost->host_lock, flags); | ||
417 | |||
418 | if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { | ||
419 | list_del_init(&starget->siblings); | ||
420 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
421 | transport_remove_device(&starget->dev); | ||
422 | device_del(&starget->dev); | ||
423 | transport_destroy_device(&starget->dev); | ||
424 | put_device(&starget->dev); | ||
425 | return; | ||
426 | |||
427 | } | ||
428 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
429 | |||
430 | return; | ||
431 | } | ||
432 | |||
403 | /** | 433 | /** |
404 | * scsi_target_reap - check to see if target is in use and destroy if not | 434 | * scsi_target_reap - check to see if target is in use and destroy if not |
405 | * | 435 | * |
@@ -411,19 +441,18 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, | |||
411 | */ | 441 | */ |
412 | void scsi_target_reap(struct scsi_target *starget) | 442 | void scsi_target_reap(struct scsi_target *starget) |
413 | { | 443 | { |
414 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 444 | struct work_queue_wrapper *wqw = |
415 | unsigned long flags; | 445 | kzalloc(sizeof(struct work_queue_wrapper), GFP_ATOMIC); |
416 | spin_lock_irqsave(shost->host_lock, flags); | ||
417 | 446 | ||
418 | if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { | 447 | if (!wqw) { |
419 | list_del_init(&starget->siblings); | 448 | starget_printk(KERN_ERR, starget, |
420 | spin_unlock_irqrestore(shost->host_lock, flags); | 449 | "Failed to allocate memory in scsi_reap_target()\n"); |
421 | device_del(&starget->dev); | ||
422 | transport_unregister_device(&starget->dev); | ||
423 | put_device(&starget->dev); | ||
424 | return; | 450 | return; |
425 | } | 451 | } |
426 | spin_unlock_irqrestore(shost->host_lock, flags); | 452 | |
453 | INIT_WORK(&wqw->work, scsi_target_reap_work, wqw); | ||
454 | wqw->starget = starget; | ||
455 | schedule_work(&wqw->work); | ||
427 | } | 456 | } |
428 | 457 | ||
429 | /** | 458 | /** |
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index cd95d2ae7b77..685b997306cf 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -105,6 +105,7 @@ static struct { | |||
105 | { FC_PORTSTATE_LINKDOWN, "Linkdown" }, | 105 | { FC_PORTSTATE_LINKDOWN, "Linkdown" }, |
106 | { FC_PORTSTATE_ERROR, "Error" }, | 106 | { FC_PORTSTATE_ERROR, "Error" }, |
107 | { FC_PORTSTATE_LOOPBACK, "Loopback" }, | 107 | { FC_PORTSTATE_LOOPBACK, "Loopback" }, |
108 | { FC_PORTSTATE_DELETED, "Deleted" }, | ||
108 | }; | 109 | }; |
109 | fc_enum_name_search(port_state, fc_port_state, fc_port_state_names) | 110 | fc_enum_name_search(port_state, fc_port_state, fc_port_state_names) |
110 | #define FC_PORTSTATE_MAX_NAMELEN 20 | 111 | #define FC_PORTSTATE_MAX_NAMELEN 20 |
@@ -211,6 +212,7 @@ fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names) | |||
211 | #define FC_MGMTSRVR_PORTID 0x00000a | 212 | #define FC_MGMTSRVR_PORTID 0x00000a |
212 | 213 | ||
213 | 214 | ||
215 | static void fc_shost_remove_rports(void *data); | ||
214 | static void fc_timeout_deleted_rport(void *data); | 216 | static void fc_timeout_deleted_rport(void *data); |
215 | static void fc_scsi_scan_rport(void *data); | 217 | static void fc_scsi_scan_rport(void *data); |
216 | static void fc_rport_terminate(struct fc_rport *rport); | 218 | static void fc_rport_terminate(struct fc_rport *rport); |
@@ -318,6 +320,8 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev, | |||
318 | fc_host_next_rport_number(shost) = 0; | 320 | fc_host_next_rport_number(shost) = 0; |
319 | fc_host_next_target_id(shost) = 0; | 321 | fc_host_next_target_id(shost) = 0; |
320 | 322 | ||
323 | fc_host_flags(shost) = 0; | ||
324 | INIT_WORK(&fc_host_rport_del_work(shost), fc_shost_remove_rports, shost); | ||
321 | return 0; | 325 | return 0; |
322 | } | 326 | } |
323 | 327 | ||
@@ -387,6 +391,7 @@ show_fc_rport_##field (struct class_device *cdev, char *buf) \ | |||
387 | struct fc_internal *i = to_fc_internal(shost->transportt); \ | 391 | struct fc_internal *i = to_fc_internal(shost->transportt); \ |
388 | if ((i->f->get_rport_##field) && \ | 392 | if ((i->f->get_rport_##field) && \ |
389 | !((rport->port_state == FC_PORTSTATE_BLOCKED) || \ | 393 | !((rport->port_state == FC_PORTSTATE_BLOCKED) || \ |
394 | (rport->port_state == FC_PORTSTATE_DELETED) || \ | ||
390 | (rport->port_state == FC_PORTSTATE_NOTPRESENT))) \ | 395 | (rport->port_state == FC_PORTSTATE_NOTPRESENT))) \ |
391 | i->f->get_rport_##field(rport); \ | 396 | i->f->get_rport_##field(rport); \ |
392 | return snprintf(buf, sz, format_string, cast rport->field); \ | 397 | return snprintf(buf, sz, format_string, cast rport->field); \ |
@@ -402,6 +407,7 @@ store_fc_rport_##field(struct class_device *cdev, const char *buf, \ | |||
402 | struct Scsi_Host *shost = rport_to_shost(rport); \ | 407 | struct Scsi_Host *shost = rport_to_shost(rport); \ |
403 | struct fc_internal *i = to_fc_internal(shost->transportt); \ | 408 | struct fc_internal *i = to_fc_internal(shost->transportt); \ |
404 | if ((rport->port_state == FC_PORTSTATE_BLOCKED) || \ | 409 | if ((rport->port_state == FC_PORTSTATE_BLOCKED) || \ |
410 | (rport->port_state == FC_PORTSTATE_DELETED) || \ | ||
405 | (rport->port_state == FC_PORTSTATE_NOTPRESENT)) \ | 411 | (rport->port_state == FC_PORTSTATE_NOTPRESENT)) \ |
406 | return -EBUSY; \ | 412 | return -EBUSY; \ |
407 | val = simple_strtoul(buf, NULL, 0); \ | 413 | val = simple_strtoul(buf, NULL, 0); \ |
@@ -519,6 +525,7 @@ store_fc_rport_dev_loss_tmo(struct class_device *cdev, const char *buf, | |||
519 | struct Scsi_Host *shost = rport_to_shost(rport); | 525 | struct Scsi_Host *shost = rport_to_shost(rport); |
520 | struct fc_internal *i = to_fc_internal(shost->transportt); | 526 | struct fc_internal *i = to_fc_internal(shost->transportt); |
521 | if ((rport->port_state == FC_PORTSTATE_BLOCKED) || | 527 | if ((rport->port_state == FC_PORTSTATE_BLOCKED) || |
528 | (rport->port_state == FC_PORTSTATE_DELETED) || | ||
522 | (rport->port_state == FC_PORTSTATE_NOTPRESENT)) | 529 | (rport->port_state == FC_PORTSTATE_NOTPRESENT)) |
523 | return -EBUSY; | 530 | return -EBUSY; |
524 | val = simple_strtoul(buf, NULL, 0); | 531 | val = simple_strtoul(buf, NULL, 0); |
@@ -1769,7 +1776,7 @@ fc_timeout_deleted_rport(void *data) | |||
1769 | rport->maxframe_size = -1; | 1776 | rport->maxframe_size = -1; |
1770 | rport->supported_classes = FC_COS_UNSPECIFIED; | 1777 | rport->supported_classes = FC_COS_UNSPECIFIED; |
1771 | rport->roles = FC_RPORT_ROLE_UNKNOWN; | 1778 | rport->roles = FC_RPORT_ROLE_UNKNOWN; |
1772 | rport->port_state = FC_PORTSTATE_NOTPRESENT; | 1779 | rport->port_state = FC_PORTSTATE_DELETED; |
1773 | 1780 | ||
1774 | /* remove the identifiers that aren't used in the consisting binding */ | 1781 | /* remove the identifiers that aren't used in the consisting binding */ |
1775 | switch (fc_host_tgtid_bind_type(shost)) { | 1782 | switch (fc_host_tgtid_bind_type(shost)) { |
@@ -1789,14 +1796,23 @@ fc_timeout_deleted_rport(void *data) | |||
1789 | break; | 1796 | break; |
1790 | } | 1797 | } |
1791 | 1798 | ||
1792 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1793 | |||
1794 | /* | 1799 | /* |
1795 | * As this only occurs if the remote port (scsi target) | 1800 | * As this only occurs if the remote port (scsi target) |
1796 | * went away and didn't come back - we'll remove | 1801 | * went away and didn't come back - we'll remove |
1797 | * all attached scsi devices. | 1802 | * all attached scsi devices. |
1803 | * | ||
1804 | * We'll schedule the shost work item to perform the actual removal | ||
1805 | * to avoid recursion in the different flush calls if we perform | ||
1806 | * the removal in each target - and there are lots of targets | ||
1807 | * whose timeouts fire at the same time. | ||
1798 | */ | 1808 | */ |
1799 | fc_rport_tgt_remove(rport); | 1809 | |
1810 | if ( !(fc_host_flags(shost) & FC_SHOST_RPORT_DEL_SCHEDULED)) { | ||
1811 | fc_host_flags(shost) |= FC_SHOST_RPORT_DEL_SCHEDULED; | ||
1812 | scsi_queue_work(shost, &fc_host_rport_del_work(shost)); | ||
1813 | } | ||
1814 | |||
1815 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1800 | } | 1816 | } |
1801 | 1817 | ||
1802 | /** | 1818 | /** |
@@ -1818,6 +1834,41 @@ fc_scsi_scan_rport(void *data) | |||
1818 | } | 1834 | } |
1819 | 1835 | ||
1820 | 1836 | ||
1837 | /** | ||
1838 | * fc_shost_remove_rports - called to remove all rports that are marked | ||
1839 | * as in a deleted (not connected) state. | ||
1840 | * | ||
1841 | * @data: shost whose rports are to be looked at | ||
1842 | **/ | ||
1843 | static void | ||
1844 | fc_shost_remove_rports(void *data) | ||
1845 | { | ||
1846 | struct Scsi_Host *shost = (struct Scsi_Host *)data; | ||
1847 | struct fc_rport *rport, *next_rport; | ||
1848 | unsigned long flags; | ||
1849 | |||
1850 | spin_lock_irqsave(shost->host_lock, flags); | ||
1851 | while (fc_host_flags(shost) & FC_SHOST_RPORT_DEL_SCHEDULED) { | ||
1852 | |||
1853 | fc_host_flags(shost) &= ~FC_SHOST_RPORT_DEL_SCHEDULED; | ||
1854 | |||
1855 | restart_search: | ||
1856 | list_for_each_entry_safe(rport, next_rport, | ||
1857 | &fc_host_rport_bindings(shost), peers) { | ||
1858 | if (rport->port_state == FC_PORTSTATE_DELETED) { | ||
1859 | rport->port_state = FC_PORTSTATE_NOTPRESENT; | ||
1860 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1861 | fc_rport_tgt_remove(rport); | ||
1862 | spin_lock_irqsave(shost->host_lock, flags); | ||
1863 | goto restart_search; | ||
1864 | } | ||
1865 | } | ||
1866 | |||
1867 | } | ||
1868 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1869 | } | ||
1870 | |||
1871 | |||
1821 | MODULE_AUTHOR("Martin Hicks"); | 1872 | MODULE_AUTHOR("Martin Hicks"); |
1822 | MODULE_DESCRIPTION("FC Transport Attributes"); | 1873 | MODULE_DESCRIPTION("FC Transport Attributes"); |
1823 | MODULE_LICENSE("GPL"); | 1874 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index ad47c1b84c3f..812bae62c8ec 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -10,7 +10,7 @@ menu "Serial drivers" | |||
10 | # The new 8250/16550 serial drivers | 10 | # The new 8250/16550 serial drivers |
11 | config SERIAL_8250 | 11 | config SERIAL_8250 |
12 | tristate "8250/16550 and compatible serial support" | 12 | tristate "8250/16550 and compatible serial support" |
13 | depends on (BROKEN || !(SPARC64 || SPARC32)) | 13 | depends on (BROKEN || !SPARC) |
14 | select SERIAL_CORE | 14 | select SERIAL_CORE |
15 | ---help--- | 15 | ---help--- |
16 | This selects whether you want to include the driver for the standard | 16 | This selects whether you want to include the driver for the standard |
@@ -469,14 +469,14 @@ config SERIAL_IMX_CONSOLE | |||
469 | 469 | ||
470 | config SERIAL_SUNCORE | 470 | config SERIAL_SUNCORE |
471 | bool | 471 | bool |
472 | depends on SPARC32 || SPARC64 | 472 | depends on SPARC |
473 | select SERIAL_CORE | 473 | select SERIAL_CORE |
474 | select SERIAL_CORE_CONSOLE | 474 | select SERIAL_CORE_CONSOLE |
475 | default y | 475 | default y |
476 | 476 | ||
477 | config SERIAL_SUNZILOG | 477 | config SERIAL_SUNZILOG |
478 | tristate "Sun Zilog8530 serial support" | 478 | tristate "Sun Zilog8530 serial support" |
479 | depends on SPARC32 || SPARC64 | 479 | depends on SPARC |
480 | help | 480 | help |
481 | This driver supports the Zilog8530 serial ports found on many Sparc | 481 | This driver supports the Zilog8530 serial ports found on many Sparc |
482 | systems. Say Y or M if you want to be able to these serial ports. | 482 | systems. Say Y or M if you want to be able to these serial ports. |
@@ -491,7 +491,7 @@ config SERIAL_SUNZILOG_CONSOLE | |||
491 | 491 | ||
492 | config SERIAL_SUNSU | 492 | config SERIAL_SUNSU |
493 | tristate "Sun SU serial support" | 493 | tristate "Sun SU serial support" |
494 | depends on (SPARC32 || SPARC64) && PCI | 494 | depends on SPARC && PCI |
495 | help | 495 | help |
496 | This driver supports the 8250 serial ports that run the keyboard and | 496 | This driver supports the 8250 serial ports that run the keyboard and |
497 | mouse on (PCI) UltraSPARC systems. Say Y or M if you want to be able | 497 | mouse on (PCI) UltraSPARC systems. Say Y or M if you want to be able |
@@ -547,7 +547,7 @@ config PDC_CONSOLE | |||
547 | 547 | ||
548 | config SERIAL_SUNSAB | 548 | config SERIAL_SUNSAB |
549 | tristate "Sun Siemens SAB82532 serial support" | 549 | tristate "Sun Siemens SAB82532 serial support" |
550 | depends on (SPARC32 || SPARC64) && PCI | 550 | depends on SPARC && PCI |
551 | help | 551 | help |
552 | This driver supports the Siemens SAB82532 DUSCC serial ports on newer | 552 | This driver supports the Siemens SAB82532 DUSCC serial ports on newer |
553 | (PCI) UltraSPARC systems. Say Y or M if you want to be able to these | 553 | (PCI) UltraSPARC systems. Say Y or M if you want to be able to these |
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 89d7bd3eaee3..d84476ee6592 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c | |||
@@ -160,7 +160,7 @@ pl011_rx_chars(struct uart_amba_port *uap) | |||
160 | flag = TTY_FRAME; | 160 | flag = TTY_FRAME; |
161 | } | 161 | } |
162 | 162 | ||
163 | if (uart_handle_sysrq_char(&uap->port, ch, regs)) | 163 | if (uart_handle_sysrq_char(&uap->port, ch & 255, regs)) |
164 | goto ignore_char; | 164 | goto ignore_char; |
165 | 165 | ||
166 | uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag); | 166 | uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag); |
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index ff5e6309d682..cc998b99a19f 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c | |||
@@ -361,7 +361,7 @@ static int serial_pxa_startup(struct uart_port *port) | |||
361 | if (port->line == 3) /* HWUART */ | 361 | if (port->line == 3) /* HWUART */ |
362 | up->mcr |= UART_MCR_AFE; | 362 | up->mcr |= UART_MCR_AFE; |
363 | else | 363 | else |
364 | up->mcr = 0; | 364 | up->mcr = 0; |
365 | 365 | ||
366 | /* | 366 | /* |
367 | * Allocate the IRQ | 367 | * Allocate the IRQ |
@@ -641,7 +641,7 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
641 | int i; | 641 | int i; |
642 | 642 | ||
643 | /* | 643 | /* |
644 | * First save the UER then disable the interrupts | 644 | * First save the IER then disable the interrupts |
645 | */ | 645 | */ |
646 | ier = serial_in(up, UART_IER); | 646 | ier = serial_in(up, UART_IER); |
647 | serial_out(up, UART_IER, UART_IER_UUE); | 647 | serial_out(up, UART_IER, UART_IER_UUE); |
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index a50c2bc506f2..3639c3f8d357 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
@@ -22,6 +22,7 @@ obj-$(CONFIG_USB_MIDI) += class/ | |||
22 | obj-$(CONFIG_USB_PRINTER) += class/ | 22 | obj-$(CONFIG_USB_PRINTER) += class/ |
23 | 23 | ||
24 | obj-$(CONFIG_USB_STORAGE) += storage/ | 24 | obj-$(CONFIG_USB_STORAGE) += storage/ |
25 | obj-$(CONFIG_USB) += storage/ | ||
25 | 26 | ||
26 | obj-$(CONFIG_USB_AIPTEK) += input/ | 27 | obj-$(CONFIG_USB_AIPTEK) += input/ |
27 | obj-$(CONFIG_USB_ATI_REMOTE) += input/ | 28 | obj-$(CONFIG_USB_ATI_REMOTE) += input/ |
diff --git a/drivers/usb/atm/Kconfig b/drivers/usb/atm/Kconfig index f429862e0974..550ddfa71a43 100644 --- a/drivers/usb/atm/Kconfig +++ b/drivers/usb/atm/Kconfig | |||
@@ -44,6 +44,19 @@ config USB_CXACRU | |||
44 | To compile this driver as a module, choose M here: the | 44 | To compile this driver as a module, choose M here: the |
45 | module will be called cxacru. | 45 | module will be called cxacru. |
46 | 46 | ||
47 | config USB_UEAGLEATM | ||
48 | tristate "ADI 930 and eagle USB DSL modem" | ||
49 | depends on USB_ATM | ||
50 | select FW_LOADER | ||
51 | help | ||
52 | Say Y here if you have an ADSL USB modem based on the ADI 930 | ||
53 | or eagle chipset. In order to use your modem you will need to | ||
54 | install firmwares and CMV (Command Management Variables); see | ||
55 | <https://gna.org/projects/ueagleatm/> for details. | ||
56 | |||
57 | To compile this driver as a module, choose M here: the | ||
58 | module will be called ueagle-atm. | ||
59 | |||
47 | config USB_XUSBATM | 60 | config USB_XUSBATM |
48 | tristate "Other USB DSL modem support" | 61 | tristate "Other USB DSL modem support" |
49 | depends on USB_ATM | 62 | depends on USB_ATM |
diff --git a/drivers/usb/atm/Makefile b/drivers/usb/atm/Makefile index 85099718c683..4c4a776ab1cd 100644 --- a/drivers/usb/atm/Makefile +++ b/drivers/usb/atm/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_USB_CXACRU) += cxacru.o | 5 | obj-$(CONFIG_USB_CXACRU) += cxacru.o |
6 | obj-$(CONFIG_USB_SPEEDTOUCH) += speedtch.o | 6 | obj-$(CONFIG_USB_SPEEDTOUCH) += speedtch.o |
7 | obj-$(CONFIG_USB_UEAGLEATM) += ueagle-atm.o | ||
7 | obj-$(CONFIG_USB_ATM) += usbatm.o | 8 | obj-$(CONFIG_USB_ATM) += usbatm.o |
8 | obj-$(CONFIG_USB_XUSBATM) += xusbatm.o | 9 | obj-$(CONFIG_USB_XUSBATM) += xusbatm.o |
9 | 10 | ||
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 9d59dc62e6d2..af0a41e7870e 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -853,7 +853,6 @@ static int cxacru_usb_probe(struct usb_interface *intf, const struct usb_device_ | |||
853 | } | 853 | } |
854 | 854 | ||
855 | static struct usb_driver cxacru_usb_driver = { | 855 | static struct usb_driver cxacru_usb_driver = { |
856 | .owner = THIS_MODULE, | ||
857 | .name = cxacru_driver_name, | 856 | .name = cxacru_driver_name, |
858 | .probe = cxacru_usb_probe, | 857 | .probe = cxacru_usb_probe, |
859 | .disconnect = usbatm_usb_disconnect, | 858 | .disconnect = usbatm_usb_disconnect, |
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index d0cbbb7f0385..b28336148658 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -659,7 +659,6 @@ MODULE_DEVICE_TABLE(usb, speedtch_usb_ids); | |||
659 | static int speedtch_usb_probe(struct usb_interface *, const struct usb_device_id *); | 659 | static int speedtch_usb_probe(struct usb_interface *, const struct usb_device_id *); |
660 | 660 | ||
661 | static struct usb_driver speedtch_usb_driver = { | 661 | static struct usb_driver speedtch_usb_driver = { |
662 | .owner = THIS_MODULE, | ||
663 | .name = speedtch_driver_name, | 662 | .name = speedtch_driver_name, |
664 | .probe = speedtch_usb_probe, | 663 | .probe = speedtch_usb_probe, |
665 | .disconnect = usbatm_usb_disconnect, | 664 | .disconnect = usbatm_usb_disconnect, |
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c new file mode 100644 index 000000000000..7d2a679989ed --- /dev/null +++ b/drivers/usb/atm/ueagle-atm.c | |||
@@ -0,0 +1,1820 @@ | |||
1 | /*- | ||
2 | * Copyright (c) 2003, 2004 | ||
3 | * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved. | ||
4 | * | ||
5 | * Copyright (c) 2005 Matthieu Castet <castet.matthieu@free.fr> | ||
6 | * | ||
7 | * This software is available to you under a choice of one of two | ||
8 | * licenses. You may choose to be licensed under the terms of the GNU | ||
9 | * General Public License (GPL) Version 2, available from the file | ||
10 | * COPYING in the main directory of this source tree, or the | ||
11 | * BSD license below: | ||
12 | * | ||
13 | * Redistribution and use in source and binary forms, with or without | ||
14 | * modification, are permitted provided that the following conditions | ||
15 | * are met: | ||
16 | * 1. Redistributions of source code must retain the above copyright | ||
17 | * notice unmodified, this list of conditions, and the following | ||
18 | * disclaimer. | ||
19 | * 2. Redistributions in binary form must reproduce the above copyright | ||
20 | * notice, this list of conditions and the following disclaimer in the | ||
21 | * documentation and/or other materials provided with the distribution. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
33 | * SUCH DAMAGE. | ||
34 | * | ||
35 | * GPL license : | ||
36 | * This program is free software; you can redistribute it and/or | ||
37 | * modify it under the terms of the GNU General Public License | ||
38 | * as published by the Free Software Foundation; either version 2 | ||
39 | * of the License, or (at your option) any later version. | ||
40 | * | ||
41 | * This program is distributed in the hope that it will be useful, | ||
42 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
43 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
44 | * GNU General Public License for more details. | ||
45 | * | ||
46 | * You should have received a copy of the GNU General Public License | ||
47 | * along with this program; if not, write to the Free Software | ||
48 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
49 | * | ||
50 | * | ||
51 | * HISTORY : some part of the code was base on ueagle 1.3 BSD driver, | ||
52 | * Damien Bergamini agree to put his code under a DUAL GPL/BSD license. | ||
53 | * | ||
54 | * The rest of the code was was rewritten from scratch. | ||
55 | */ | ||
56 | |||
57 | #include <linux/module.h> | ||
58 | #include <linux/moduleparam.h> | ||
59 | #include <linux/init.h> | ||
60 | #include <linux/crc32.h> | ||
61 | #include <linux/usb.h> | ||
62 | #include <linux/firmware.h> | ||
63 | #include <linux/ctype.h> | ||
64 | #include <linux/kthread.h> | ||
65 | #include <linux/version.h> | ||
66 | #include <asm/unaligned.h> | ||
67 | |||
68 | #include "usbatm.h" | ||
69 | |||
70 | #define EAGLEUSBVERSION "ueagle 1.1" | ||
71 | |||
72 | |||
73 | /* | ||
74 | * Debug macros | ||
75 | */ | ||
76 | #define uea_dbg(usb_dev, format, args...) \ | ||
77 | do { \ | ||
78 | if (debug >= 1) \ | ||
79 | dev_dbg(&(usb_dev)->dev, \ | ||
80 | "[ueagle-atm dbg] %s: " format, \ | ||
81 | __FUNCTION__, ##args); \ | ||
82 | } while (0) | ||
83 | |||
84 | #define uea_vdbg(usb_dev, format, args...) \ | ||
85 | do { \ | ||
86 | if (debug >= 2) \ | ||
87 | dev_dbg(&(usb_dev)->dev, \ | ||
88 | "[ueagle-atm vdbg] " format, ##args); \ | ||
89 | } while (0) | ||
90 | |||
91 | #define uea_enters(usb_dev) \ | ||
92 | uea_vdbg(usb_dev, "entering %s\n", __FUNCTION__) | ||
93 | |||
94 | #define uea_leaves(usb_dev) \ | ||
95 | uea_vdbg(usb_dev, "leaving %s\n", __FUNCTION__) | ||
96 | |||
97 | #define uea_err(usb_dev, format,args...) \ | ||
98 | dev_err(&(usb_dev)->dev ,"[UEAGLE-ATM] " format , ##args) | ||
99 | |||
100 | #define uea_warn(usb_dev, format,args...) \ | ||
101 | dev_warn(&(usb_dev)->dev ,"[Ueagle-atm] " format, ##args) | ||
102 | |||
103 | #define uea_info(usb_dev, format,args...) \ | ||
104 | dev_info(&(usb_dev)->dev ,"[ueagle-atm] " format, ##args) | ||
105 | |||
106 | struct uea_cmvs { | ||
107 | u32 address; | ||
108 | u16 offset; | ||
109 | u32 data; | ||
110 | } __attribute__ ((packed)); | ||
111 | |||
112 | struct uea_softc { | ||
113 | struct usb_device *usb_dev; | ||
114 | struct usbatm_data *usbatm; | ||
115 | |||
116 | int modem_index; | ||
117 | unsigned int driver_info; | ||
118 | |||
119 | int booting; | ||
120 | int reset; | ||
121 | |||
122 | wait_queue_head_t sync_q; | ||
123 | |||
124 | struct task_struct *kthread; | ||
125 | u32 data; | ||
126 | wait_queue_head_t cmv_ack_wait; | ||
127 | int cmv_ack; | ||
128 | |||
129 | struct work_struct task; | ||
130 | u16 pageno; | ||
131 | u16 ovl; | ||
132 | |||
133 | const struct firmware *dsp_firm; | ||
134 | struct urb *urb_int; | ||
135 | |||
136 | u8 cmv_function; | ||
137 | u16 cmv_idx; | ||
138 | u32 cmv_address; | ||
139 | u16 cmv_offset; | ||
140 | |||
141 | /* keep in sync with eaglectl */ | ||
142 | struct uea_stats { | ||
143 | struct { | ||
144 | u32 state; | ||
145 | u32 flags; | ||
146 | u32 mflags; | ||
147 | u32 vidcpe; | ||
148 | u32 vidco; | ||
149 | u32 dsrate; | ||
150 | u32 usrate; | ||
151 | u32 dsunc; | ||
152 | u32 usunc; | ||
153 | u32 dscorr; | ||
154 | u32 uscorr; | ||
155 | u32 txflow; | ||
156 | u32 rxflow; | ||
157 | u32 usattenuation; | ||
158 | u32 dsattenuation; | ||
159 | u32 dsmargin; | ||
160 | u32 usmargin; | ||
161 | u32 firmid; | ||
162 | } phy; | ||
163 | } stats; | ||
164 | }; | ||
165 | |||
166 | /* | ||
167 | * Elsa IDs | ||
168 | */ | ||
169 | #define ELSA_VID 0x05CC | ||
170 | #define ELSA_PID_PSTFIRM 0x3350 | ||
171 | #define ELSA_PID_PREFIRM 0x3351 | ||
172 | |||
173 | /* | ||
174 | * Sagem USB IDs | ||
175 | */ | ||
176 | #define EAGLE_VID 0x1110 | ||
177 | #define EAGLE_I_PID_PREFIRM 0x9010 /* Eagle I */ | ||
178 | #define EAGLE_I_PID_PSTFIRM 0x900F /* Eagle I */ | ||
179 | |||
180 | #define EAGLE_IIC_PID_PREFIRM 0x9024 /* Eagle IIC */ | ||
181 | #define EAGLE_IIC_PID_PSTFIRM 0x9023 /* Eagle IIC */ | ||
182 | |||
183 | #define EAGLE_II_PID_PREFIRM 0x9022 /* Eagle II */ | ||
184 | #define EAGLE_II_PID_PSTFIRM 0x9021 /* Eagle II */ | ||
185 | |||
186 | /* | ||
187 | * Eagle III Pid | ||
188 | */ | ||
189 | #define EAGLE_III_PID_PREFIRM 0x9032 /* Eagle III */ | ||
190 | #define EAGLE_III_PID_PSTFIRM 0x9031 /* Eagle III */ | ||
191 | |||
192 | /* | ||
193 | * USR USB IDs | ||
194 | */ | ||
195 | #define USR_VID 0x0BAF | ||
196 | #define MILLER_A_PID_PREFIRM 0x00F2 | ||
197 | #define MILLER_A_PID_PSTFIRM 0x00F1 | ||
198 | #define MILLER_B_PID_PREFIRM 0x00FA | ||
199 | #define MILLER_B_PID_PSTFIRM 0x00F9 | ||
200 | #define HEINEKEN_A_PID_PREFIRM 0x00F6 | ||
201 | #define HEINEKEN_A_PID_PSTFIRM 0x00F5 | ||
202 | #define HEINEKEN_B_PID_PREFIRM 0x00F8 | ||
203 | #define HEINEKEN_B_PID_PSTFIRM 0x00F7 | ||
204 | |||
205 | #define PREFIRM 0 | ||
206 | #define PSTFIRM (1<<7) | ||
207 | enum { | ||
208 | ADI930 = 0, | ||
209 | EAGLE_I, | ||
210 | EAGLE_II, | ||
211 | EAGLE_III | ||
212 | }; | ||
213 | |||
214 | /* macros for both struct usb_device_id and struct uea_softc */ | ||
215 | #define UEA_IS_PREFIRM(x) \ | ||
216 | (!((x)->driver_info & PSTFIRM)) | ||
217 | #define UEA_CHIP_VERSION(x) \ | ||
218 | ((x)->driver_info & 0xf) | ||
219 | |||
220 | #define IS_ISDN(sc) \ | ||
221 | (le16_to_cpu(sc->usb_dev->descriptor.bcdDevice) & 0x80) | ||
222 | |||
223 | #define INS_TO_USBDEV(ins) ins->usb_dev | ||
224 | |||
225 | #define GET_STATUS(data) \ | ||
226 | ((data >> 8) & 0xf) | ||
227 | #define IS_OPERATIONAL(sc) \ | ||
228 | (GET_STATUS(sc->stats.phy.state) == 2) | ||
229 | |||
230 | /* | ||
231 | * Set of macros to handle unaligned data in the firmware blob. | ||
232 | * The FW_GET_BYTE() macro is provided only for consistency. | ||
233 | */ | ||
234 | |||
235 | #define FW_GET_BYTE(p) *((__u8 *) (p)) | ||
236 | #define FW_GET_WORD(p) le16_to_cpu(get_unaligned((__le16 *) (p))) | ||
237 | #define FW_GET_LONG(p) le32_to_cpu(get_unaligned((__le32 *) (p))) | ||
238 | |||
239 | #define FW_DIR "ueagle-atm/" | ||
240 | #define NB_MODEM 4 | ||
241 | |||
242 | #define BULK_TIMEOUT 300 | ||
243 | #define CTRL_TIMEOUT 1000 | ||
244 | |||
245 | #define ACK_TIMEOUT msecs_to_jiffies(1500) | ||
246 | |||
247 | #define UEA_INTR_IFACE_NO 0 | ||
248 | #define UEA_US_IFACE_NO 1 | ||
249 | #define UEA_DS_IFACE_NO 2 | ||
250 | |||
251 | #define FASTEST_ISO_INTF 8 | ||
252 | |||
253 | #define UEA_BULK_DATA_PIPE 0x02 | ||
254 | #define UEA_IDMA_PIPE 0x04 | ||
255 | #define UEA_INTR_PIPE 0x04 | ||
256 | #define UEA_ISO_DATA_PIPE 0x08 | ||
257 | |||
258 | #define UEA_SET_BLOCK 0x0001 | ||
259 | #define UEA_SET_MODE 0x0003 | ||
260 | #define UEA_SET_2183_DATA 0x0004 | ||
261 | #define UEA_SET_TIMEOUT 0x0011 | ||
262 | |||
263 | #define UEA_LOOPBACK_OFF 0x0002 | ||
264 | #define UEA_LOOPBACK_ON 0x0003 | ||
265 | #define UEA_BOOT_IDMA 0x0006 | ||
266 | #define UEA_START_RESET 0x0007 | ||
267 | #define UEA_END_RESET 0x0008 | ||
268 | |||
269 | #define UEA_SWAP_MAILBOX (0x3fcd | 0x4000) | ||
270 | #define UEA_MPTX_START (0x3fce | 0x4000) | ||
271 | #define UEA_MPTX_MAILBOX (0x3fd6 | 0x4000) | ||
272 | #define UEA_MPRX_MAILBOX (0x3fdf | 0x4000) | ||
273 | |||
274 | /* structure describing a block within a DSP page */ | ||
275 | struct block_info { | ||
276 | __le16 wHdr; | ||
277 | #define UEA_BIHDR 0xabcd | ||
278 | __le16 wAddress; | ||
279 | __le16 wSize; | ||
280 | __le16 wOvlOffset; | ||
281 | __le16 wOvl; /* overlay */ | ||
282 | __le16 wLast; | ||
283 | } __attribute__ ((packed)); | ||
284 | #define BLOCK_INFO_SIZE 12 | ||
285 | |||
286 | /* structure representing a CMV (Configuration and Management Variable) */ | ||
287 | struct cmv { | ||
288 | __le16 wPreamble; | ||
289 | #define PREAMBLE 0x535c | ||
290 | __u8 bDirection; | ||
291 | #define MODEMTOHOST 0x01 | ||
292 | #define HOSTTOMODEM 0x10 | ||
293 | __u8 bFunction; | ||
294 | #define FUNCTION_TYPE(f) ((f) >> 4) | ||
295 | #define MEMACCESS 0x1 | ||
296 | #define ADSLDIRECTIVE 0x7 | ||
297 | |||
298 | #define FUNCTION_SUBTYPE(f) ((f) & 0x0f) | ||
299 | /* for MEMACCESS */ | ||
300 | #define REQUESTREAD 0x0 | ||
301 | #define REQUESTWRITE 0x1 | ||
302 | #define REPLYREAD 0x2 | ||
303 | #define REPLYWRITE 0x3 | ||
304 | /* for ADSLDIRECTIVE */ | ||
305 | #define KERNELREADY 0x0 | ||
306 | #define MODEMREADY 0x1 | ||
307 | |||
308 | #define MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf)) | ||
309 | __le16 wIndex; | ||
310 | __le32 dwSymbolicAddress; | ||
311 | #define MAKESA(a, b, c, d) \ | ||
312 | (((c) & 0xff) << 24 | \ | ||
313 | ((d) & 0xff) << 16 | \ | ||
314 | ((a) & 0xff) << 8 | \ | ||
315 | ((b) & 0xff)) | ||
316 | |||
317 | #define SA_CNTL MAKESA('C', 'N', 'T', 'L') | ||
318 | #define SA_DIAG MAKESA('D', 'I', 'A', 'G') | ||
319 | #define SA_INFO MAKESA('I', 'N', 'F', 'O') | ||
320 | #define SA_OPTN MAKESA('O', 'P', 'T', 'N') | ||
321 | #define SA_RATE MAKESA('R', 'A', 'T', 'E') | ||
322 | #define SA_STAT MAKESA('S', 'T', 'A', 'T') | ||
323 | __le16 wOffsetAddress; | ||
324 | __le32 dwData; | ||
325 | } __attribute__ ((packed)); | ||
326 | #define CMV_SIZE 16 | ||
327 | |||
328 | /* structure representing swap information */ | ||
329 | struct swap_info { | ||
330 | __u8 bSwapPageNo; | ||
331 | __u8 bOvl; /* overlay */ | ||
332 | } __attribute__ ((packed)); | ||
333 | |||
334 | /* structure representing interrupt data */ | ||
335 | struct intr_pkt { | ||
336 | __u8 bType; | ||
337 | __u8 bNotification; | ||
338 | __le16 wValue; | ||
339 | __le16 wIndex; | ||
340 | __le16 wLength; | ||
341 | __le16 wInterrupt; | ||
342 | #define INT_LOADSWAPPAGE 0x0001 | ||
343 | #define INT_INCOMINGCMV 0x0002 | ||
344 | union { | ||
345 | struct { | ||
346 | struct swap_info swapinfo; | ||
347 | __le16 wDataSize; | ||
348 | } __attribute__ ((packed)) s1; | ||
349 | |||
350 | struct { | ||
351 | struct cmv cmv; | ||
352 | __le16 wDataSize; | ||
353 | } __attribute__ ((packed)) s2; | ||
354 | } __attribute__ ((packed)) u; | ||
355 | #define bSwapPageNo u.s1.swapinfo.bSwapPageNo | ||
356 | #define bOvl u.s1.swapinfo.bOvl | ||
357 | } __attribute__ ((packed)); | ||
358 | #define INTR_PKT_SIZE 28 | ||
359 | |||
360 | static struct usb_driver uea_driver; | ||
361 | static DECLARE_MUTEX(uea_semaphore); | ||
362 | static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"}; | ||
363 | |||
364 | static int modem_index; | ||
365 | static unsigned int debug; | ||
366 | static int sync_wait[NB_MODEM]; | ||
367 | static char *cmv_file[NB_MODEM]; | ||
368 | |||
369 | module_param(debug, uint, 0644); | ||
370 | MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)"); | ||
371 | module_param_array(sync_wait, bool, NULL, 0644); | ||
372 | MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM"); | ||
373 | module_param_array(cmv_file, charp, NULL, 0644); | ||
374 | MODULE_PARM_DESC(cmv_file, | ||
375 | "file name with configuration and management variables"); | ||
376 | |||
377 | #define UPDATE_ATM_STAT(type, val) \ | ||
378 | do { \ | ||
379 | if (sc->usbatm->atm_dev) \ | ||
380 | sc->usbatm->atm_dev->type = val; \ | ||
381 | } while (0) | ||
382 | |||
383 | /* Firmware loading */ | ||
384 | #define LOAD_INTERNAL 0xA0 | ||
385 | #define F8051_USBCS 0x7f92 | ||
386 | |||
387 | /** | ||
388 | * uea_send_modem_cmd - Send a command for pre-firmware devices. | ||
389 | */ | ||
390 | static int uea_send_modem_cmd(struct usb_device *usb, | ||
391 | u16 addr, u16 size, u8 * buff) | ||
392 | { | ||
393 | int ret = -ENOMEM; | ||
394 | u8 *xfer_buff; | ||
395 | |||
396 | xfer_buff = kmalloc(size, GFP_KERNEL); | ||
397 | if (xfer_buff) { | ||
398 | memcpy(xfer_buff, buff, size); | ||
399 | ret = usb_control_msg(usb, | ||
400 | usb_sndctrlpipe(usb, 0), | ||
401 | LOAD_INTERNAL, | ||
402 | USB_DIR_OUT | USB_TYPE_VENDOR | | ||
403 | USB_RECIP_DEVICE, addr, 0, xfer_buff, | ||
404 | size, CTRL_TIMEOUT); | ||
405 | kfree(xfer_buff); | ||
406 | } | ||
407 | |||
408 | if (ret < 0) | ||
409 | return ret; | ||
410 | |||
411 | return (ret == size) ? 0 : -EIO; | ||
412 | } | ||
413 | |||
414 | static void uea_upload_pre_firmware(const struct firmware *fw_entry, void *context) | ||
415 | { | ||
416 | struct usb_device *usb = context; | ||
417 | u8 *pfw, value; | ||
418 | u32 crc = 0; | ||
419 | int ret, size; | ||
420 | |||
421 | uea_enters(usb); | ||
422 | if (!fw_entry) { | ||
423 | uea_err(usb, "firmware is not available\n"); | ||
424 | goto err; | ||
425 | } | ||
426 | |||
427 | pfw = fw_entry->data; | ||
428 | size = fw_entry->size; | ||
429 | if (size < 4) | ||
430 | goto err_fw_corrupted; | ||
431 | |||
432 | crc = FW_GET_LONG(pfw); | ||
433 | pfw += 4; | ||
434 | size -= 4; | ||
435 | if (crc32_be(0, pfw, size) != crc) | ||
436 | goto err_fw_corrupted; | ||
437 | |||
438 | /* | ||
439 | * Start to upload formware : send reset | ||
440 | */ | ||
441 | value = 1; | ||
442 | ret = uea_send_modem_cmd(usb, F8051_USBCS, sizeof(value), &value); | ||
443 | |||
444 | if (ret < 0) { | ||
445 | uea_err(usb, "modem reset failed with error %d\n", ret); | ||
446 | goto err; | ||
447 | } | ||
448 | |||
449 | while (size > 3) { | ||
450 | u8 len = FW_GET_BYTE(pfw); | ||
451 | u16 add = FW_GET_WORD(pfw + 1); | ||
452 | |||
453 | size -= len + 3; | ||
454 | if (size < 0) | ||
455 | goto err_fw_corrupted; | ||
456 | |||
457 | ret = uea_send_modem_cmd(usb, add, len, pfw + 3); | ||
458 | if (ret < 0) { | ||
459 | uea_err(usb, "uploading firmware data failed " | ||
460 | "with error %d\n", ret); | ||
461 | goto err; | ||
462 | } | ||
463 | pfw += len + 3; | ||
464 | } | ||
465 | |||
466 | if (size != 0) | ||
467 | goto err_fw_corrupted; | ||
468 | |||
469 | /* | ||
470 | * Tell the modem we finish : de-assert reset | ||
471 | */ | ||
472 | value = 0; | ||
473 | ret = uea_send_modem_cmd(usb, F8051_USBCS, 1, &value); | ||
474 | if (ret < 0) | ||
475 | uea_err(usb, "modem de-assert failed with error %d\n", ret); | ||
476 | else | ||
477 | uea_info(usb, "firmware uploaded\n"); | ||
478 | |||
479 | uea_leaves(usb); | ||
480 | return; | ||
481 | |||
482 | err_fw_corrupted: | ||
483 | uea_err(usb, "firmware is corrupted\n"); | ||
484 | err: | ||
485 | uea_leaves(usb); | ||
486 | } | ||
487 | |||
488 | /** | ||
489 | * uea_load_firmware - Load usb firmware for pre-firmware devices. | ||
490 | */ | ||
491 | static int uea_load_firmware(struct usb_device *usb, unsigned int ver) | ||
492 | { | ||
493 | int ret; | ||
494 | char *fw_name = FW_DIR "eagle.fw"; | ||
495 | |||
496 | uea_enters(usb); | ||
497 | uea_info(usb, "pre-firmware device, uploading firmware\n"); | ||
498 | |||
499 | switch (ver) { | ||
500 | case ADI930: | ||
501 | fw_name = FW_DIR "adi930.fw"; | ||
502 | break; | ||
503 | case EAGLE_I: | ||
504 | fw_name = FW_DIR "eagleI.fw"; | ||
505 | break; | ||
506 | case EAGLE_II: | ||
507 | fw_name = FW_DIR "eagleII.fw"; | ||
508 | break; | ||
509 | case EAGLE_III: | ||
510 | fw_name = FW_DIR "eagleIII.fw"; | ||
511 | break; | ||
512 | } | ||
513 | |||
514 | ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware); | ||
515 | if (ret) | ||
516 | uea_err(usb, "firmware %s is not available\n", fw_name); | ||
517 | else | ||
518 | uea_info(usb, "loading firmware %s\n", fw_name); | ||
519 | |||
520 | uea_leaves(usb); | ||
521 | return ret; | ||
522 | } | ||
523 | |||
524 | /* modem management : dsp firmware, send/read CMV, monitoring statistic | ||
525 | */ | ||
526 | |||
527 | /* | ||
528 | * Make sure that the DSP code provided is safe to use. | ||
529 | */ | ||
530 | static int check_dsp(u8 *dsp, unsigned int len) | ||
531 | { | ||
532 | u8 pagecount, blockcount; | ||
533 | u16 blocksize; | ||
534 | u32 pageoffset; | ||
535 | unsigned int i, j, p, pp; | ||
536 | |||
537 | pagecount = FW_GET_BYTE(dsp); | ||
538 | p = 1; | ||
539 | |||
540 | /* enough space for page offsets? */ | ||
541 | if (p + 4 * pagecount > len) | ||
542 | return 1; | ||
543 | |||
544 | for (i = 0; i < pagecount; i++) { | ||
545 | |||
546 | pageoffset = FW_GET_LONG(dsp + p); | ||
547 | p += 4; | ||
548 | |||
549 | if (pageoffset == 0) | ||
550 | continue; | ||
551 | |||
552 | /* enough space for blockcount? */ | ||
553 | if (pageoffset >= len) | ||
554 | return 1; | ||
555 | |||
556 | pp = pageoffset; | ||
557 | blockcount = FW_GET_BYTE(dsp + pp); | ||
558 | pp += 1; | ||
559 | |||
560 | for (j = 0; j < blockcount; j++) { | ||
561 | |||
562 | /* enough space for block header? */ | ||
563 | if (pp + 4 > len) | ||
564 | return 1; | ||
565 | |||
566 | pp += 2; /* skip blockaddr */ | ||
567 | blocksize = FW_GET_WORD(dsp + pp); | ||
568 | pp += 2; | ||
569 | |||
570 | /* enough space for block data? */ | ||
571 | if (pp + blocksize > len) | ||
572 | return 1; | ||
573 | |||
574 | pp += blocksize; | ||
575 | } | ||
576 | } | ||
577 | |||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | * send data to the idma pipe | ||
583 | * */ | ||
584 | static int uea_idma_write(struct uea_softc *sc, void *data, u32 size) | ||
585 | { | ||
586 | int ret = -ENOMEM; | ||
587 | u8 *xfer_buff; | ||
588 | int bytes_read; | ||
589 | |||
590 | xfer_buff = kmalloc(size, GFP_KERNEL); | ||
591 | if (!xfer_buff) { | ||
592 | uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n"); | ||
593 | return ret; | ||
594 | } | ||
595 | |||
596 | memcpy(xfer_buff, data, size); | ||
597 | |||
598 | ret = usb_bulk_msg(sc->usb_dev, | ||
599 | usb_sndbulkpipe(sc->usb_dev, UEA_IDMA_PIPE), | ||
600 | xfer_buff, size, &bytes_read, BULK_TIMEOUT); | ||
601 | |||
602 | kfree(xfer_buff); | ||
603 | if (ret < 0) | ||
604 | return ret; | ||
605 | if (size != bytes_read) { | ||
606 | uea_err(INS_TO_USBDEV(sc), "size != bytes_read %d %d\n", size, | ||
607 | bytes_read); | ||
608 | return -EIO; | ||
609 | } | ||
610 | |||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | static int request_dsp(struct uea_softc *sc) | ||
615 | { | ||
616 | int ret; | ||
617 | char *dsp_name; | ||
618 | |||
619 | if (UEA_CHIP_VERSION(sc) == ADI930) { | ||
620 | if (IS_ISDN(sc)) | ||
621 | dsp_name = FW_DIR "DSP9i.bin"; | ||
622 | else | ||
623 | dsp_name = FW_DIR "DSP9p.bin"; | ||
624 | } else { | ||
625 | if (IS_ISDN(sc)) | ||
626 | dsp_name = FW_DIR "DSPei.bin"; | ||
627 | else | ||
628 | dsp_name = FW_DIR "DSPep.bin"; | ||
629 | } | ||
630 | |||
631 | ret = request_firmware(&sc->dsp_firm, | ||
632 | dsp_name, &sc->usb_dev->dev); | ||
633 | if (ret < 0) { | ||
634 | uea_err(INS_TO_USBDEV(sc), | ||
635 | "requesting firmware %s failed with error %d\n", | ||
636 | dsp_name, ret); | ||
637 | return ret; | ||
638 | } | ||
639 | |||
640 | if (check_dsp(sc->dsp_firm->data, sc->dsp_firm->size)) { | ||
641 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", | ||
642 | dsp_name); | ||
643 | release_firmware(sc->dsp_firm); | ||
644 | sc->dsp_firm = NULL; | ||
645 | return -EILSEQ; | ||
646 | } | ||
647 | |||
648 | return 0; | ||
649 | } | ||
650 | |||
651 | /* | ||
652 | * The uea_load_page() function must be called within a process context | ||
653 | */ | ||
654 | static void uea_load_page(void *xsc) | ||
655 | { | ||
656 | struct uea_softc *sc = xsc; | ||
657 | u16 pageno = sc->pageno; | ||
658 | u16 ovl = sc->ovl; | ||
659 | struct block_info bi; | ||
660 | |||
661 | u8 *p; | ||
662 | u8 pagecount, blockcount; | ||
663 | u16 blockaddr, blocksize; | ||
664 | u32 pageoffset; | ||
665 | int i; | ||
666 | |||
667 | /* reload firmware when reboot start and it's loaded already */ | ||
668 | if (ovl == 0 && pageno == 0 && sc->dsp_firm) { | ||
669 | release_firmware(sc->dsp_firm); | ||
670 | sc->dsp_firm = NULL; | ||
671 | } | ||
672 | |||
673 | if (sc->dsp_firm == NULL && request_dsp(sc) < 0) | ||
674 | return; | ||
675 | |||
676 | p = sc->dsp_firm->data; | ||
677 | pagecount = FW_GET_BYTE(p); | ||
678 | p += 1; | ||
679 | |||
680 | if (pageno >= pagecount) | ||
681 | goto bad1; | ||
682 | |||
683 | p += 4 * pageno; | ||
684 | pageoffset = FW_GET_LONG(p); | ||
685 | |||
686 | if (pageoffset == 0) | ||
687 | goto bad1; | ||
688 | |||
689 | p = sc->dsp_firm->data + pageoffset; | ||
690 | blockcount = FW_GET_BYTE(p); | ||
691 | p += 1; | ||
692 | |||
693 | uea_dbg(INS_TO_USBDEV(sc), | ||
694 | "sending %u blocks for DSP page %u\n", blockcount, pageno); | ||
695 | |||
696 | bi.wHdr = cpu_to_le16(UEA_BIHDR); | ||
697 | bi.wOvl = cpu_to_le16(ovl); | ||
698 | bi.wOvlOffset = cpu_to_le16(ovl | 0x8000); | ||
699 | |||
700 | for (i = 0; i < blockcount; i++) { | ||
701 | blockaddr = FW_GET_WORD(p); | ||
702 | p += 2; | ||
703 | |||
704 | blocksize = FW_GET_WORD(p); | ||
705 | p += 2; | ||
706 | |||
707 | bi.wSize = cpu_to_le16(blocksize); | ||
708 | bi.wAddress = cpu_to_le16(blockaddr); | ||
709 | bi.wLast = cpu_to_le16((i == blockcount - 1) ? 1 : 0); | ||
710 | |||
711 | /* send block info through the IDMA pipe */ | ||
712 | if (uea_idma_write(sc, &bi, BLOCK_INFO_SIZE)) | ||
713 | goto bad2; | ||
714 | |||
715 | /* send block data through the IDMA pipe */ | ||
716 | if (uea_idma_write(sc, p, blocksize)) | ||
717 | goto bad2; | ||
718 | |||
719 | p += blocksize; | ||
720 | } | ||
721 | |||
722 | return; | ||
723 | |||
724 | bad2: | ||
725 | uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", i); | ||
726 | return; | ||
727 | bad1: | ||
728 | uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n",pageno); | ||
729 | } | ||
730 | |||
731 | static inline void wake_up_cmv_ack(struct uea_softc *sc) | ||
732 | { | ||
733 | sc->cmv_ack = 1; | ||
734 | wake_up(&sc->cmv_ack_wait); | ||
735 | } | ||
736 | |||
737 | static inline int wait_cmv_ack(struct uea_softc *sc) | ||
738 | { | ||
739 | int ret = wait_event_timeout(sc->cmv_ack_wait, | ||
740 | sc->cmv_ack, ACK_TIMEOUT); | ||
741 | sc->cmv_ack = 0; | ||
742 | |||
743 | if (ret < 0) | ||
744 | return ret; | ||
745 | |||
746 | return (ret == 0) ? -ETIMEDOUT : 0; | ||
747 | |||
748 | } | ||
749 | |||
750 | #define UCDC_SEND_ENCAPSULATED_COMMAND 0x00 | ||
751 | |||
752 | static int uea_request(struct uea_softc *sc, | ||
753 | u16 value, u16 index, u16 size, void *data) | ||
754 | { | ||
755 | u8 *xfer_buff; | ||
756 | int ret = -ENOMEM; | ||
757 | |||
758 | xfer_buff = kmalloc(size, GFP_KERNEL); | ||
759 | if (!xfer_buff) { | ||
760 | uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n"); | ||
761 | return ret; | ||
762 | } | ||
763 | memcpy(xfer_buff, data, size); | ||
764 | |||
765 | ret = usb_control_msg(sc->usb_dev, usb_sndctrlpipe(sc->usb_dev, 0), | ||
766 | UCDC_SEND_ENCAPSULATED_COMMAND, | ||
767 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
768 | value, index, xfer_buff, size, CTRL_TIMEOUT); | ||
769 | |||
770 | kfree(xfer_buff); | ||
771 | if (ret < 0) { | ||
772 | uea_err(INS_TO_USBDEV(sc), "usb_control_msg error %d\n", ret); | ||
773 | return ret; | ||
774 | } | ||
775 | |||
776 | if (ret != size) { | ||
777 | uea_err(INS_TO_USBDEV(sc), | ||
778 | "usb_control_msg send only %d bytes (instead of %d)\n", | ||
779 | ret, size); | ||
780 | return -EIO; | ||
781 | } | ||
782 | |||
783 | return 0; | ||
784 | } | ||
785 | |||
786 | static int uea_cmv(struct uea_softc *sc, | ||
787 | u8 function, u32 address, u16 offset, u32 data) | ||
788 | { | ||
789 | struct cmv cmv; | ||
790 | int ret; | ||
791 | |||
792 | /* we send a request, but we expect a reply */ | ||
793 | sc->cmv_function = function | 0x2; | ||
794 | sc->cmv_idx++; | ||
795 | sc->cmv_address = address; | ||
796 | sc->cmv_offset = offset; | ||
797 | |||
798 | cmv.wPreamble = cpu_to_le16(PREAMBLE); | ||
799 | cmv.bDirection = HOSTTOMODEM; | ||
800 | cmv.bFunction = function; | ||
801 | cmv.wIndex = cpu_to_le16(sc->cmv_idx); | ||
802 | put_unaligned(cpu_to_le32(address), &cmv.dwSymbolicAddress); | ||
803 | cmv.wOffsetAddress = cpu_to_le16(offset); | ||
804 | put_unaligned(cpu_to_le32(data >> 16 | data << 16), &cmv.dwData); | ||
805 | |||
806 | ret = uea_request(sc, UEA_SET_BLOCK, UEA_MPTX_START, CMV_SIZE, &cmv); | ||
807 | if (ret < 0) | ||
808 | return ret; | ||
809 | return wait_cmv_ack(sc); | ||
810 | } | ||
811 | |||
812 | static inline int uea_read_cmv(struct uea_softc *sc, | ||
813 | u32 address, u16 offset, u32 *data) | ||
814 | { | ||
815 | int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTREAD), | ||
816 | address, offset, 0); | ||
817 | if (ret < 0) | ||
818 | uea_err(INS_TO_USBDEV(sc), | ||
819 | "reading cmv failed with error %d\n", ret); | ||
820 | else | ||
821 | *data = sc->data; | ||
822 | |||
823 | return ret; | ||
824 | } | ||
825 | |||
826 | static inline int uea_write_cmv(struct uea_softc *sc, | ||
827 | u32 address, u16 offset, u32 data) | ||
828 | { | ||
829 | int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTWRITE), | ||
830 | address, offset, data); | ||
831 | if (ret < 0) | ||
832 | uea_err(INS_TO_USBDEV(sc), | ||
833 | "writing cmv failed with error %d\n", ret); | ||
834 | |||
835 | return ret; | ||
836 | } | ||
837 | |||
838 | /* | ||
839 | * Monitor the modem and update the stat | ||
840 | * return 0 if everything is ok | ||
841 | * return < 0 if an error occurs (-EAGAIN reboot needed) | ||
842 | */ | ||
843 | static int uea_stat(struct uea_softc *sc) | ||
844 | { | ||
845 | u32 data; | ||
846 | int ret; | ||
847 | |||
848 | uea_enters(INS_TO_USBDEV(sc)); | ||
849 | data = sc->stats.phy.state; | ||
850 | |||
851 | ret = uea_read_cmv(sc, SA_STAT, 0, &sc->stats.phy.state); | ||
852 | if (ret < 0) | ||
853 | return ret; | ||
854 | |||
855 | switch (GET_STATUS(sc->stats.phy.state)) { | ||
856 | case 0: /* not yet synchronized */ | ||
857 | uea_dbg(INS_TO_USBDEV(sc), | ||
858 | "modem not yet synchronized\n"); | ||
859 | return 0; | ||
860 | |||
861 | case 1: /* initialization */ | ||
862 | uea_dbg(INS_TO_USBDEV(sc), "modem initializing\n"); | ||
863 | return 0; | ||
864 | |||
865 | case 2: /* operational */ | ||
866 | uea_vdbg(INS_TO_USBDEV(sc), "modem operational\n"); | ||
867 | break; | ||
868 | |||
869 | case 3: /* fail ... */ | ||
870 | uea_info(INS_TO_USBDEV(sc), "modem synchronization failed\n"); | ||
871 | return -EAGAIN; | ||
872 | |||
873 | case 4 ... 6: /* test state */ | ||
874 | uea_warn(INS_TO_USBDEV(sc), | ||
875 | "modem in test mode - not supported\n"); | ||
876 | return -EAGAIN; | ||
877 | |||
878 | case 7: /* fast-retain ... */ | ||
879 | uea_info(INS_TO_USBDEV(sc), "modem in fast-retain mode\n"); | ||
880 | return 0; | ||
881 | default: | ||
882 | uea_err(INS_TO_USBDEV(sc), "modem invalid SW mode %d\n", | ||
883 | GET_STATUS(sc->stats.phy.state)); | ||
884 | return -EAGAIN; | ||
885 | } | ||
886 | |||
887 | if (GET_STATUS(data) != 2) { | ||
888 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_OFF, 0, NULL); | ||
889 | uea_info(INS_TO_USBDEV(sc), "modem operational\n"); | ||
890 | |||
891 | /* release the dsp firmware as it is not needed until | ||
892 | * the next failure | ||
893 | */ | ||
894 | if (sc->dsp_firm) { | ||
895 | release_firmware(sc->dsp_firm); | ||
896 | sc->dsp_firm = NULL; | ||
897 | } | ||
898 | |||
899 | ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid); | ||
900 | if (ret < 0) | ||
901 | return ret; | ||
902 | uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", | ||
903 | sc->stats.phy.firmid); | ||
904 | } | ||
905 | |||
906 | /* always update it as atm layer could not be init when we switch to | ||
907 | * operational state | ||
908 | */ | ||
909 | UPDATE_ATM_STAT(signal, ATM_PHY_SIG_FOUND); | ||
910 | |||
911 | /* wake up processes waiting for synchronization */ | ||
912 | wake_up(&sc->sync_q); | ||
913 | |||
914 | ret = uea_read_cmv(sc, SA_DIAG, 2, &sc->stats.phy.flags); | ||
915 | if (ret < 0) | ||
916 | return ret; | ||
917 | sc->stats.phy.mflags |= sc->stats.phy.flags; | ||
918 | |||
919 | /* in case of a flags ( for example delineation LOSS (& 0x10)), | ||
920 | * we check the status again in order to detect the failure earlier | ||
921 | */ | ||
922 | if (sc->stats.phy.flags) { | ||
923 | uea_dbg(INS_TO_USBDEV(sc), "Stat flag = %d\n", | ||
924 | sc->stats.phy.flags); | ||
925 | return 0; | ||
926 | } | ||
927 | |||
928 | ret = uea_read_cmv(sc, SA_RATE, 0, &data); | ||
929 | if (ret < 0) | ||
930 | return ret; | ||
931 | |||
932 | /* in bulk mode the modem have problem with high rate | ||
933 | * changing internal timing could improve things, but the | ||
934 | * value is misterious. | ||
935 | * ADI930 don't support it (-EPIPE error). | ||
936 | */ | ||
937 | if (UEA_CHIP_VERSION(sc) != ADI930 | ||
938 | && sc->stats.phy.dsrate != (data >> 16) * 32) { | ||
939 | /* Original timming from ADI(used in windows driver) | ||
940 | * 0x20ffff>>16 * 32 = 32 * 32 = 1Mbits | ||
941 | */ | ||
942 | u16 timeout = (data <= 0x20ffff) ? 0 : 1; | ||
943 | ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL); | ||
944 | uea_info(INS_TO_USBDEV(sc), | ||
945 | "setting new timeout %d%s\n", timeout, | ||
946 | ret < 0?" failed":""); | ||
947 | } | ||
948 | sc->stats.phy.dsrate = (data >> 16) * 32; | ||
949 | sc->stats.phy.usrate = (data & 0xffff) * 32; | ||
950 | UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424); | ||
951 | |||
952 | ret = uea_read_cmv(sc, SA_DIAG, 23, &data); | ||
953 | if (ret < 0) | ||
954 | return ret; | ||
955 | sc->stats.phy.dsattenuation = (data & 0xff) / 2; | ||
956 | |||
957 | ret = uea_read_cmv(sc, SA_DIAG, 47, &data); | ||
958 | if (ret < 0) | ||
959 | return ret; | ||
960 | sc->stats.phy.usattenuation = (data & 0xff) / 2; | ||
961 | |||
962 | ret = uea_read_cmv(sc, SA_DIAG, 25, &sc->stats.phy.dsmargin); | ||
963 | if (ret < 0) | ||
964 | return ret; | ||
965 | |||
966 | ret = uea_read_cmv(sc, SA_DIAG, 49, &sc->stats.phy.usmargin); | ||
967 | if (ret < 0) | ||
968 | return ret; | ||
969 | |||
970 | ret = uea_read_cmv(sc, SA_DIAG, 51, &sc->stats.phy.rxflow); | ||
971 | if (ret < 0) | ||
972 | return ret; | ||
973 | |||
974 | ret = uea_read_cmv(sc, SA_DIAG, 52, &sc->stats.phy.txflow); | ||
975 | if (ret < 0) | ||
976 | return ret; | ||
977 | |||
978 | ret = uea_read_cmv(sc, SA_DIAG, 54, &sc->stats.phy.dsunc); | ||
979 | if (ret < 0) | ||
980 | return ret; | ||
981 | |||
982 | /* only for atu-c */ | ||
983 | ret = uea_read_cmv(sc, SA_DIAG, 58, &sc->stats.phy.usunc); | ||
984 | if (ret < 0) | ||
985 | return ret; | ||
986 | |||
987 | ret = uea_read_cmv(sc, SA_DIAG, 53, &sc->stats.phy.dscorr); | ||
988 | if (ret < 0) | ||
989 | return ret; | ||
990 | |||
991 | /* only for atu-c */ | ||
992 | ret = uea_read_cmv(sc, SA_DIAG, 57, &sc->stats.phy.uscorr); | ||
993 | if (ret < 0) | ||
994 | return ret; | ||
995 | |||
996 | ret = uea_read_cmv(sc, SA_INFO, 8, &sc->stats.phy.vidco); | ||
997 | if (ret < 0) | ||
998 | return ret; | ||
999 | |||
1000 | ret = uea_read_cmv(sc, SA_INFO, 13, &sc->stats.phy.vidcpe); | ||
1001 | if (ret < 0) | ||
1002 | return ret; | ||
1003 | |||
1004 | return 0; | ||
1005 | } | ||
1006 | |||
1007 | static int request_cmvs(struct uea_softc *sc, | ||
1008 | struct uea_cmvs **cmvs, const struct firmware **fw) | ||
1009 | { | ||
1010 | int ret, size; | ||
1011 | u8 *data; | ||
1012 | char *file; | ||
1013 | static char cmv_name[256] = FW_DIR; | ||
1014 | |||
1015 | if (cmv_file[sc->modem_index] == NULL) { | ||
1016 | if (UEA_CHIP_VERSION(sc) == ADI930) | ||
1017 | file = (IS_ISDN(sc)) ? "CMV9i.bin" : "CMV9p.bin"; | ||
1018 | else | ||
1019 | file = (IS_ISDN(sc)) ? "CMVei.bin" : "CMVep.bin"; | ||
1020 | } else | ||
1021 | file = cmv_file[sc->modem_index]; | ||
1022 | |||
1023 | strcpy(cmv_name, FW_DIR); | ||
1024 | strlcat(cmv_name, file, sizeof(cmv_name)); | ||
1025 | |||
1026 | ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev); | ||
1027 | if (ret < 0) { | ||
1028 | uea_err(INS_TO_USBDEV(sc), | ||
1029 | "requesting firmware %s failed with error %d\n", | ||
1030 | cmv_name, ret); | ||
1031 | return ret; | ||
1032 | } | ||
1033 | |||
1034 | data = (u8 *) (*fw)->data; | ||
1035 | size = *data * sizeof(struct uea_cmvs) + 1; | ||
1036 | if (size != (*fw)->size) { | ||
1037 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", | ||
1038 | cmv_name); | ||
1039 | release_firmware(*fw); | ||
1040 | return -EILSEQ; | ||
1041 | } | ||
1042 | |||
1043 | *cmvs = (struct uea_cmvs *)(data + 1); | ||
1044 | return *data; | ||
1045 | } | ||
1046 | |||
1047 | /* Start boot post firmware modem: | ||
1048 | * - send reset commands through usb control pipe | ||
1049 | * - start workqueue for DSP loading | ||
1050 | * - send CMV options to modem | ||
1051 | */ | ||
1052 | |||
1053 | static int uea_start_reset(struct uea_softc *sc) | ||
1054 | { | ||
1055 | u16 zero = 0; /* ;-) */ | ||
1056 | int i, len, ret; | ||
1057 | struct uea_cmvs *cmvs; | ||
1058 | const struct firmware *cmvs_fw; | ||
1059 | |||
1060 | uea_enters(INS_TO_USBDEV(sc)); | ||
1061 | uea_info(INS_TO_USBDEV(sc), "(re)booting started\n"); | ||
1062 | |||
1063 | sc->booting = 1; | ||
1064 | UPDATE_ATM_STAT(signal, ATM_PHY_SIG_LOST); | ||
1065 | |||
1066 | /* reset statistics */ | ||
1067 | memset(&sc->stats, 0, sizeof(struct uea_stats)); | ||
1068 | |||
1069 | /* tell the modem that we want to boot in IDMA mode */ | ||
1070 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL); | ||
1071 | uea_request(sc, UEA_SET_MODE, UEA_BOOT_IDMA, 0, NULL); | ||
1072 | |||
1073 | /* enter reset mode */ | ||
1074 | uea_request(sc, UEA_SET_MODE, UEA_START_RESET, 0, NULL); | ||
1075 | |||
1076 | /* original driver use 200ms, but windows driver use 100ms */ | ||
1077 | msleep(100); | ||
1078 | |||
1079 | /* leave reset mode */ | ||
1080 | uea_request(sc, UEA_SET_MODE, UEA_END_RESET, 0, NULL); | ||
1081 | |||
1082 | /* clear tx and rx mailboxes */ | ||
1083 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPTX_MAILBOX, 2, &zero); | ||
1084 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPRX_MAILBOX, 2, &zero); | ||
1085 | uea_request(sc, UEA_SET_2183_DATA, UEA_SWAP_MAILBOX, 2, &zero); | ||
1086 | |||
1087 | msleep(1000); | ||
1088 | sc->cmv_function = MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY); | ||
1089 | sc->booting = 0; | ||
1090 | |||
1091 | /* start loading DSP */ | ||
1092 | sc->pageno = 0; | ||
1093 | sc->ovl = 0; | ||
1094 | schedule_work(&sc->task); | ||
1095 | |||
1096 | /* wait for modem ready CMV */ | ||
1097 | ret = wait_cmv_ack(sc); | ||
1098 | if (ret < 0) | ||
1099 | return ret; | ||
1100 | |||
1101 | /* Enter in R-IDLE (cmv) until instructed otherwise */ | ||
1102 | ret = uea_write_cmv(sc, SA_CNTL, 0, 1); | ||
1103 | if (ret < 0) | ||
1104 | return ret; | ||
1105 | |||
1106 | /* get options */ | ||
1107 | ret = len = request_cmvs(sc, &cmvs, &cmvs_fw); | ||
1108 | if (ret < 0) | ||
1109 | return ret; | ||
1110 | |||
1111 | /* send options */ | ||
1112 | for (i = 0; i < len; i++) { | ||
1113 | ret = uea_write_cmv(sc, FW_GET_LONG(&cmvs[i].address), | ||
1114 | FW_GET_WORD(&cmvs[i].offset), | ||
1115 | FW_GET_LONG(&cmvs[i].data)); | ||
1116 | if (ret < 0) | ||
1117 | goto out; | ||
1118 | } | ||
1119 | /* Enter in R-ACT-REQ */ | ||
1120 | ret = uea_write_cmv(sc, SA_CNTL, 0, 2); | ||
1121 | out: | ||
1122 | release_firmware(cmvs_fw); | ||
1123 | sc->reset = 0; | ||
1124 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1125 | return ret; | ||
1126 | } | ||
1127 | |||
1128 | /* | ||
1129 | * In case of an error wait 1s before rebooting the modem | ||
1130 | * if the modem don't request reboot (-EAGAIN). | ||
1131 | * Monitor the modem every 1s. | ||
1132 | */ | ||
1133 | |||
1134 | static int uea_kthread(void *data) | ||
1135 | { | ||
1136 | struct uea_softc *sc = data; | ||
1137 | int ret = -EAGAIN; | ||
1138 | |||
1139 | uea_enters(INS_TO_USBDEV(sc)); | ||
1140 | while (!kthread_should_stop()) { | ||
1141 | if (ret < 0 || sc->reset) | ||
1142 | ret = uea_start_reset(sc); | ||
1143 | if (!ret) | ||
1144 | ret = uea_stat(sc); | ||
1145 | if (ret != -EAGAIN) | ||
1146 | msleep(1000); | ||
1147 | } | ||
1148 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1149 | return ret; | ||
1150 | } | ||
1151 | |||
1152 | /* Load second usb firmware for ADI930 chip */ | ||
1153 | static int load_XILINX_firmware(struct uea_softc *sc) | ||
1154 | { | ||
1155 | const struct firmware *fw_entry; | ||
1156 | int ret, size, u, ln; | ||
1157 | u8 *pfw, value; | ||
1158 | char *fw_name = FW_DIR "930-fpga.bin"; | ||
1159 | |||
1160 | uea_enters(INS_TO_USBDEV(sc)); | ||
1161 | |||
1162 | ret = request_firmware(&fw_entry, fw_name, &sc->usb_dev->dev); | ||
1163 | if (ret) { | ||
1164 | uea_err(INS_TO_USBDEV(sc), "firmware %s is not available\n", | ||
1165 | fw_name); | ||
1166 | goto err0; | ||
1167 | } | ||
1168 | |||
1169 | pfw = fw_entry->data; | ||
1170 | size = fw_entry->size; | ||
1171 | if (size != 0x577B) { | ||
1172 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", | ||
1173 | fw_name); | ||
1174 | ret = -EILSEQ; | ||
1175 | goto err1; | ||
1176 | } | ||
1177 | for (u = 0; u < size; u += ln) { | ||
1178 | ln = min(size - u, 64); | ||
1179 | ret = uea_request(sc, 0xe, 0, ln, pfw + u); | ||
1180 | if (ret < 0) { | ||
1181 | uea_err(INS_TO_USBDEV(sc), | ||
1182 | "elsa download data failed (%d)\n", ret); | ||
1183 | goto err1; | ||
1184 | } | ||
1185 | } | ||
1186 | |||
1187 | /* finish to send the fpga | ||
1188 | */ | ||
1189 | ret = uea_request(sc, 0xe, 1, 0, NULL); | ||
1190 | if (ret < 0) { | ||
1191 | uea_err(INS_TO_USBDEV(sc), | ||
1192 | "elsa download data failed (%d)\n", ret); | ||
1193 | goto err1; | ||
1194 | } | ||
1195 | |||
1196 | /* | ||
1197 | * Tell the modem we finish : de-assert reset | ||
1198 | */ | ||
1199 | value = 0; | ||
1200 | ret = uea_send_modem_cmd(sc->usb_dev, 0xe, 1, &value); | ||
1201 | if (ret < 0) | ||
1202 | uea_err(sc->usb_dev, "elsa de-assert failed with error %d\n", ret); | ||
1203 | |||
1204 | |||
1205 | err1: | ||
1206 | release_firmware(fw_entry); | ||
1207 | err0: | ||
1208 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1209 | return ret; | ||
1210 | } | ||
1211 | |||
1212 | static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) | ||
1213 | { | ||
1214 | uea_enters(INS_TO_USBDEV(sc)); | ||
1215 | if (le16_to_cpu(cmv->wPreamble) != PREAMBLE) | ||
1216 | goto bad1; | ||
1217 | |||
1218 | if (cmv->bDirection != MODEMTOHOST) | ||
1219 | goto bad1; | ||
1220 | |||
1221 | /* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to | ||
1222 | * the first MEMACESS cmv. Ignore it... | ||
1223 | */ | ||
1224 | if (cmv->bFunction != sc->cmv_function) { | ||
1225 | if (UEA_CHIP_VERSION(sc) == ADI930 | ||
1226 | && cmv->bFunction == MAKEFUNCTION(2, 2)) { | ||
1227 | cmv->wIndex = cpu_to_le16(sc->cmv_idx); | ||
1228 | put_unaligned(cpu_to_le32(sc->cmv_address), &cmv->dwSymbolicAddress); | ||
1229 | cmv->wOffsetAddress = cpu_to_le16(sc->cmv_offset); | ||
1230 | } | ||
1231 | else | ||
1232 | goto bad2; | ||
1233 | } | ||
1234 | |||
1235 | if (cmv->bFunction == MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY)) { | ||
1236 | wake_up_cmv_ack(sc); | ||
1237 | return; | ||
1238 | } | ||
1239 | |||
1240 | /* in case of MEMACCESS */ | ||
1241 | if (le16_to_cpu(cmv->wIndex) != sc->cmv_idx || | ||
1242 | le32_to_cpu(get_unaligned(&cmv->dwSymbolicAddress)) != | ||
1243 | sc->cmv_address | ||
1244 | || le16_to_cpu(cmv->wOffsetAddress) != sc->cmv_offset) | ||
1245 | goto bad2; | ||
1246 | |||
1247 | sc->data = le32_to_cpu(get_unaligned(&cmv->dwData)); | ||
1248 | sc->data = sc->data << 16 | sc->data >> 16; | ||
1249 | |||
1250 | wake_up_cmv_ack(sc); | ||
1251 | return; | ||
1252 | |||
1253 | bad2: | ||
1254 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received," | ||
1255 | "Function : %d, Subfunction : %d\n", | ||
1256 | FUNCTION_TYPE(cmv->bFunction), | ||
1257 | FUNCTION_SUBTYPE(cmv->bFunction)); | ||
1258 | return; | ||
1259 | |||
1260 | bad1: | ||
1261 | uea_err(INS_TO_USBDEV(sc), "invalid cmv received, " | ||
1262 | "wPreamble %d, bDirection %d\n", | ||
1263 | le16_to_cpu(cmv->wPreamble), cmv->bDirection); | ||
1264 | } | ||
1265 | |||
1266 | /* | ||
1267 | * interrupt handler | ||
1268 | */ | ||
1269 | static void uea_intr(struct urb *urb, struct pt_regs *regs) | ||
1270 | { | ||
1271 | struct uea_softc *sc = (struct uea_softc *)urb->context; | ||
1272 | struct intr_pkt *intr; | ||
1273 | uea_enters(INS_TO_USBDEV(sc)); | ||
1274 | |||
1275 | if (urb->status < 0) { | ||
1276 | uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n", | ||
1277 | urb->status); | ||
1278 | return; | ||
1279 | } | ||
1280 | |||
1281 | intr = (struct intr_pkt *) urb->transfer_buffer; | ||
1282 | |||
1283 | /* device-to-host interrupt */ | ||
1284 | if (intr->bType != 0x08 || sc->booting) { | ||
1285 | uea_err(INS_TO_USBDEV(sc), "wrong intr\n"); | ||
1286 | // rebooting ? | ||
1287 | // sc->reset = 1; | ||
1288 | goto resubmit; | ||
1289 | } | ||
1290 | |||
1291 | switch (le16_to_cpu(intr->wInterrupt)) { | ||
1292 | case INT_LOADSWAPPAGE: | ||
1293 | sc->pageno = intr->bSwapPageNo; | ||
1294 | sc->ovl = intr->bOvl >> 4 | intr->bOvl << 4; | ||
1295 | schedule_work(&sc->task); | ||
1296 | break; | ||
1297 | |||
1298 | case INT_INCOMINGCMV: | ||
1299 | uea_dispatch_cmv(sc, &intr->u.s2.cmv); | ||
1300 | break; | ||
1301 | |||
1302 | default: | ||
1303 | uea_err(INS_TO_USBDEV(sc), "unknown intr %u\n", | ||
1304 | le16_to_cpu(intr->wInterrupt)); | ||
1305 | } | ||
1306 | |||
1307 | resubmit: | ||
1308 | usb_submit_urb(sc->urb_int, GFP_ATOMIC); | ||
1309 | } | ||
1310 | |||
1311 | /* | ||
1312 | * Start the modem : init the data and start kernel thread | ||
1313 | */ | ||
1314 | static int uea_boot(struct uea_softc *sc) | ||
1315 | { | ||
1316 | int ret; | ||
1317 | struct intr_pkt *intr; | ||
1318 | |||
1319 | uea_enters(INS_TO_USBDEV(sc)); | ||
1320 | |||
1321 | INIT_WORK(&sc->task, uea_load_page, sc); | ||
1322 | init_waitqueue_head(&sc->sync_q); | ||
1323 | init_waitqueue_head(&sc->cmv_ack_wait); | ||
1324 | |||
1325 | if (UEA_CHIP_VERSION(sc) == ADI930) | ||
1326 | load_XILINX_firmware(sc); | ||
1327 | |||
1328 | intr = kmalloc(INTR_PKT_SIZE, GFP_KERNEL); | ||
1329 | if (!intr) { | ||
1330 | uea_err(INS_TO_USBDEV(sc), | ||
1331 | "cannot allocate interrupt package\n"); | ||
1332 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1333 | return -ENOMEM; | ||
1334 | } | ||
1335 | |||
1336 | sc->urb_int = usb_alloc_urb(0, GFP_KERNEL); | ||
1337 | if (!sc->urb_int) { | ||
1338 | uea_err(INS_TO_USBDEV(sc), "cannot allocate interrupt URB\n"); | ||
1339 | goto err; | ||
1340 | } | ||
1341 | |||
1342 | usb_fill_int_urb(sc->urb_int, sc->usb_dev, | ||
1343 | usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE), | ||
1344 | intr, INTR_PKT_SIZE, uea_intr, sc, | ||
1345 | sc->usb_dev->actconfig->interface[0]->altsetting[0]. | ||
1346 | endpoint[0].desc.bInterval); | ||
1347 | |||
1348 | ret = usb_submit_urb(sc->urb_int, GFP_KERNEL); | ||
1349 | if (ret < 0) { | ||
1350 | uea_err(INS_TO_USBDEV(sc), | ||
1351 | "urb submition failed with error %d\n", ret); | ||
1352 | goto err1; | ||
1353 | } | ||
1354 | |||
1355 | sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); | ||
1356 | if (sc->kthread == ERR_PTR(-ENOMEM)) { | ||
1357 | uea_err(INS_TO_USBDEV(sc), "failed to create thread\n"); | ||
1358 | goto err2; | ||
1359 | } | ||
1360 | |||
1361 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1362 | return 0; | ||
1363 | |||
1364 | err2: | ||
1365 | usb_kill_urb(sc->urb_int); | ||
1366 | err1: | ||
1367 | kfree(intr); | ||
1368 | err: | ||
1369 | usb_free_urb(sc->urb_int); | ||
1370 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1371 | return -ENOMEM; | ||
1372 | } | ||
1373 | |||
1374 | /* | ||
1375 | * Stop the modem : kill kernel thread and free data | ||
1376 | */ | ||
1377 | static void uea_stop(struct uea_softc *sc) | ||
1378 | { | ||
1379 | int ret; | ||
1380 | uea_enters(INS_TO_USBDEV(sc)); | ||
1381 | ret = kthread_stop(sc->kthread); | ||
1382 | uea_info(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret); | ||
1383 | |||
1384 | /* stop any pending boot process */ | ||
1385 | flush_scheduled_work(); | ||
1386 | |||
1387 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL); | ||
1388 | |||
1389 | usb_kill_urb(sc->urb_int); | ||
1390 | kfree(sc->urb_int->transfer_buffer); | ||
1391 | usb_free_urb(sc->urb_int); | ||
1392 | |||
1393 | if (sc->dsp_firm) | ||
1394 | release_firmware(sc->dsp_firm); | ||
1395 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1396 | } | ||
1397 | |||
1398 | /* syfs interface */ | ||
1399 | static struct uea_softc *dev_to_uea(struct device *dev) | ||
1400 | { | ||
1401 | struct usb_interface *intf; | ||
1402 | struct usbatm_data *usbatm; | ||
1403 | |||
1404 | intf = to_usb_interface(dev); | ||
1405 | if (!intf) | ||
1406 | return NULL; | ||
1407 | |||
1408 | usbatm = usb_get_intfdata(intf); | ||
1409 | if (!usbatm) | ||
1410 | return NULL; | ||
1411 | |||
1412 | return usbatm->driver_data; | ||
1413 | } | ||
1414 | |||
1415 | static ssize_t read_status(struct device *dev, struct device_attribute *attr, | ||
1416 | char *buf) | ||
1417 | { | ||
1418 | int ret = -ENODEV; | ||
1419 | struct uea_softc *sc; | ||
1420 | |||
1421 | down(&uea_semaphore); | ||
1422 | sc = dev_to_uea(dev); | ||
1423 | if (!sc) | ||
1424 | goto out; | ||
1425 | ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.state); | ||
1426 | out: | ||
1427 | up(&uea_semaphore); | ||
1428 | return ret; | ||
1429 | } | ||
1430 | |||
1431 | static ssize_t reboot(struct device *dev, struct device_attribute *attr, | ||
1432 | const char *buf, size_t count) | ||
1433 | { | ||
1434 | int ret = -ENODEV; | ||
1435 | struct uea_softc *sc; | ||
1436 | |||
1437 | down(&uea_semaphore); | ||
1438 | sc = dev_to_uea(dev); | ||
1439 | if (!sc) | ||
1440 | goto out; | ||
1441 | sc->reset = 1; | ||
1442 | ret = count; | ||
1443 | out: | ||
1444 | up(&uea_semaphore); | ||
1445 | return ret; | ||
1446 | } | ||
1447 | |||
1448 | static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot); | ||
1449 | |||
1450 | static ssize_t read_human_status(struct device *dev, struct device_attribute *attr, | ||
1451 | char *buf) | ||
1452 | { | ||
1453 | int ret = -ENODEV; | ||
1454 | struct uea_softc *sc; | ||
1455 | |||
1456 | down(&uea_semaphore); | ||
1457 | sc = dev_to_uea(dev); | ||
1458 | if (!sc) | ||
1459 | goto out; | ||
1460 | |||
1461 | switch (GET_STATUS(sc->stats.phy.state)) { | ||
1462 | case 0: | ||
1463 | ret = sprintf(buf, "Modem is booting\n"); | ||
1464 | break; | ||
1465 | case 1: | ||
1466 | ret = sprintf(buf, "Modem is initializing\n"); | ||
1467 | break; | ||
1468 | case 2: | ||
1469 | ret = sprintf(buf, "Modem is operational\n"); | ||
1470 | break; | ||
1471 | default: | ||
1472 | ret = sprintf(buf, "Modem synchronization failed\n"); | ||
1473 | break; | ||
1474 | } | ||
1475 | out: | ||
1476 | up(&uea_semaphore); | ||
1477 | return ret; | ||
1478 | } | ||
1479 | |||
1480 | static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO, read_human_status, NULL); | ||
1481 | |||
1482 | static ssize_t read_delin(struct device *dev, struct device_attribute *attr, | ||
1483 | char *buf) | ||
1484 | { | ||
1485 | int ret = -ENODEV; | ||
1486 | struct uea_softc *sc; | ||
1487 | |||
1488 | down(&uea_semaphore); | ||
1489 | sc = dev_to_uea(dev); | ||
1490 | if (!sc) | ||
1491 | goto out; | ||
1492 | |||
1493 | if (sc->stats.phy.flags & 0x0C00) | ||
1494 | ret = sprintf(buf, "ERROR\n"); | ||
1495 | else if (sc->stats.phy.flags & 0x0030) | ||
1496 | ret = sprintf(buf, "LOSS\n"); | ||
1497 | else | ||
1498 | ret = sprintf(buf, "GOOD\n"); | ||
1499 | out: | ||
1500 | up(&uea_semaphore); | ||
1501 | return ret; | ||
1502 | } | ||
1503 | |||
1504 | static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL); | ||
1505 | |||
1506 | #define UEA_ATTR(name, reset) \ | ||
1507 | \ | ||
1508 | static ssize_t read_##name(struct device *dev, \ | ||
1509 | struct device_attribute *attr, char *buf) \ | ||
1510 | { \ | ||
1511 | int ret = -ENODEV; \ | ||
1512 | struct uea_softc *sc; \ | ||
1513 | \ | ||
1514 | down(&uea_semaphore); \ | ||
1515 | sc = dev_to_uea(dev); \ | ||
1516 | if (!sc) \ | ||
1517 | goto out; \ | ||
1518 | ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.name); \ | ||
1519 | if (reset) \ | ||
1520 | sc->stats.phy.name = 0; \ | ||
1521 | out: \ | ||
1522 | up(&uea_semaphore); \ | ||
1523 | return ret; \ | ||
1524 | } \ | ||
1525 | \ | ||
1526 | static DEVICE_ATTR(stat_##name, S_IRUGO, read_##name, NULL) | ||
1527 | |||
1528 | UEA_ATTR(mflags, 1); | ||
1529 | UEA_ATTR(vidcpe, 0); | ||
1530 | UEA_ATTR(usrate, 0); | ||
1531 | UEA_ATTR(dsrate, 0); | ||
1532 | UEA_ATTR(usattenuation, 0); | ||
1533 | UEA_ATTR(dsattenuation, 0); | ||
1534 | UEA_ATTR(usmargin, 0); | ||
1535 | UEA_ATTR(dsmargin, 0); | ||
1536 | UEA_ATTR(txflow, 0); | ||
1537 | UEA_ATTR(rxflow, 0); | ||
1538 | UEA_ATTR(uscorr, 0); | ||
1539 | UEA_ATTR(dscorr, 0); | ||
1540 | UEA_ATTR(usunc, 0); | ||
1541 | UEA_ATTR(dsunc, 0); | ||
1542 | |||
1543 | /* Retrieve the device End System Identifier (MAC) */ | ||
1544 | |||
1545 | #define htoi(x) (isdigit(x) ? x-'0' : toupper(x)-'A'+10) | ||
1546 | static int uea_getesi(struct uea_softc *sc, u_char * esi) | ||
1547 | { | ||
1548 | unsigned char mac_str[2 * ETH_ALEN + 1]; | ||
1549 | int i; | ||
1550 | if (usb_string | ||
1551 | (sc->usb_dev, sc->usb_dev->descriptor.iSerialNumber, mac_str, | ||
1552 | sizeof(mac_str)) != 2 * ETH_ALEN) | ||
1553 | return 1; | ||
1554 | |||
1555 | for (i = 0; i < ETH_ALEN; i++) | ||
1556 | esi[i] = htoi(mac_str[2 * i]) * 16 + htoi(mac_str[2 * i + 1]); | ||
1557 | |||
1558 | return 0; | ||
1559 | } | ||
1560 | |||
1561 | /* ATM stuff */ | ||
1562 | static int uea_atm_open(struct usbatm_data *usbatm, struct atm_dev *atm_dev) | ||
1563 | { | ||
1564 | struct uea_softc *sc = usbatm->driver_data; | ||
1565 | |||
1566 | return uea_getesi(sc, atm_dev->esi); | ||
1567 | } | ||
1568 | |||
1569 | static int uea_heavy(struct usbatm_data *usbatm, struct usb_interface *intf) | ||
1570 | { | ||
1571 | struct uea_softc *sc = usbatm->driver_data; | ||
1572 | |||
1573 | wait_event(sc->sync_q, IS_OPERATIONAL(sc)); | ||
1574 | |||
1575 | return 0; | ||
1576 | |||
1577 | } | ||
1578 | |||
1579 | static int claim_interface(struct usb_device *usb_dev, | ||
1580 | struct usbatm_data *usbatm, int ifnum) | ||
1581 | { | ||
1582 | int ret; | ||
1583 | struct usb_interface *intf = usb_ifnum_to_if(usb_dev, ifnum); | ||
1584 | |||
1585 | if (!intf) { | ||
1586 | uea_err(usb_dev, "interface %d not found\n", ifnum); | ||
1587 | return -ENODEV; | ||
1588 | } | ||
1589 | |||
1590 | ret = usb_driver_claim_interface(&uea_driver, intf, usbatm); | ||
1591 | if (ret != 0) | ||
1592 | uea_err(usb_dev, "can't claim interface %d, error %d\n", ifnum, | ||
1593 | ret); | ||
1594 | return ret; | ||
1595 | } | ||
1596 | |||
1597 | static void create_fs_entries(struct uea_softc *sc, struct usb_interface *intf) | ||
1598 | { | ||
1599 | /* sysfs interface */ | ||
1600 | device_create_file(&intf->dev, &dev_attr_stat_status); | ||
1601 | device_create_file(&intf->dev, &dev_attr_stat_mflags); | ||
1602 | device_create_file(&intf->dev, &dev_attr_stat_human_status); | ||
1603 | device_create_file(&intf->dev, &dev_attr_stat_delin); | ||
1604 | device_create_file(&intf->dev, &dev_attr_stat_vidcpe); | ||
1605 | device_create_file(&intf->dev, &dev_attr_stat_usrate); | ||
1606 | device_create_file(&intf->dev, &dev_attr_stat_dsrate); | ||
1607 | device_create_file(&intf->dev, &dev_attr_stat_usattenuation); | ||
1608 | device_create_file(&intf->dev, &dev_attr_stat_dsattenuation); | ||
1609 | device_create_file(&intf->dev, &dev_attr_stat_usmargin); | ||
1610 | device_create_file(&intf->dev, &dev_attr_stat_dsmargin); | ||
1611 | device_create_file(&intf->dev, &dev_attr_stat_txflow); | ||
1612 | device_create_file(&intf->dev, &dev_attr_stat_rxflow); | ||
1613 | device_create_file(&intf->dev, &dev_attr_stat_uscorr); | ||
1614 | device_create_file(&intf->dev, &dev_attr_stat_dscorr); | ||
1615 | device_create_file(&intf->dev, &dev_attr_stat_usunc); | ||
1616 | device_create_file(&intf->dev, &dev_attr_stat_dsunc); | ||
1617 | } | ||
1618 | |||
1619 | static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | ||
1620 | const struct usb_device_id *id, int *heavy) | ||
1621 | { | ||
1622 | struct usb_device *usb = interface_to_usbdev(intf); | ||
1623 | struct uea_softc *sc; | ||
1624 | int ret, ifnum = intf->altsetting->desc.bInterfaceNumber; | ||
1625 | |||
1626 | uea_enters(usb); | ||
1627 | |||
1628 | /* interface 0 is for firmware/monitoring */ | ||
1629 | if (ifnum != UEA_INTR_IFACE_NO) | ||
1630 | return -ENODEV; | ||
1631 | |||
1632 | *heavy = sync_wait[modem_index]; | ||
1633 | |||
1634 | /* interface 1 is for outbound traffic */ | ||
1635 | ret = claim_interface(usb, usbatm, UEA_US_IFACE_NO); | ||
1636 | if (ret < 0) | ||
1637 | return ret; | ||
1638 | |||
1639 | /* ADI930 has only 2 interfaces and inbound traffic | ||
1640 | * is on interface 1 | ||
1641 | */ | ||
1642 | if (UEA_CHIP_VERSION(id) != ADI930) { | ||
1643 | /* interface 2 is for inbound traffic */ | ||
1644 | ret = claim_interface(usb, usbatm, UEA_DS_IFACE_NO); | ||
1645 | if (ret < 0) | ||
1646 | return ret; | ||
1647 | } | ||
1648 | |||
1649 | sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL); | ||
1650 | if (!sc) { | ||
1651 | uea_err(INS_TO_USBDEV(sc), "uea_init: not enough memory !\n"); | ||
1652 | return -ENOMEM; | ||
1653 | } | ||
1654 | |||
1655 | sc->usb_dev = usb; | ||
1656 | usbatm->driver_data = sc; | ||
1657 | sc->usbatm = usbatm; | ||
1658 | sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0; | ||
1659 | sc->driver_info = id->driver_info; | ||
1660 | |||
1661 | ret = uea_boot(sc); | ||
1662 | if (ret < 0) { | ||
1663 | kfree(sc); | ||
1664 | return ret; | ||
1665 | } | ||
1666 | |||
1667 | create_fs_entries(sc, intf); | ||
1668 | return 0; | ||
1669 | } | ||
1670 | |||
1671 | static void destroy_fs_entries(struct uea_softc *sc, struct usb_interface *intf) | ||
1672 | { | ||
1673 | /* sysfs interface */ | ||
1674 | device_remove_file(&intf->dev, &dev_attr_stat_status); | ||
1675 | device_remove_file(&intf->dev, &dev_attr_stat_mflags); | ||
1676 | device_remove_file(&intf->dev, &dev_attr_stat_human_status); | ||
1677 | device_remove_file(&intf->dev, &dev_attr_stat_delin); | ||
1678 | device_remove_file(&intf->dev, &dev_attr_stat_vidcpe); | ||
1679 | device_remove_file(&intf->dev, &dev_attr_stat_usrate); | ||
1680 | device_remove_file(&intf->dev, &dev_attr_stat_dsrate); | ||
1681 | device_remove_file(&intf->dev, &dev_attr_stat_usattenuation); | ||
1682 | device_remove_file(&intf->dev, &dev_attr_stat_dsattenuation); | ||
1683 | device_remove_file(&intf->dev, &dev_attr_stat_usmargin); | ||
1684 | device_remove_file(&intf->dev, &dev_attr_stat_dsmargin); | ||
1685 | device_remove_file(&intf->dev, &dev_attr_stat_txflow); | ||
1686 | device_remove_file(&intf->dev, &dev_attr_stat_rxflow); | ||
1687 | device_remove_file(&intf->dev, &dev_attr_stat_uscorr); | ||
1688 | device_remove_file(&intf->dev, &dev_attr_stat_dscorr); | ||
1689 | device_remove_file(&intf->dev, &dev_attr_stat_usunc); | ||
1690 | device_remove_file(&intf->dev, &dev_attr_stat_dsunc); | ||
1691 | } | ||
1692 | |||
1693 | static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf) | ||
1694 | { | ||
1695 | struct uea_softc *sc = usbatm->driver_data; | ||
1696 | |||
1697 | destroy_fs_entries(sc, intf); | ||
1698 | uea_stop(sc); | ||
1699 | kfree(sc); | ||
1700 | } | ||
1701 | |||
1702 | static struct usbatm_driver uea_usbatm_driver = { | ||
1703 | .driver_name = "ueagle-atm", | ||
1704 | .owner = THIS_MODULE, | ||
1705 | .bind = uea_bind, | ||
1706 | .atm_start = uea_atm_open, | ||
1707 | .unbind = uea_unbind, | ||
1708 | .heavy_init = uea_heavy, | ||
1709 | .in = UEA_BULK_DATA_PIPE, | ||
1710 | .out = UEA_BULK_DATA_PIPE, | ||
1711 | }; | ||
1712 | |||
1713 | static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
1714 | { | ||
1715 | struct usb_device *usb = interface_to_usbdev(intf); | ||
1716 | |||
1717 | uea_enters(usb); | ||
1718 | uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s\n", | ||
1719 | le16_to_cpu(usb->descriptor.idVendor), | ||
1720 | le16_to_cpu(usb->descriptor.idProduct), | ||
1721 | chip_name[UEA_CHIP_VERSION(id)]); | ||
1722 | |||
1723 | usb_reset_device(usb); | ||
1724 | |||
1725 | if (UEA_IS_PREFIRM(id)) | ||
1726 | return uea_load_firmware(usb, UEA_CHIP_VERSION(id)); | ||
1727 | |||
1728 | return usbatm_usb_probe(intf, id, &uea_usbatm_driver); | ||
1729 | } | ||
1730 | |||
1731 | static void uea_disconnect(struct usb_interface *intf) | ||
1732 | { | ||
1733 | struct usb_device *usb = interface_to_usbdev(intf); | ||
1734 | int ifnum = intf->altsetting->desc.bInterfaceNumber; | ||
1735 | uea_enters(usb); | ||
1736 | |||
1737 | /* ADI930 has 2 interfaces and eagle 3 interfaces. | ||
1738 | * Pre-firmware device has one interface | ||
1739 | */ | ||
1740 | if (usb->config->desc.bNumInterfaces != 1 && ifnum == 0) { | ||
1741 | down(&uea_semaphore); | ||
1742 | usbatm_usb_disconnect(intf); | ||
1743 | up(&uea_semaphore); | ||
1744 | uea_info(usb, "ADSL device removed\n"); | ||
1745 | } | ||
1746 | |||
1747 | uea_leaves(usb); | ||
1748 | } | ||
1749 | |||
1750 | /* | ||
1751 | * List of supported VID/PID | ||
1752 | */ | ||
1753 | static const struct usb_device_id uea_ids[] = { | ||
1754 | {USB_DEVICE(ELSA_VID, ELSA_PID_PREFIRM), .driver_info = ADI930 | PREFIRM}, | ||
1755 | {USB_DEVICE(ELSA_VID, ELSA_PID_PSTFIRM), .driver_info = ADI930 | PSTFIRM}, | ||
1756 | {USB_DEVICE(EAGLE_VID, EAGLE_I_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
1757 | {USB_DEVICE(EAGLE_VID, EAGLE_I_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | ||
1758 | {USB_DEVICE(EAGLE_VID, EAGLE_II_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
1759 | {USB_DEVICE(EAGLE_VID, EAGLE_II_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | ||
1760 | {USB_DEVICE(EAGLE_VID, EAGLE_IIC_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
1761 | {USB_DEVICE(EAGLE_VID, EAGLE_IIC_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | ||
1762 | {USB_DEVICE(EAGLE_VID, EAGLE_III_PID_PREFIRM), .driver_info = EAGLE_III | PREFIRM}, | ||
1763 | {USB_DEVICE(EAGLE_VID, EAGLE_III_PID_PSTFIRM), .driver_info = EAGLE_III | PSTFIRM}, | ||
1764 | {USB_DEVICE(USR_VID, MILLER_A_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
1765 | {USB_DEVICE(USR_VID, MILLER_A_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | ||
1766 | {USB_DEVICE(USR_VID, MILLER_B_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
1767 | {USB_DEVICE(USR_VID, MILLER_B_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | ||
1768 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, | ||
1769 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM}, | ||
1770 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, | ||
1771 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM}, | ||
1772 | {} | ||
1773 | }; | ||
1774 | |||
1775 | /* | ||
1776 | * USB driver descriptor | ||
1777 | */ | ||
1778 | static struct usb_driver uea_driver = { | ||
1779 | .name = "ueagle-atm", | ||
1780 | .id_table = uea_ids, | ||
1781 | .probe = uea_probe, | ||
1782 | .disconnect = uea_disconnect, | ||
1783 | }; | ||
1784 | |||
1785 | MODULE_DEVICE_TABLE(usb, uea_ids); | ||
1786 | |||
1787 | /** | ||
1788 | * uea_init - Initialize the module. | ||
1789 | * Register to USB subsystem | ||
1790 | */ | ||
1791 | static int __init uea_init(void) | ||
1792 | { | ||
1793 | printk(KERN_INFO "[ueagle-atm] driver " EAGLEUSBVERSION " loaded\n"); | ||
1794 | |||
1795 | usb_register(&uea_driver); | ||
1796 | |||
1797 | return 0; | ||
1798 | } | ||
1799 | |||
1800 | module_init(uea_init); | ||
1801 | |||
1802 | /** | ||
1803 | * uea_exit - Destroy module | ||
1804 | * Deregister with USB subsystem | ||
1805 | */ | ||
1806 | static void __exit uea_exit(void) | ||
1807 | { | ||
1808 | /* | ||
1809 | * This calls automatically the uea_disconnect method if necessary: | ||
1810 | */ | ||
1811 | usb_deregister(&uea_driver); | ||
1812 | |||
1813 | printk(KERN_INFO "[ueagle-atm] driver unloaded\n"); | ||
1814 | } | ||
1815 | |||
1816 | module_exit(uea_exit); | ||
1817 | |||
1818 | MODULE_AUTHOR("Damien Bergamini/Matthieu Castet/Stanislaw W. Gruszka"); | ||
1819 | MODULE_DESCRIPTION("ADI 930/Eagle USB ADSL Modem driver"); | ||
1820 | MODULE_LICENSE("Dual BSD/GPL"); | ||
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 2e6593e6c1bd..9baa6296fc95 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c | |||
@@ -646,14 +646,14 @@ static void usbatm_destroy_instance(struct kref *kref) | |||
646 | kfree(instance); | 646 | kfree(instance); |
647 | } | 647 | } |
648 | 648 | ||
649 | void usbatm_get_instance(struct usbatm_data *instance) | 649 | static void usbatm_get_instance(struct usbatm_data *instance) |
650 | { | 650 | { |
651 | dbg("%s", __func__); | 651 | dbg("%s", __func__); |
652 | 652 | ||
653 | kref_get(&instance->refcount); | 653 | kref_get(&instance->refcount); |
654 | } | 654 | } |
655 | 655 | ||
656 | void usbatm_put_instance(struct usbatm_data *instance) | 656 | static void usbatm_put_instance(struct usbatm_data *instance) |
657 | { | 657 | { |
658 | dbg("%s", __func__); | 658 | dbg("%s", __func__); |
659 | 659 | ||
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c index 7fe7fb484d10..5c76e3aaaa5e 100644 --- a/drivers/usb/atm/xusbatm.c +++ b/drivers/usb/atm/xusbatm.c | |||
@@ -140,7 +140,6 @@ static int xusbatm_usb_probe(struct usb_interface *intf, | |||
140 | } | 140 | } |
141 | 141 | ||
142 | static struct usb_driver xusbatm_usb_driver = { | 142 | static struct usb_driver xusbatm_usb_driver = { |
143 | .owner = THIS_MODULE, | ||
144 | .name = xusbatm_driver_name, | 143 | .name = xusbatm_driver_name, |
145 | .probe = xusbatm_usb_probe, | 144 | .probe = xusbatm_usb_probe, |
146 | .disconnect = usbatm_usb_disconnect, | 145 | .disconnect = usbatm_usb_disconnect, |
diff --git a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c index 50858273f8d3..3ad9ee8b84a9 100644 --- a/drivers/usb/class/audio.c +++ b/drivers/usb/class/audio.c | |||
@@ -2732,7 +2732,6 @@ static struct usb_device_id usb_audio_ids [] = { | |||
2732 | MODULE_DEVICE_TABLE (usb, usb_audio_ids); | 2732 | MODULE_DEVICE_TABLE (usb, usb_audio_ids); |
2733 | 2733 | ||
2734 | static struct usb_driver usb_audio_driver = { | 2734 | static struct usb_driver usb_audio_driver = { |
2735 | .owner = THIS_MODULE, | ||
2736 | .name = "audio", | 2735 | .name = "audio", |
2737 | .probe = usb_audio_probe, | 2736 | .probe = usb_audio_probe, |
2738 | .disconnect = usb_audio_disconnect, | 2737 | .disconnect = usb_audio_disconnect, |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 1b4751412970..248279e44c99 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright (c) 1999 Johannes Erdfelt <johannes@erdfelt.com> | 6 | * Copyright (c) 1999 Johannes Erdfelt <johannes@erdfelt.com> |
7 | * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> | 7 | * Copyright (c) 2000 Vojtech Pavlik <vojtech@suse.cz> |
8 | * Copyright (c) 2004 Oliver Neukum <oliver@neukum.name> | 8 | * Copyright (c) 2004 Oliver Neukum <oliver@neukum.name> |
9 | * Copyright (c) 2005 David Kubicek <dave@awk.cz> | ||
9 | * | 10 | * |
10 | * USB Abstract Control Model driver for USB modems and ISDN adapters | 11 | * USB Abstract Control Model driver for USB modems and ISDN adapters |
11 | * | 12 | * |
@@ -29,6 +30,7 @@ | |||
29 | * config we want, sysadmin changes bConfigurationValue in sysfs. | 30 | * config we want, sysadmin changes bConfigurationValue in sysfs. |
30 | * v0.23 - use softirq for rx processing, as needed by tty layer | 31 | * v0.23 - use softirq for rx processing, as needed by tty layer |
31 | * v0.24 - change probe method to evaluate CDC union descriptor | 32 | * v0.24 - change probe method to evaluate CDC union descriptor |
33 | * v0.25 - downstream tasks paralelized to maximize throughput | ||
32 | */ | 34 | */ |
33 | 35 | ||
34 | /* | 36 | /* |
@@ -63,14 +65,15 @@ | |||
63 | #include <linux/usb_cdc.h> | 65 | #include <linux/usb_cdc.h> |
64 | #include <asm/byteorder.h> | 66 | #include <asm/byteorder.h> |
65 | #include <asm/unaligned.h> | 67 | #include <asm/unaligned.h> |
68 | #include <linux/list.h> | ||
66 | 69 | ||
67 | #include "cdc-acm.h" | 70 | #include "cdc-acm.h" |
68 | 71 | ||
69 | /* | 72 | /* |
70 | * Version Information | 73 | * Version Information |
71 | */ | 74 | */ |
72 | #define DRIVER_VERSION "v0.23" | 75 | #define DRIVER_VERSION "v0.25" |
73 | #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik" | 76 | #define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek" |
74 | #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters" | 77 | #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters" |
75 | 78 | ||
76 | static struct usb_driver acm_driver; | 79 | static struct usb_driver acm_driver; |
@@ -284,7 +287,9 @@ exit: | |||
284 | /* data interface returns incoming bytes, or we got unthrottled */ | 287 | /* data interface returns incoming bytes, or we got unthrottled */ |
285 | static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) | 288 | static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) |
286 | { | 289 | { |
287 | struct acm *acm = urb->context; | 290 | struct acm_rb *buf; |
291 | struct acm_ru *rcv = urb->context; | ||
292 | struct acm *acm = rcv->instance; | ||
288 | dbg("Entering acm_read_bulk with status %d\n", urb->status); | 293 | dbg("Entering acm_read_bulk with status %d\n", urb->status); |
289 | 294 | ||
290 | if (!ACM_READY(acm)) | 295 | if (!ACM_READY(acm)) |
@@ -293,49 +298,109 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs) | |||
293 | if (urb->status) | 298 | if (urb->status) |
294 | dev_dbg(&acm->data->dev, "bulk rx status %d\n", urb->status); | 299 | dev_dbg(&acm->data->dev, "bulk rx status %d\n", urb->status); |
295 | 300 | ||
296 | /* calling tty_flip_buffer_push() in_irq() isn't allowed */ | 301 | buf = rcv->buffer; |
297 | tasklet_schedule(&acm->bh); | 302 | buf->size = urb->actual_length; |
303 | |||
304 | spin_lock(&acm->read_lock); | ||
305 | list_add_tail(&rcv->list, &acm->spare_read_urbs); | ||
306 | list_add_tail(&buf->list, &acm->filled_read_bufs); | ||
307 | spin_unlock(&acm->read_lock); | ||
308 | |||
309 | tasklet_schedule(&acm->urb_task); | ||
298 | } | 310 | } |
299 | 311 | ||
300 | static void acm_rx_tasklet(unsigned long _acm) | 312 | static void acm_rx_tasklet(unsigned long _acm) |
301 | { | 313 | { |
302 | struct acm *acm = (void *)_acm; | 314 | struct acm *acm = (void *)_acm; |
303 | struct urb *urb = acm->readurb; | 315 | struct acm_rb *buf; |
304 | struct tty_struct *tty = acm->tty; | 316 | struct tty_struct *tty = acm->tty; |
305 | unsigned char *data = urb->transfer_buffer; | 317 | struct acm_ru *rcv; |
318 | //unsigned long flags; | ||
306 | int i = 0; | 319 | int i = 0; |
307 | dbg("Entering acm_rx_tasklet"); | 320 | dbg("Entering acm_rx_tasklet"); |
308 | 321 | ||
309 | if (urb->actual_length > 0 && !acm->throttle) { | 322 | if (!ACM_READY(acm) || acm->throttle) |
310 | for (i = 0; i < urb->actual_length && !acm->throttle; i++) { | 323 | return; |
311 | /* if we insert more than TTY_FLIPBUF_SIZE characters, | 324 | |
312 | * we drop them. */ | 325 | next_buffer: |
313 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | 326 | spin_lock(&acm->read_lock); |
314 | tty_flip_buffer_push(tty); | 327 | if (list_empty(&acm->filled_read_bufs)) { |
315 | } | 328 | spin_unlock(&acm->read_lock); |
316 | tty_insert_flip_char(tty, data[i], 0); | 329 | goto urbs; |
317 | } | ||
318 | dbg("Handed %d bytes to tty layer", i+1); | ||
319 | tty_flip_buffer_push(tty); | ||
320 | } | 330 | } |
331 | buf = list_entry(acm->filled_read_bufs.next, | ||
332 | struct acm_rb, list); | ||
333 | list_del(&buf->list); | ||
334 | spin_unlock(&acm->read_lock); | ||
335 | |||
336 | dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size); | ||
337 | |||
338 | for (i = 0; i < buf->size && !acm->throttle; i++) { | ||
339 | /* if we insert more than TTY_FLIPBUF_SIZE characters, | ||
340 | we drop them. */ | ||
341 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
342 | tty_flip_buffer_push(tty); | ||
343 | } | ||
344 | tty_insert_flip_char(tty, buf->base[i], 0); | ||
345 | } | ||
346 | tty_flip_buffer_push(tty); | ||
321 | 347 | ||
322 | spin_lock(&acm->throttle_lock); | 348 | spin_lock(&acm->throttle_lock); |
323 | if (acm->throttle) { | 349 | if (acm->throttle) { |
324 | dbg("Throtteling noticed"); | 350 | dbg("Throtteling noticed"); |
325 | memmove(data, data + i, urb->actual_length - i); | 351 | memmove(buf->base, buf->base + i, buf->size - i); |
326 | urb->actual_length -= i; | 352 | buf->size -= i; |
327 | acm->resubmit_to_unthrottle = 1; | ||
328 | spin_unlock(&acm->throttle_lock); | 353 | spin_unlock(&acm->throttle_lock); |
354 | spin_lock(&acm->read_lock); | ||
355 | list_add(&buf->list, &acm->filled_read_bufs); | ||
356 | spin_unlock(&acm->read_lock); | ||
329 | return; | 357 | return; |
330 | } | 358 | } |
331 | spin_unlock(&acm->throttle_lock); | 359 | spin_unlock(&acm->throttle_lock); |
332 | 360 | ||
333 | urb->actual_length = 0; | 361 | spin_lock(&acm->read_lock); |
334 | urb->dev = acm->dev; | 362 | list_add(&buf->list, &acm->spare_read_bufs); |
335 | 363 | spin_unlock(&acm->read_lock); | |
336 | i = usb_submit_urb(urb, GFP_ATOMIC); | 364 | goto next_buffer; |
337 | if (i) | 365 | |
338 | dev_dbg(&acm->data->dev, "bulk rx resubmit %d\n", i); | 366 | urbs: |
367 | while (!list_empty(&acm->spare_read_bufs)) { | ||
368 | spin_lock(&acm->read_lock); | ||
369 | if (list_empty(&acm->spare_read_urbs)) { | ||
370 | spin_unlock(&acm->read_lock); | ||
371 | return; | ||
372 | } | ||
373 | rcv = list_entry(acm->spare_read_urbs.next, | ||
374 | struct acm_ru, list); | ||
375 | list_del(&rcv->list); | ||
376 | spin_unlock(&acm->read_lock); | ||
377 | |||
378 | buf = list_entry(acm->spare_read_bufs.next, | ||
379 | struct acm_rb, list); | ||
380 | list_del(&buf->list); | ||
381 | |||
382 | rcv->buffer = buf; | ||
383 | |||
384 | usb_fill_bulk_urb(rcv->urb, acm->dev, | ||
385 | acm->rx_endpoint, | ||
386 | buf->base, | ||
387 | acm->readsize, | ||
388 | acm_read_bulk, rcv); | ||
389 | rcv->urb->transfer_dma = buf->dma; | ||
390 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
391 | |||
392 | dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p\n", rcv->urb, rcv, buf); | ||
393 | |||
394 | /* This shouldn't kill the driver as unsuccessful URBs are returned to the | ||
395 | free-urbs-pool and resubmited ASAP */ | ||
396 | if (usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) { | ||
397 | list_add(&buf->list, &acm->spare_read_bufs); | ||
398 | spin_lock(&acm->read_lock); | ||
399 | list_add(&rcv->list, &acm->spare_read_urbs); | ||
400 | spin_unlock(&acm->read_lock); | ||
401 | return; | ||
402 | } | ||
403 | } | ||
339 | } | 404 | } |
340 | 405 | ||
341 | /* data interface wrote those outgoing bytes */ | 406 | /* data interface wrote those outgoing bytes */ |
@@ -369,6 +434,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
369 | { | 434 | { |
370 | struct acm *acm; | 435 | struct acm *acm; |
371 | int rv = -EINVAL; | 436 | int rv = -EINVAL; |
437 | int i; | ||
372 | dbg("Entering acm_tty_open.\n"); | 438 | dbg("Entering acm_tty_open.\n"); |
373 | 439 | ||
374 | down(&open_sem); | 440 | down(&open_sem); |
@@ -382,7 +448,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
382 | tty->driver_data = acm; | 448 | tty->driver_data = acm; |
383 | acm->tty = tty; | 449 | acm->tty = tty; |
384 | 450 | ||
385 | 451 | /* force low_latency on so that our tty_push actually forces the data through, | |
452 | otherwise it is scheduled, and with high data rates data can get lost. */ | ||
453 | tty->low_latency = 1; | ||
386 | 454 | ||
387 | if (acm->used++) { | 455 | if (acm->used++) { |
388 | goto done; | 456 | goto done; |
@@ -394,18 +462,20 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
394 | goto bail_out; | 462 | goto bail_out; |
395 | } | 463 | } |
396 | 464 | ||
397 | acm->readurb->dev = acm->dev; | ||
398 | if (usb_submit_urb(acm->readurb, GFP_KERNEL)) { | ||
399 | dbg("usb_submit_urb(read bulk) failed"); | ||
400 | goto bail_out_and_unlink; | ||
401 | } | ||
402 | |||
403 | if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS)) | 465 | if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS)) |
404 | goto full_bailout; | 466 | goto full_bailout; |
405 | 467 | ||
406 | /* force low_latency on so that our tty_push actually forces the data through, | 468 | INIT_LIST_HEAD(&acm->spare_read_urbs); |
407 | otherwise it is scheduled, and with high data rates data can get lost. */ | 469 | INIT_LIST_HEAD(&acm->spare_read_bufs); |
408 | tty->low_latency = 1; | 470 | INIT_LIST_HEAD(&acm->filled_read_bufs); |
471 | for (i = 0; i < ACM_NRU; i++) { | ||
472 | list_add(&(acm->ru[i].list), &acm->spare_read_urbs); | ||
473 | } | ||
474 | for (i = 0; i < ACM_NRB; i++) { | ||
475 | list_add(&(acm->rb[i].list), &acm->spare_read_bufs); | ||
476 | } | ||
477 | |||
478 | tasklet_schedule(&acm->urb_task); | ||
409 | 479 | ||
410 | done: | 480 | done: |
411 | err_out: | 481 | err_out: |
@@ -413,8 +483,6 @@ err_out: | |||
413 | return rv; | 483 | return rv; |
414 | 484 | ||
415 | full_bailout: | 485 | full_bailout: |
416 | usb_kill_urb(acm->readurb); | ||
417 | bail_out_and_unlink: | ||
418 | usb_kill_urb(acm->ctrlurb); | 486 | usb_kill_urb(acm->ctrlurb); |
419 | bail_out: | 487 | bail_out: |
420 | acm->used--; | 488 | acm->used--; |
@@ -424,18 +492,22 @@ bail_out: | |||
424 | 492 | ||
425 | static void acm_tty_unregister(struct acm *acm) | 493 | static void acm_tty_unregister(struct acm *acm) |
426 | { | 494 | { |
495 | int i; | ||
496 | |||
427 | tty_unregister_device(acm_tty_driver, acm->minor); | 497 | tty_unregister_device(acm_tty_driver, acm->minor); |
428 | usb_put_intf(acm->control); | 498 | usb_put_intf(acm->control); |
429 | acm_table[acm->minor] = NULL; | 499 | acm_table[acm->minor] = NULL; |
430 | usb_free_urb(acm->ctrlurb); | 500 | usb_free_urb(acm->ctrlurb); |
431 | usb_free_urb(acm->readurb); | ||
432 | usb_free_urb(acm->writeurb); | 501 | usb_free_urb(acm->writeurb); |
502 | for (i = 0; i < ACM_NRU; i++) | ||
503 | usb_free_urb(acm->ru[i].urb); | ||
433 | kfree(acm); | 504 | kfree(acm); |
434 | } | 505 | } |
435 | 506 | ||
436 | static void acm_tty_close(struct tty_struct *tty, struct file *filp) | 507 | static void acm_tty_close(struct tty_struct *tty, struct file *filp) |
437 | { | 508 | { |
438 | struct acm *acm = tty->driver_data; | 509 | struct acm *acm = tty->driver_data; |
510 | int i; | ||
439 | 511 | ||
440 | if (!acm || !acm->used) | 512 | if (!acm || !acm->used) |
441 | return; | 513 | return; |
@@ -446,7 +518,8 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) | |||
446 | acm_set_control(acm, acm->ctrlout = 0); | 518 | acm_set_control(acm, acm->ctrlout = 0); |
447 | usb_kill_urb(acm->ctrlurb); | 519 | usb_kill_urb(acm->ctrlurb); |
448 | usb_kill_urb(acm->writeurb); | 520 | usb_kill_urb(acm->writeurb); |
449 | usb_kill_urb(acm->readurb); | 521 | for (i = 0; i < ACM_NRU; i++) |
522 | usb_kill_urb(acm->ru[i].urb); | ||
450 | } else | 523 | } else |
451 | acm_tty_unregister(acm); | 524 | acm_tty_unregister(acm); |
452 | } | 525 | } |
@@ -528,10 +601,7 @@ static void acm_tty_unthrottle(struct tty_struct *tty) | |||
528 | spin_lock_bh(&acm->throttle_lock); | 601 | spin_lock_bh(&acm->throttle_lock); |
529 | acm->throttle = 0; | 602 | acm->throttle = 0; |
530 | spin_unlock_bh(&acm->throttle_lock); | 603 | spin_unlock_bh(&acm->throttle_lock); |
531 | if (acm->resubmit_to_unthrottle) { | 604 | tasklet_schedule(&acm->urb_task); |
532 | acm->resubmit_to_unthrottle = 0; | ||
533 | acm_read_bulk(acm->readurb, NULL); | ||
534 | } | ||
535 | } | 605 | } |
536 | 606 | ||
537 | static void acm_tty_break_ctl(struct tty_struct *tty, int state) | 607 | static void acm_tty_break_ctl(struct tty_struct *tty, int state) |
@@ -588,7 +658,7 @@ static int acm_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int | |||
588 | return -ENOIOCTLCMD; | 658 | return -ENOIOCTLCMD; |
589 | } | 659 | } |
590 | 660 | ||
591 | static __u32 acm_tty_speed[] = { | 661 | static const __u32 acm_tty_speed[] = { |
592 | 0, 50, 75, 110, 134, 150, 200, 300, 600, | 662 | 0, 50, 75, 110, 134, 150, 200, 300, 600, |
593 | 1200, 1800, 2400, 4800, 9600, 19200, 38400, | 663 | 1200, 1800, 2400, 4800, 9600, 19200, 38400, |
594 | 57600, 115200, 230400, 460800, 500000, 576000, | 664 | 57600, 115200, 230400, 460800, 500000, 576000, |
@@ -596,7 +666,7 @@ static __u32 acm_tty_speed[] = { | |||
596 | 2500000, 3000000, 3500000, 4000000 | 666 | 2500000, 3000000, 3500000, 4000000 |
597 | }; | 667 | }; |
598 | 668 | ||
599 | static __u8 acm_tty_size[] = { | 669 | static const __u8 acm_tty_size[] = { |
600 | 5, 6, 7, 8 | 670 | 5, 6, 7, 8 |
601 | }; | 671 | }; |
602 | 672 | ||
@@ -694,6 +764,7 @@ static int acm_probe (struct usb_interface *intf, | |||
694 | int call_interface_num = -1; | 764 | int call_interface_num = -1; |
695 | int data_interface_num; | 765 | int data_interface_num; |
696 | unsigned long quirks; | 766 | unsigned long quirks; |
767 | int i; | ||
697 | 768 | ||
698 | /* handle quirks deadly to normal probing*/ | 769 | /* handle quirks deadly to normal probing*/ |
699 | quirks = (unsigned long)id->driver_info; | 770 | quirks = (unsigned long)id->driver_info; |
@@ -833,7 +904,7 @@ skip_normal_probe: | |||
833 | } | 904 | } |
834 | 905 | ||
835 | ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); | 906 | ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize); |
836 | readsize = le16_to_cpu(epread->wMaxPacketSize); | 907 | readsize = le16_to_cpu(epread->wMaxPacketSize)*2; |
837 | acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize); | 908 | acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize); |
838 | acm->control = control_interface; | 909 | acm->control = control_interface; |
839 | acm->data = data_interface; | 910 | acm->data = data_interface; |
@@ -842,12 +913,14 @@ skip_normal_probe: | |||
842 | acm->ctrl_caps = ac_management_function; | 913 | acm->ctrl_caps = ac_management_function; |
843 | acm->ctrlsize = ctrlsize; | 914 | acm->ctrlsize = ctrlsize; |
844 | acm->readsize = readsize; | 915 | acm->readsize = readsize; |
845 | acm->bh.func = acm_rx_tasklet; | 916 | acm->urb_task.func = acm_rx_tasklet; |
846 | acm->bh.data = (unsigned long) acm; | 917 | acm->urb_task.data = (unsigned long) acm; |
847 | INIT_WORK(&acm->work, acm_softint, acm); | 918 | INIT_WORK(&acm->work, acm_softint, acm); |
848 | spin_lock_init(&acm->throttle_lock); | 919 | spin_lock_init(&acm->throttle_lock); |
849 | spin_lock_init(&acm->write_lock); | 920 | spin_lock_init(&acm->write_lock); |
921 | spin_lock_init(&acm->read_lock); | ||
850 | acm->write_ready = 1; | 922 | acm->write_ready = 1; |
923 | acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); | ||
851 | 924 | ||
852 | buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); | 925 | buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); |
853 | if (!buf) { | 926 | if (!buf) { |
@@ -856,13 +929,6 @@ skip_normal_probe: | |||
856 | } | 929 | } |
857 | acm->ctrl_buffer = buf; | 930 | acm->ctrl_buffer = buf; |
858 | 931 | ||
859 | buf = usb_buffer_alloc(usb_dev, readsize, GFP_KERNEL, &acm->read_dma); | ||
860 | if (!buf) { | ||
861 | dev_dbg(&intf->dev, "out of memory (read buffer alloc)\n"); | ||
862 | goto alloc_fail3; | ||
863 | } | ||
864 | acm->read_buffer = buf; | ||
865 | |||
866 | if (acm_write_buffers_alloc(acm) < 0) { | 932 | if (acm_write_buffers_alloc(acm) < 0) { |
867 | dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n"); | 933 | dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n"); |
868 | goto alloc_fail4; | 934 | goto alloc_fail4; |
@@ -873,10 +939,25 @@ skip_normal_probe: | |||
873 | dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); | 939 | dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); |
874 | goto alloc_fail5; | 940 | goto alloc_fail5; |
875 | } | 941 | } |
876 | acm->readurb = usb_alloc_urb(0, GFP_KERNEL); | 942 | for (i = 0; i < ACM_NRU; i++) { |
877 | if (!acm->readurb) { | 943 | struct acm_ru *rcv = &(acm->ru[i]); |
878 | dev_dbg(&intf->dev, "out of memory (readurb kmalloc)\n"); | 944 | |
879 | goto alloc_fail6; | 945 | if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) { |
946 | dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n"); | ||
947 | goto alloc_fail7; | ||
948 | } | ||
949 | |||
950 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
951 | rcv->instance = acm; | ||
952 | } | ||
953 | for (i = 0; i < ACM_NRB; i++) { | ||
954 | struct acm_rb *buf = &(acm->rb[i]); | ||
955 | |||
956 | // Using usb_buffer_alloc instead of kmalloc as Oliver suggested | ||
957 | if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) { | ||
958 | dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n"); | ||
959 | goto alloc_fail7; | ||
960 | } | ||
880 | } | 961 | } |
881 | acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); | 962 | acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); |
882 | if (!acm->writeurb) { | 963 | if (!acm->writeurb) { |
@@ -889,15 +970,9 @@ skip_normal_probe: | |||
889 | acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 970 | acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
890 | acm->ctrlurb->transfer_dma = acm->ctrl_dma; | 971 | acm->ctrlurb->transfer_dma = acm->ctrl_dma; |
891 | 972 | ||
892 | usb_fill_bulk_urb(acm->readurb, usb_dev, usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress), | ||
893 | acm->read_buffer, readsize, acm_read_bulk, acm); | ||
894 | acm->readurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP; | ||
895 | acm->readurb->transfer_dma = acm->read_dma; | ||
896 | |||
897 | usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), | 973 | usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), |
898 | NULL, acm->writesize, acm_write_bulk, acm); | 974 | NULL, acm->writesize, acm_write_bulk, acm); |
899 | acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP; | 975 | acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP; |
900 | /* acm->writeurb->transfer_dma = 0; */ | ||
901 | 976 | ||
902 | dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); | 977 | dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor); |
903 | 978 | ||
@@ -917,14 +992,14 @@ skip_normal_probe: | |||
917 | return 0; | 992 | return 0; |
918 | 993 | ||
919 | alloc_fail7: | 994 | alloc_fail7: |
920 | usb_free_urb(acm->readurb); | 995 | for (i = 0; i < ACM_NRB; i++) |
921 | alloc_fail6: | 996 | usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); |
997 | for (i = 0; i < ACM_NRU; i++) | ||
998 | usb_free_urb(acm->ru[i].urb); | ||
922 | usb_free_urb(acm->ctrlurb); | 999 | usb_free_urb(acm->ctrlurb); |
923 | alloc_fail5: | 1000 | alloc_fail5: |
924 | acm_write_buffers_free(acm); | 1001 | acm_write_buffers_free(acm); |
925 | alloc_fail4: | 1002 | alloc_fail4: |
926 | usb_buffer_free(usb_dev, readsize, acm->read_buffer, acm->read_dma); | ||
927 | alloc_fail3: | ||
928 | usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); | 1003 | usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); |
929 | alloc_fail2: | 1004 | alloc_fail2: |
930 | kfree(acm); | 1005 | kfree(acm); |
@@ -936,6 +1011,7 @@ static void acm_disconnect(struct usb_interface *intf) | |||
936 | { | 1011 | { |
937 | struct acm *acm = usb_get_intfdata (intf); | 1012 | struct acm *acm = usb_get_intfdata (intf); |
938 | struct usb_device *usb_dev = interface_to_usbdev(intf); | 1013 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
1014 | int i; | ||
939 | 1015 | ||
940 | if (!acm || !acm->dev) { | 1016 | if (!acm || !acm->dev) { |
941 | dbg("disconnect on nonexisting interface"); | 1017 | dbg("disconnect on nonexisting interface"); |
@@ -946,15 +1022,24 @@ static void acm_disconnect(struct usb_interface *intf) | |||
946 | acm->dev = NULL; | 1022 | acm->dev = NULL; |
947 | usb_set_intfdata (intf, NULL); | 1023 | usb_set_intfdata (intf, NULL); |
948 | 1024 | ||
1025 | tasklet_disable(&acm->urb_task); | ||
1026 | |||
949 | usb_kill_urb(acm->ctrlurb); | 1027 | usb_kill_urb(acm->ctrlurb); |
950 | usb_kill_urb(acm->readurb); | ||
951 | usb_kill_urb(acm->writeurb); | 1028 | usb_kill_urb(acm->writeurb); |
1029 | for (i = 0; i < ACM_NRU; i++) | ||
1030 | usb_kill_urb(acm->ru[i].urb); | ||
1031 | |||
1032 | INIT_LIST_HEAD(&acm->filled_read_bufs); | ||
1033 | INIT_LIST_HEAD(&acm->spare_read_bufs); | ||
1034 | |||
1035 | tasklet_enable(&acm->urb_task); | ||
952 | 1036 | ||
953 | flush_scheduled_work(); /* wait for acm_softint */ | 1037 | flush_scheduled_work(); /* wait for acm_softint */ |
954 | 1038 | ||
955 | acm_write_buffers_free(acm); | 1039 | acm_write_buffers_free(acm); |
956 | usb_buffer_free(usb_dev, acm->readsize, acm->read_buffer, acm->read_dma); | ||
957 | usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); | 1040 | usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); |
1041 | for (i = 0; i < ACM_NRB; i++) | ||
1042 | usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); | ||
958 | 1043 | ||
959 | usb_driver_release_interface(&acm_driver, acm->data); | 1044 | usb_driver_release_interface(&acm_driver, acm->data); |
960 | 1045 | ||
@@ -1003,7 +1088,6 @@ static struct usb_device_id acm_ids[] = { | |||
1003 | MODULE_DEVICE_TABLE (usb, acm_ids); | 1088 | MODULE_DEVICE_TABLE (usb, acm_ids); |
1004 | 1089 | ||
1005 | static struct usb_driver acm_driver = { | 1090 | static struct usb_driver acm_driver = { |
1006 | .owner = THIS_MODULE, | ||
1007 | .name = "cdc_acm", | 1091 | .name = "cdc_acm", |
1008 | .probe = acm_probe, | 1092 | .probe = acm_probe, |
1009 | .disconnect = acm_disconnect, | 1093 | .disconnect = acm_disconnect, |
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index 963a5dfd2096..fd2aaccdcbac 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h | |||
@@ -59,6 +59,9 @@ | |||
59 | * when processing onlcr, so we only need 2 buffers. | 59 | * when processing onlcr, so we only need 2 buffers. |
60 | */ | 60 | */ |
61 | #define ACM_NWB 2 | 61 | #define ACM_NWB 2 |
62 | #define ACM_NRU 16 | ||
63 | #define ACM_NRB 16 | ||
64 | |||
62 | struct acm_wb { | 65 | struct acm_wb { |
63 | unsigned char *buf; | 66 | unsigned char *buf; |
64 | dma_addr_t dmah; | 67 | dma_addr_t dmah; |
@@ -66,22 +69,43 @@ struct acm_wb { | |||
66 | int use; | 69 | int use; |
67 | }; | 70 | }; |
68 | 71 | ||
72 | struct acm_rb { | ||
73 | struct list_head list; | ||
74 | int size; | ||
75 | unsigned char *base; | ||
76 | dma_addr_t dma; | ||
77 | }; | ||
78 | |||
79 | struct acm_ru { | ||
80 | struct list_head list; | ||
81 | struct acm_rb *buffer; | ||
82 | struct urb *urb; | ||
83 | struct acm *instance; | ||
84 | }; | ||
85 | |||
69 | struct acm { | 86 | struct acm { |
70 | struct usb_device *dev; /* the corresponding usb device */ | 87 | struct usb_device *dev; /* the corresponding usb device */ |
71 | struct usb_interface *control; /* control interface */ | 88 | struct usb_interface *control; /* control interface */ |
72 | struct usb_interface *data; /* data interface */ | 89 | struct usb_interface *data; /* data interface */ |
73 | struct tty_struct *tty; /* the corresponding tty */ | 90 | struct tty_struct *tty; /* the corresponding tty */ |
74 | struct urb *ctrlurb, *readurb, *writeurb; /* urbs */ | 91 | struct urb *ctrlurb, *writeurb; /* urbs */ |
75 | u8 *ctrl_buffer, *read_buffer; /* buffers of urbs */ | 92 | u8 *ctrl_buffer; /* buffers of urbs */ |
76 | dma_addr_t ctrl_dma, read_dma; /* dma handles of buffers */ | 93 | dma_addr_t ctrl_dma; /* dma handles of buffers */ |
77 | struct acm_wb wb[ACM_NWB]; | 94 | struct acm_wb wb[ACM_NWB]; |
95 | struct acm_ru ru[ACM_NRU]; | ||
96 | struct acm_rb rb[ACM_NRB]; | ||
97 | int rx_endpoint; | ||
98 | spinlock_t read_lock; | ||
99 | struct list_head spare_read_urbs; | ||
100 | struct list_head spare_read_bufs; | ||
101 | struct list_head filled_read_bufs; | ||
78 | int write_current; /* current write buffer */ | 102 | int write_current; /* current write buffer */ |
79 | int write_used; /* number of non-empty write buffers */ | 103 | int write_used; /* number of non-empty write buffers */ |
80 | int write_ready; /* write urb is not running */ | 104 | int write_ready; /* write urb is not running */ |
81 | spinlock_t write_lock; | 105 | spinlock_t write_lock; |
82 | struct usb_cdc_line_coding line; /* bits, stop, parity */ | 106 | struct usb_cdc_line_coding line; /* bits, stop, parity */ |
83 | struct work_struct work; /* work queue entry for line discipline waking up */ | 107 | struct work_struct work; /* work queue entry for line discipline waking up */ |
84 | struct tasklet_struct bh; /* rx processing */ | 108 | struct tasklet_struct urb_task; /* rx processing */ |
85 | spinlock_t throttle_lock; /* synchronize throtteling and read callback */ | 109 | spinlock_t throttle_lock; /* synchronize throtteling and read callback */ |
86 | unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ | 110 | unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ |
87 | unsigned int ctrlout; /* output control lines (DTR, RTS) */ | 111 | unsigned int ctrlout; /* output control lines (DTR, RTS) */ |
@@ -91,7 +115,6 @@ struct acm { | |||
91 | unsigned int minor; /* acm minor number */ | 115 | unsigned int minor; /* acm minor number */ |
92 | unsigned char throttle; /* throttled by tty layer */ | 116 | unsigned char throttle; /* throttled by tty layer */ |
93 | unsigned char clocal; /* termios CLOCAL */ | 117 | unsigned char clocal; /* termios CLOCAL */ |
94 | unsigned char resubmit_to_unthrottle; /* throtteling has disabled the read urb */ | ||
95 | unsigned int ctrl_caps; /* control capabilities from the class specific header */ | 118 | unsigned int ctrl_caps; /* control capabilities from the class specific header */ |
96 | }; | 119 | }; |
97 | 120 | ||
diff --git a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c index 5f8af35e7633..f13f004d311f 100644 --- a/drivers/usb/class/usb-midi.c +++ b/drivers/usb/class/usb-midi.c | |||
@@ -2027,7 +2027,6 @@ static struct usb_device_id id_table[] = { | |||
2027 | }; | 2027 | }; |
2028 | 2028 | ||
2029 | static struct usb_driver usb_midi_driver = { | 2029 | static struct usb_driver usb_midi_driver = { |
2030 | .owner = THIS_MODULE, | ||
2031 | .name = "midi", | 2030 | .name = "midi", |
2032 | .probe = usb_midi_probe, | 2031 | .probe = usb_midi_probe, |
2033 | .disconnect = usb_midi_disconnect, | 2032 | .disconnect = usb_midi_disconnect, |
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 357e75335f17..27e9404547f3 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -199,7 +199,7 @@ struct quirk_printer_struct { | |||
199 | #define USBLP_QUIRK_BIDIR 0x1 /* reports bidir but requires unidirectional mode (no INs/reads) */ | 199 | #define USBLP_QUIRK_BIDIR 0x1 /* reports bidir but requires unidirectional mode (no INs/reads) */ |
200 | #define USBLP_QUIRK_USB_INIT 0x2 /* needs vendor USB init string */ | 200 | #define USBLP_QUIRK_USB_INIT 0x2 /* needs vendor USB init string */ |
201 | 201 | ||
202 | static struct quirk_printer_struct quirk_printers[] = { | 202 | static const struct quirk_printer_struct quirk_printers[] = { |
203 | { 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */ | 203 | { 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */ |
204 | { 0x03f0, 0x0104, USBLP_QUIRK_BIDIR }, /* HP DeskJet 880C */ | 204 | { 0x03f0, 0x0104, USBLP_QUIRK_BIDIR }, /* HP DeskJet 880C */ |
205 | { 0x03f0, 0x0204, USBLP_QUIRK_BIDIR }, /* HP DeskJet 815C */ | 205 | { 0x03f0, 0x0204, USBLP_QUIRK_BIDIR }, /* HP DeskJet 815C */ |
@@ -301,7 +301,7 @@ static void usblp_bulk_write(struct urb *urb, struct pt_regs *regs) | |||
301 | * Get and print printer errors. | 301 | * Get and print printer errors. |
302 | */ | 302 | */ |
303 | 303 | ||
304 | static char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" }; | 304 | static const char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" }; |
305 | 305 | ||
306 | static int usblp_check_status(struct usblp *usblp, int err) | 306 | static int usblp_check_status(struct usblp *usblp, int err) |
307 | { | 307 | { |
@@ -438,7 +438,7 @@ static unsigned int usblp_poll(struct file *file, struct poll_table_struct *wait | |||
438 | | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM); | 438 | | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM); |
439 | } | 439 | } |
440 | 440 | ||
441 | static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 441 | static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
442 | { | 442 | { |
443 | struct usblp *usblp = file->private_data; | 443 | struct usblp *usblp = file->private_data; |
444 | int length, err, i; | 444 | int length, err, i; |
@@ -838,7 +838,8 @@ static struct file_operations usblp_fops = { | |||
838 | .read = usblp_read, | 838 | .read = usblp_read, |
839 | .write = usblp_write, | 839 | .write = usblp_write, |
840 | .poll = usblp_poll, | 840 | .poll = usblp_poll, |
841 | .ioctl = usblp_ioctl, | 841 | .unlocked_ioctl = usblp_ioctl, |
842 | .compat_ioctl = usblp_ioctl, | ||
842 | .open = usblp_open, | 843 | .open = usblp_open, |
843 | .release = usblp_release, | 844 | .release = usblp_release, |
844 | }; | 845 | }; |
@@ -849,6 +850,20 @@ static struct usb_class_driver usblp_class = { | |||
849 | .minor_base = USBLP_MINOR_BASE, | 850 | .minor_base = USBLP_MINOR_BASE, |
850 | }; | 851 | }; |
851 | 852 | ||
853 | static ssize_t usblp_show_ieee1284_id(struct device *dev, struct device_attribute *attr, char *buf) | ||
854 | { | ||
855 | struct usb_interface *intf = to_usb_interface(dev); | ||
856 | struct usblp *usblp = usb_get_intfdata (intf); | ||
857 | |||
858 | if (usblp->device_id_string[0] == 0 && | ||
859 | usblp->device_id_string[1] == 0) | ||
860 | return 0; | ||
861 | |||
862 | return sprintf(buf, "%s", usblp->device_id_string+2); | ||
863 | } | ||
864 | |||
865 | static DEVICE_ATTR(ieee1284_id, S_IRUGO, usblp_show_ieee1284_id, NULL); | ||
866 | |||
852 | static int usblp_probe(struct usb_interface *intf, | 867 | static int usblp_probe(struct usb_interface *intf, |
853 | const struct usb_device_id *id) | 868 | const struct usb_device_id *id) |
854 | { | 869 | { |
@@ -933,20 +948,12 @@ static int usblp_probe(struct usb_interface *intf, | |||
933 | 948 | ||
934 | /* Retrieve and store the device ID string. */ | 949 | /* Retrieve and store the device ID string. */ |
935 | usblp_cache_device_id_string(usblp); | 950 | usblp_cache_device_id_string(usblp); |
951 | device_create_file(&intf->dev, &dev_attr_ieee1284_id); | ||
936 | 952 | ||
937 | #ifdef DEBUG | 953 | #ifdef DEBUG |
938 | usblp_check_status(usblp, 0); | 954 | usblp_check_status(usblp, 0); |
939 | #endif | 955 | #endif |
940 | 956 | ||
941 | info("usblp%d: USB %sdirectional printer dev %d " | ||
942 | "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X", | ||
943 | usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, | ||
944 | usblp->ifnum, | ||
945 | usblp->protocol[usblp->current_protocol].alt_setting, | ||
946 | usblp->current_protocol, | ||
947 | le16_to_cpu(usblp->dev->descriptor.idVendor), | ||
948 | le16_to_cpu(usblp->dev->descriptor.idProduct)); | ||
949 | |||
950 | usb_set_intfdata (intf, usblp); | 957 | usb_set_intfdata (intf, usblp); |
951 | 958 | ||
952 | usblp->present = 1; | 959 | usblp->present = 1; |
@@ -957,11 +964,20 @@ static int usblp_probe(struct usb_interface *intf, | |||
957 | goto abort_intfdata; | 964 | goto abort_intfdata; |
958 | } | 965 | } |
959 | usblp->minor = intf->minor; | 966 | usblp->minor = intf->minor; |
967 | info("usblp%d: USB %sdirectional printer dev %d " | ||
968 | "if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X", | ||
969 | usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, | ||
970 | usblp->ifnum, | ||
971 | usblp->protocol[usblp->current_protocol].alt_setting, | ||
972 | usblp->current_protocol, | ||
973 | le16_to_cpu(usblp->dev->descriptor.idVendor), | ||
974 | le16_to_cpu(usblp->dev->descriptor.idProduct)); | ||
960 | 975 | ||
961 | return 0; | 976 | return 0; |
962 | 977 | ||
963 | abort_intfdata: | 978 | abort_intfdata: |
964 | usb_set_intfdata (intf, NULL); | 979 | usb_set_intfdata (intf, NULL); |
980 | device_remove_file(&intf->dev, &dev_attr_ieee1284_id); | ||
965 | abort: | 981 | abort: |
966 | if (usblp) { | 982 | if (usblp) { |
967 | if (usblp->writebuf) | 983 | if (usblp->writebuf) |
@@ -1156,6 +1172,8 @@ static void usblp_disconnect(struct usb_interface *intf) | |||
1156 | BUG (); | 1172 | BUG (); |
1157 | } | 1173 | } |
1158 | 1174 | ||
1175 | device_remove_file(&intf->dev, &dev_attr_ieee1284_id); | ||
1176 | |||
1159 | down (&usblp_sem); | 1177 | down (&usblp_sem); |
1160 | down (&usblp->sem); | 1178 | down (&usblp->sem); |
1161 | usblp->present = 0; | 1179 | usblp->present = 0; |
@@ -1186,7 +1204,6 @@ static struct usb_device_id usblp_ids [] = { | |||
1186 | MODULE_DEVICE_TABLE (usb, usblp_ids); | 1204 | MODULE_DEVICE_TABLE (usb, usblp_ids); |
1187 | 1205 | ||
1188 | static struct usb_driver usblp_driver = { | 1206 | static struct usb_driver usblp_driver = { |
1189 | .owner = THIS_MODULE, | ||
1190 | .name = "usblp", | 1207 | .name = "usblp", |
1191 | .probe = usblp_probe, | 1208 | .probe = usblp_probe, |
1192 | .disconnect = usblp_disconnect, | 1209 | .disconnect = usblp_disconnect, |
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index 86d5c380892d..28329ddf187c 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for USB Core files and filesystem | 2 | # Makefile for USB Core files and filesystem |
3 | # | 3 | # |
4 | 4 | ||
5 | usbcore-objs := usb.o hub.o hcd.o urb.o message.o \ | 5 | usbcore-objs := usb.o hub.o hcd.o urb.o message.o driver.o \ |
6 | config.o file.o buffer.o sysfs.o devio.o notify.o | 6 | config.o file.o buffer.o sysfs.o devio.o notify.o |
7 | 7 | ||
8 | ifeq ($(CONFIG_PCI),y) | 8 | ifeq ($(CONFIG_PCI),y) |
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index 419c9943a7cb..ad742cec94fa 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c | |||
@@ -55,6 +55,9 @@ int hcd_buffer_create (struct usb_hcd *hcd) | |||
55 | char name [16]; | 55 | char name [16]; |
56 | int i, size; | 56 | int i, size; |
57 | 57 | ||
58 | if (!hcd->self.controller->dma_mask) | ||
59 | return 0; | ||
60 | |||
58 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { | 61 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
59 | if (!(size = pool_max [i])) | 62 | if (!(size = pool_max [i])) |
60 | continue; | 63 | continue; |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 83e815d3cd52..2684e15b813b 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -67,45 +67,45 @@ | |||
67 | /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */ | 67 | /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */ |
68 | #define ALLOW_SERIAL_NUMBER | 68 | #define ALLOW_SERIAL_NUMBER |
69 | 69 | ||
70 | static char *format_topo = | 70 | static const char *format_topo = |
71 | /* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */ | 71 | /* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */ |
72 | "\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n"; | 72 | "\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n"; |
73 | 73 | ||
74 | static char *format_string_manufacturer = | 74 | static const char *format_string_manufacturer = |
75 | /* S: Manufacturer=xxxx */ | 75 | /* S: Manufacturer=xxxx */ |
76 | "S: Manufacturer=%.100s\n"; | 76 | "S: Manufacturer=%.100s\n"; |
77 | 77 | ||
78 | static char *format_string_product = | 78 | static const char *format_string_product = |
79 | /* S: Product=xxxx */ | 79 | /* S: Product=xxxx */ |
80 | "S: Product=%.100s\n"; | 80 | "S: Product=%.100s\n"; |
81 | 81 | ||
82 | #ifdef ALLOW_SERIAL_NUMBER | 82 | #ifdef ALLOW_SERIAL_NUMBER |
83 | static char *format_string_serialnumber = | 83 | static const char *format_string_serialnumber = |
84 | /* S: SerialNumber=xxxx */ | 84 | /* S: SerialNumber=xxxx */ |
85 | "S: SerialNumber=%.100s\n"; | 85 | "S: SerialNumber=%.100s\n"; |
86 | #endif | 86 | #endif |
87 | 87 | ||
88 | static char *format_bandwidth = | 88 | static const char *format_bandwidth = |
89 | /* B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */ | 89 | /* B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */ |
90 | "B: Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n"; | 90 | "B: Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n"; |
91 | 91 | ||
92 | static char *format_device1 = | 92 | static const char *format_device1 = |
93 | /* D: Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */ | 93 | /* D: Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */ |
94 | "D: Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n"; | 94 | "D: Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n"; |
95 | 95 | ||
96 | static char *format_device2 = | 96 | static const char *format_device2 = |
97 | /* P: Vendor=xxxx ProdID=xxxx Rev=xx.xx */ | 97 | /* P: Vendor=xxxx ProdID=xxxx Rev=xx.xx */ |
98 | "P: Vendor=%04x ProdID=%04x Rev=%2x.%02x\n"; | 98 | "P: Vendor=%04x ProdID=%04x Rev=%2x.%02x\n"; |
99 | 99 | ||
100 | static char *format_config = | 100 | static const char *format_config = |
101 | /* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */ | 101 | /* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */ |
102 | "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n"; | 102 | "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n"; |
103 | 103 | ||
104 | static char *format_iface = | 104 | static const char *format_iface = |
105 | /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/ | 105 | /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/ |
106 | "I: If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; | 106 | "I: If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; |
107 | 107 | ||
108 | static char *format_endpt = | 108 | static const char *format_endpt = |
109 | /* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */ | 109 | /* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */ |
110 | "E: Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n"; | 110 | "E: Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n"; |
111 | 111 | ||
@@ -545,10 +545,10 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski | |||
545 | struct usb_device *childdev = usbdev->children[chix]; | 545 | struct usb_device *childdev = usbdev->children[chix]; |
546 | 546 | ||
547 | if (childdev) { | 547 | if (childdev) { |
548 | down(&childdev->serialize); | 548 | usb_lock_device(childdev); |
549 | ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, childdev, | 549 | ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, childdev, |
550 | bus, level + 1, chix, ++cnt); | 550 | bus, level + 1, chix, ++cnt); |
551 | up(&childdev->serialize); | 551 | usb_unlock_device(childdev); |
552 | if (ret == -EFAULT) | 552 | if (ret == -EFAULT) |
553 | return total_written; | 553 | return total_written; |
554 | total_written += ret; | 554 | total_written += ret; |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index b1d6e9af732d..2b68998fe4b3 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -402,7 +402,6 @@ static void driver_disconnect(struct usb_interface *intf) | |||
402 | } | 402 | } |
403 | 403 | ||
404 | struct usb_driver usbfs_driver = { | 404 | struct usb_driver usbfs_driver = { |
405 | .owner = THIS_MODULE, | ||
406 | .name = "usbfs", | 405 | .name = "usbfs", |
407 | .probe = driver_probe, | 406 | .probe = driver_probe, |
408 | .disconnect = driver_disconnect, | 407 | .disconnect = driver_disconnect, |
@@ -1350,9 +1349,7 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) | |||
1350 | /* let kernel drivers try to (re)bind to the interface */ | 1349 | /* let kernel drivers try to (re)bind to the interface */ |
1351 | case USBDEVFS_CONNECT: | 1350 | case USBDEVFS_CONNECT: |
1352 | usb_unlock_device(ps->dev); | 1351 | usb_unlock_device(ps->dev); |
1353 | usb_lock_all_devices(); | ||
1354 | bus_rescan_devices(intf->dev.bus); | 1352 | bus_rescan_devices(intf->dev.bus); |
1355 | usb_unlock_all_devices(); | ||
1356 | usb_lock_device(ps->dev); | 1353 | usb_lock_device(ps->dev); |
1357 | break; | 1354 | break; |
1358 | 1355 | ||
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c new file mode 100644 index 000000000000..076462c8ba2a --- /dev/null +++ b/drivers/usb/core/driver.c | |||
@@ -0,0 +1,472 @@ | |||
1 | /* | ||
2 | * drivers/usb/driver.c - most of the driver model stuff for usb | ||
3 | * | ||
4 | * (C) Copyright 2005 Greg Kroah-Hartman <gregkh@suse.de> | ||
5 | * | ||
6 | * based on drivers/usb/usb.c which had the following copyrights: | ||
7 | * (C) Copyright Linus Torvalds 1999 | ||
8 | * (C) Copyright Johannes Erdfelt 1999-2001 | ||
9 | * (C) Copyright Andreas Gal 1999 | ||
10 | * (C) Copyright Gregory P. Smith 1999 | ||
11 | * (C) Copyright Deti Fliegl 1999 (new USB architecture) | ||
12 | * (C) Copyright Randy Dunlap 2000 | ||
13 | * (C) Copyright David Brownell 2000-2004 | ||
14 | * (C) Copyright Yggdrasil Computing, Inc. 2000 | ||
15 | * (usb_device_id matching changes by Adam J. Richter) | ||
16 | * (C) Copyright Greg Kroah-Hartman 2002-2003 | ||
17 | * | ||
18 | * NOTE! This is not actually a driver at all, rather this is | ||
19 | * just a collection of helper routines that implement the | ||
20 | * generic USB things that the real drivers can use.. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <linux/config.h> | ||
25 | #include <linux/device.h> | ||
26 | #include <linux/usb.h> | ||
27 | #include "hcd.h" | ||
28 | #include "usb.h" | ||
29 | |||
30 | static int usb_match_one_id(struct usb_interface *interface, | ||
31 | const struct usb_device_id *id); | ||
32 | |||
33 | struct usb_dynid { | ||
34 | struct list_head node; | ||
35 | struct usb_device_id id; | ||
36 | }; | ||
37 | |||
38 | |||
39 | static int generic_probe(struct device *dev) | ||
40 | { | ||
41 | return 0; | ||
42 | } | ||
43 | static int generic_remove(struct device *dev) | ||
44 | { | ||
45 | struct usb_device *udev = to_usb_device(dev); | ||
46 | |||
47 | /* if this is only an unbind, not a physical disconnect, then | ||
48 | * unconfigure the device */ | ||
49 | if (udev->state == USB_STATE_CONFIGURED) | ||
50 | usb_set_configuration(udev, 0); | ||
51 | |||
52 | /* in case the call failed or the device was suspended */ | ||
53 | if (udev->state >= USB_STATE_CONFIGURED) | ||
54 | usb_disable_device(udev, 0); | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | struct device_driver usb_generic_driver = { | ||
59 | .owner = THIS_MODULE, | ||
60 | .name = "usb", | ||
61 | .bus = &usb_bus_type, | ||
62 | .probe = generic_probe, | ||
63 | .remove = generic_remove, | ||
64 | }; | ||
65 | |||
66 | /* Fun hack to determine if the struct device is a | ||
67 | * usb device or a usb interface. */ | ||
68 | int usb_generic_driver_data; | ||
69 | |||
70 | #ifdef CONFIG_HOTPLUG | ||
71 | |||
72 | /* | ||
73 | * Adds a new dynamic USBdevice ID to this driver, | ||
74 | * and cause the driver to probe for all devices again. | ||
75 | */ | ||
76 | static ssize_t store_new_id(struct device_driver *driver, | ||
77 | const char *buf, size_t count) | ||
78 | { | ||
79 | struct usb_driver *usb_drv = to_usb_driver(driver); | ||
80 | struct usb_dynid *dynid; | ||
81 | u32 idVendor = 0; | ||
82 | u32 idProduct = 0; | ||
83 | int fields = 0; | ||
84 | |||
85 | fields = sscanf(buf, "%x %x", &idVendor, &idProduct); | ||
86 | if (fields < 2) | ||
87 | return -EINVAL; | ||
88 | |||
89 | dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); | ||
90 | if (!dynid) | ||
91 | return -ENOMEM; | ||
92 | |||
93 | INIT_LIST_HEAD(&dynid->node); | ||
94 | dynid->id.idVendor = idVendor; | ||
95 | dynid->id.idProduct = idProduct; | ||
96 | dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; | ||
97 | |||
98 | spin_lock(&usb_drv->dynids.lock); | ||
99 | list_add_tail(&usb_drv->dynids.list, &dynid->node); | ||
100 | spin_unlock(&usb_drv->dynids.lock); | ||
101 | |||
102 | if (get_driver(driver)) { | ||
103 | driver_attach(driver); | ||
104 | put_driver(driver); | ||
105 | } | ||
106 | |||
107 | return count; | ||
108 | } | ||
109 | static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); | ||
110 | |||
111 | static int usb_create_newid_file(struct usb_driver *usb_drv) | ||
112 | { | ||
113 | int error = 0; | ||
114 | |||
115 | if (usb_drv->no_dynamic_id) | ||
116 | goto exit; | ||
117 | |||
118 | if (usb_drv->probe != NULL) | ||
119 | error = sysfs_create_file(&usb_drv->driver.kobj, | ||
120 | &driver_attr_new_id.attr); | ||
121 | exit: | ||
122 | return error; | ||
123 | } | ||
124 | |||
125 | static void usb_remove_newid_file(struct usb_driver *usb_drv) | ||
126 | { | ||
127 | if (usb_drv->no_dynamic_id) | ||
128 | return; | ||
129 | |||
130 | if (usb_drv->probe != NULL) | ||
131 | sysfs_remove_file(&usb_drv->driver.kobj, | ||
132 | &driver_attr_new_id.attr); | ||
133 | } | ||
134 | |||
135 | static void usb_free_dynids(struct usb_driver *usb_drv) | ||
136 | { | ||
137 | struct usb_dynid *dynid, *n; | ||
138 | |||
139 | spin_lock(&usb_drv->dynids.lock); | ||
140 | list_for_each_entry_safe(dynid, n, &usb_drv->dynids.list, node) { | ||
141 | list_del(&dynid->node); | ||
142 | kfree(dynid); | ||
143 | } | ||
144 | spin_unlock(&usb_drv->dynids.lock); | ||
145 | } | ||
146 | #else | ||
147 | static inline int usb_create_newid_file(struct usb_driver *usb_drv) | ||
148 | { | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static void usb_remove_newid_file(struct usb_driver *usb_drv) | ||
153 | { | ||
154 | } | ||
155 | |||
156 | static inline void usb_free_dynids(struct usb_driver *usb_drv) | ||
157 | { | ||
158 | } | ||
159 | #endif | ||
160 | |||
161 | static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf, | ||
162 | struct usb_driver *drv) | ||
163 | { | ||
164 | struct usb_dynid *dynid; | ||
165 | |||
166 | spin_lock(&drv->dynids.lock); | ||
167 | list_for_each_entry(dynid, &drv->dynids.list, node) { | ||
168 | if (usb_match_one_id(intf, &dynid->id)) { | ||
169 | spin_unlock(&drv->dynids.lock); | ||
170 | return &dynid->id; | ||
171 | } | ||
172 | } | ||
173 | spin_unlock(&drv->dynids.lock); | ||
174 | return NULL; | ||
175 | } | ||
176 | |||
177 | |||
178 | /* called from driver core with usb_bus_type.subsys writelock */ | ||
179 | static int usb_probe_interface(struct device *dev) | ||
180 | { | ||
181 | struct usb_interface * intf = to_usb_interface(dev); | ||
182 | struct usb_driver * driver = to_usb_driver(dev->driver); | ||
183 | const struct usb_device_id *id; | ||
184 | int error = -ENODEV; | ||
185 | |||
186 | dev_dbg(dev, "%s\n", __FUNCTION__); | ||
187 | |||
188 | if (!driver->probe) | ||
189 | return error; | ||
190 | /* FIXME we'd much prefer to just resume it ... */ | ||
191 | if (interface_to_usbdev(intf)->state == USB_STATE_SUSPENDED) | ||
192 | return -EHOSTUNREACH; | ||
193 | |||
194 | id = usb_match_id(intf, driver->id_table); | ||
195 | if (!id) | ||
196 | id = usb_match_dynamic_id(intf, driver); | ||
197 | if (id) { | ||
198 | dev_dbg(dev, "%s - got id\n", __FUNCTION__); | ||
199 | |||
200 | /* Interface "power state" doesn't correspond to any hardware | ||
201 | * state whatsoever. We use it to record when it's bound to | ||
202 | * a driver that may start I/0: it's not frozen/quiesced. | ||
203 | */ | ||
204 | mark_active(intf); | ||
205 | intf->condition = USB_INTERFACE_BINDING; | ||
206 | error = driver->probe(intf, id); | ||
207 | if (error) { | ||
208 | mark_quiesced(intf); | ||
209 | intf->condition = USB_INTERFACE_UNBOUND; | ||
210 | } else | ||
211 | intf->condition = USB_INTERFACE_BOUND; | ||
212 | } | ||
213 | |||
214 | return error; | ||
215 | } | ||
216 | |||
217 | /* called from driver core with usb_bus_type.subsys writelock */ | ||
218 | static int usb_unbind_interface(struct device *dev) | ||
219 | { | ||
220 | struct usb_interface *intf = to_usb_interface(dev); | ||
221 | struct usb_driver *driver = to_usb_driver(intf->dev.driver); | ||
222 | |||
223 | intf->condition = USB_INTERFACE_UNBINDING; | ||
224 | |||
225 | /* release all urbs for this interface */ | ||
226 | usb_disable_interface(interface_to_usbdev(intf), intf); | ||
227 | |||
228 | if (driver && driver->disconnect) | ||
229 | driver->disconnect(intf); | ||
230 | |||
231 | /* reset other interface state */ | ||
232 | usb_set_interface(interface_to_usbdev(intf), | ||
233 | intf->altsetting[0].desc.bInterfaceNumber, | ||
234 | 0); | ||
235 | usb_set_intfdata(intf, NULL); | ||
236 | intf->condition = USB_INTERFACE_UNBOUND; | ||
237 | mark_quiesced(intf); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | /* returns 0 if no match, 1 if match */ | ||
243 | static int usb_match_one_id(struct usb_interface *interface, | ||
244 | const struct usb_device_id *id) | ||
245 | { | ||
246 | struct usb_host_interface *intf; | ||
247 | struct usb_device *dev; | ||
248 | |||
249 | /* proc_connectinfo in devio.c may call us with id == NULL. */ | ||
250 | if (id == NULL) | ||
251 | return 0; | ||
252 | |||
253 | intf = interface->cur_altsetting; | ||
254 | dev = interface_to_usbdev(interface); | ||
255 | |||
256 | if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && | ||
257 | id->idVendor != le16_to_cpu(dev->descriptor.idVendor)) | ||
258 | return 0; | ||
259 | |||
260 | if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) && | ||
261 | id->idProduct != le16_to_cpu(dev->descriptor.idProduct)) | ||
262 | return 0; | ||
263 | |||
264 | /* No need to test id->bcdDevice_lo != 0, since 0 is never | ||
265 | greater than any unsigned number. */ | ||
266 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) && | ||
267 | (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice))) | ||
268 | return 0; | ||
269 | |||
270 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) && | ||
271 | (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice))) | ||
272 | return 0; | ||
273 | |||
274 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) && | ||
275 | (id->bDeviceClass != dev->descriptor.bDeviceClass)) | ||
276 | return 0; | ||
277 | |||
278 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && | ||
279 | (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass)) | ||
280 | return 0; | ||
281 | |||
282 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && | ||
283 | (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol)) | ||
284 | return 0; | ||
285 | |||
286 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && | ||
287 | (id->bInterfaceClass != intf->desc.bInterfaceClass)) | ||
288 | return 0; | ||
289 | |||
290 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) && | ||
291 | (id->bInterfaceSubClass != intf->desc.bInterfaceSubClass)) | ||
292 | return 0; | ||
293 | |||
294 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) && | ||
295 | (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol)) | ||
296 | return 0; | ||
297 | |||
298 | return 1; | ||
299 | } | ||
300 | /** | ||
301 | * usb_match_id - find first usb_device_id matching device or interface | ||
302 | * @interface: the interface of interest | ||
303 | * @id: array of usb_device_id structures, terminated by zero entry | ||
304 | * | ||
305 | * usb_match_id searches an array of usb_device_id's and returns | ||
306 | * the first one matching the device or interface, or null. | ||
307 | * This is used when binding (or rebinding) a driver to an interface. | ||
308 | * Most USB device drivers will use this indirectly, through the usb core, | ||
309 | * but some layered driver frameworks use it directly. | ||
310 | * These device tables are exported with MODULE_DEVICE_TABLE, through | ||
311 | * modutils, to support the driver loading functionality of USB hotplugging. | ||
312 | * | ||
313 | * What Matches: | ||
314 | * | ||
315 | * The "match_flags" element in a usb_device_id controls which | ||
316 | * members are used. If the corresponding bit is set, the | ||
317 | * value in the device_id must match its corresponding member | ||
318 | * in the device or interface descriptor, or else the device_id | ||
319 | * does not match. | ||
320 | * | ||
321 | * "driver_info" is normally used only by device drivers, | ||
322 | * but you can create a wildcard "matches anything" usb_device_id | ||
323 | * as a driver's "modules.usbmap" entry if you provide an id with | ||
324 | * only a nonzero "driver_info" field. If you do this, the USB device | ||
325 | * driver's probe() routine should use additional intelligence to | ||
326 | * decide whether to bind to the specified interface. | ||
327 | * | ||
328 | * What Makes Good usb_device_id Tables: | ||
329 | * | ||
330 | * The match algorithm is very simple, so that intelligence in | ||
331 | * driver selection must come from smart driver id records. | ||
332 | * Unless you have good reasons to use another selection policy, | ||
333 | * provide match elements only in related groups, and order match | ||
334 | * specifiers from specific to general. Use the macros provided | ||
335 | * for that purpose if you can. | ||
336 | * | ||
337 | * The most specific match specifiers use device descriptor | ||
338 | * data. These are commonly used with product-specific matches; | ||
339 | * the USB_DEVICE macro lets you provide vendor and product IDs, | ||
340 | * and you can also match against ranges of product revisions. | ||
341 | * These are widely used for devices with application or vendor | ||
342 | * specific bDeviceClass values. | ||
343 | * | ||
344 | * Matches based on device class/subclass/protocol specifications | ||
345 | * are slightly more general; use the USB_DEVICE_INFO macro, or | ||
346 | * its siblings. These are used with single-function devices | ||
347 | * where bDeviceClass doesn't specify that each interface has | ||
348 | * its own class. | ||
349 | * | ||
350 | * Matches based on interface class/subclass/protocol are the | ||
351 | * most general; they let drivers bind to any interface on a | ||
352 | * multiple-function device. Use the USB_INTERFACE_INFO | ||
353 | * macro, or its siblings, to match class-per-interface style | ||
354 | * devices (as recorded in bDeviceClass). | ||
355 | * | ||
356 | * Within those groups, remember that not all combinations are | ||
357 | * meaningful. For example, don't give a product version range | ||
358 | * without vendor and product IDs; or specify a protocol without | ||
359 | * its associated class and subclass. | ||
360 | */ | ||
361 | const struct usb_device_id *usb_match_id(struct usb_interface *interface, | ||
362 | const struct usb_device_id *id) | ||
363 | { | ||
364 | /* proc_connectinfo in devio.c may call us with id == NULL. */ | ||
365 | if (id == NULL) | ||
366 | return NULL; | ||
367 | |||
368 | /* It is important to check that id->driver_info is nonzero, | ||
369 | since an entry that is all zeroes except for a nonzero | ||
370 | id->driver_info is the way to create an entry that | ||
371 | indicates that the driver want to examine every | ||
372 | device and interface. */ | ||
373 | for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass || | ||
374 | id->driver_info; id++) { | ||
375 | if (usb_match_one_id(interface, id)) | ||
376 | return id; | ||
377 | } | ||
378 | |||
379 | return NULL; | ||
380 | } | ||
381 | EXPORT_SYMBOL_GPL(usb_match_id); | ||
382 | |||
383 | int usb_device_match(struct device *dev, struct device_driver *drv) | ||
384 | { | ||
385 | struct usb_interface *intf; | ||
386 | struct usb_driver *usb_drv; | ||
387 | const struct usb_device_id *id; | ||
388 | |||
389 | /* check for generic driver, which we don't match any device with */ | ||
390 | if (drv == &usb_generic_driver) | ||
391 | return 0; | ||
392 | |||
393 | intf = to_usb_interface(dev); | ||
394 | usb_drv = to_usb_driver(drv); | ||
395 | |||
396 | id = usb_match_id(intf, usb_drv->id_table); | ||
397 | if (id) | ||
398 | return 1; | ||
399 | |||
400 | id = usb_match_dynamic_id(intf, usb_drv); | ||
401 | if (id) | ||
402 | return 1; | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | /** | ||
407 | * usb_register_driver - register a USB driver | ||
408 | * @new_driver: USB operations for the driver | ||
409 | * @owner: module owner of this driver. | ||
410 | * | ||
411 | * Registers a USB driver with the USB core. The list of unattached | ||
412 | * interfaces will be rescanned whenever a new driver is added, allowing | ||
413 | * the new driver to attach to any recognized devices. | ||
414 | * Returns a negative error code on failure and 0 on success. | ||
415 | * | ||
416 | * NOTE: if you want your driver to use the USB major number, you must call | ||
417 | * usb_register_dev() to enable that functionality. This function no longer | ||
418 | * takes care of that. | ||
419 | */ | ||
420 | int usb_register_driver(struct usb_driver *new_driver, struct module *owner) | ||
421 | { | ||
422 | int retval = 0; | ||
423 | |||
424 | if (usb_disabled()) | ||
425 | return -ENODEV; | ||
426 | |||
427 | new_driver->driver.name = (char *)new_driver->name; | ||
428 | new_driver->driver.bus = &usb_bus_type; | ||
429 | new_driver->driver.probe = usb_probe_interface; | ||
430 | new_driver->driver.remove = usb_unbind_interface; | ||
431 | new_driver->driver.owner = owner; | ||
432 | spin_lock_init(&new_driver->dynids.lock); | ||
433 | INIT_LIST_HEAD(&new_driver->dynids.list); | ||
434 | |||
435 | retval = driver_register(&new_driver->driver); | ||
436 | |||
437 | if (!retval) { | ||
438 | pr_info("%s: registered new driver %s\n", | ||
439 | usbcore_name, new_driver->name); | ||
440 | usbfs_update_special(); | ||
441 | usb_create_newid_file(new_driver); | ||
442 | } else { | ||
443 | printk(KERN_ERR "%s: error %d registering driver %s\n", | ||
444 | usbcore_name, retval, new_driver->name); | ||
445 | } | ||
446 | |||
447 | return retval; | ||
448 | } | ||
449 | EXPORT_SYMBOL_GPL(usb_register_driver); | ||
450 | |||
451 | /** | ||
452 | * usb_deregister - unregister a USB driver | ||
453 | * @driver: USB operations of the driver to unregister | ||
454 | * Context: must be able to sleep | ||
455 | * | ||
456 | * Unlinks the specified driver from the internal USB driver list. | ||
457 | * | ||
458 | * NOTE: If you called usb_register_dev(), you still need to call | ||
459 | * usb_deregister_dev() to clean up your driver's allocated minor numbers, | ||
460 | * this * call will no longer do it for you. | ||
461 | */ | ||
462 | void usb_deregister(struct usb_driver *driver) | ||
463 | { | ||
464 | pr_info("%s: deregistering driver %s\n", usbcore_name, driver->name); | ||
465 | |||
466 | usb_remove_newid_file(driver); | ||
467 | usb_free_dynids(driver); | ||
468 | driver_unregister(&driver->driver); | ||
469 | |||
470 | usbfs_update_special(); | ||
471 | } | ||
472 | EXPORT_SYMBOL_GPL(usb_deregister); | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index da24c31ee00d..0018bbc4de34 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -857,9 +857,7 @@ static int register_root_hub (struct usb_device *usb_dev, | |||
857 | return (retval < 0) ? retval : -EMSGSIZE; | 857 | return (retval < 0) ? retval : -EMSGSIZE; |
858 | } | 858 | } |
859 | 859 | ||
860 | usb_lock_device (usb_dev); | ||
861 | retval = usb_new_device (usb_dev); | 860 | retval = usb_new_device (usb_dev); |
862 | usb_unlock_device (usb_dev); | ||
863 | if (retval) { | 861 | if (retval) { |
864 | usb_dev->bus->root_hub = NULL; | 862 | usb_dev->bus->root_hub = NULL; |
865 | dev_err (parent_dev, "can't register root hub for %s, %d\n", | 863 | dev_err (parent_dev, "can't register root hub for %s, %d\n", |
@@ -1827,8 +1825,6 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1827 | retval = -ENOMEM; | 1825 | retval = -ENOMEM; |
1828 | goto err_allocate_root_hub; | 1826 | goto err_allocate_root_hub; |
1829 | } | 1827 | } |
1830 | rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH : | ||
1831 | USB_SPEED_FULL; | ||
1832 | 1828 | ||
1833 | /* Although in principle hcd->driver->start() might need to use rhdev, | 1829 | /* Although in principle hcd->driver->start() might need to use rhdev, |
1834 | * none of the current drivers do. | 1830 | * none of the current drivers do. |
@@ -1846,6 +1842,9 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1846 | dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); | 1842 | dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); |
1847 | hcd->remote_wakeup = hcd->can_wakeup; | 1843 | hcd->remote_wakeup = hcd->can_wakeup; |
1848 | 1844 | ||
1845 | rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH : | ||
1846 | USB_SPEED_FULL; | ||
1847 | rhdev->bus_mA = min(500u, hcd->power_budget); | ||
1849 | if ((retval = register_root_hub(rhdev, hcd)) != 0) | 1848 | if ((retval = register_root_hub(rhdev, hcd)) != 0) |
1850 | goto err_register_root_hub; | 1849 | goto err_register_root_hub; |
1851 | 1850 | ||
@@ -1891,7 +1890,10 @@ void usb_remove_hcd(struct usb_hcd *hcd) | |||
1891 | spin_lock_irq (&hcd_root_hub_lock); | 1890 | spin_lock_irq (&hcd_root_hub_lock); |
1892 | hcd->rh_registered = 0; | 1891 | hcd->rh_registered = 0; |
1893 | spin_unlock_irq (&hcd_root_hub_lock); | 1892 | spin_unlock_irq (&hcd_root_hub_lock); |
1893 | |||
1894 | down(&usb_bus_list_lock); | ||
1894 | usb_disconnect(&hcd->self.root_hub); | 1895 | usb_disconnect(&hcd->self.root_hub); |
1896 | up(&usb_bus_list_lock); | ||
1895 | 1897 | ||
1896 | hcd->poll_rh = 0; | 1898 | hcd->poll_rh = 0; |
1897 | del_timer_sync(&hcd->rh_timer); | 1899 | del_timer_sync(&hcd->rh_timer); |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index c8a1b350e2cf..591b5aad1a18 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -380,6 +380,7 @@ extern int usb_find_interface_driver (struct usb_device *dev, | |||
380 | #ifdef CONFIG_PM | 380 | #ifdef CONFIG_PM |
381 | extern void usb_hcd_suspend_root_hub (struct usb_hcd *hcd); | 381 | extern void usb_hcd_suspend_root_hub (struct usb_hcd *hcd); |
382 | extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd); | 382 | extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd); |
383 | extern void usb_root_hub_lost_power (struct usb_device *rhdev); | ||
383 | extern int hcd_bus_suspend (struct usb_bus *bus); | 384 | extern int hcd_bus_suspend (struct usb_bus *bus); |
384 | extern int hcd_bus_resume (struct usb_bus *bus); | 385 | extern int hcd_bus_resume (struct usb_bus *bus); |
385 | #else | 386 | #else |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index f78bd124d290..650d5ee5871b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include "hub.h" | 32 | #include "hub.h" |
33 | 33 | ||
34 | /* Protect struct usb_device->state and ->children members | 34 | /* Protect struct usb_device->state and ->children members |
35 | * Note: Both are also protected by ->serialize, except that ->state can | 35 | * Note: Both are also protected by ->dev.sem, except that ->state can |
36 | * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ | 36 | * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ |
37 | static DEFINE_SPINLOCK(device_state_lock); | 37 | static DEFINE_SPINLOCK(device_state_lock); |
38 | 38 | ||
@@ -515,6 +515,31 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) | |||
515 | return ret; | 515 | return ret; |
516 | } | 516 | } |
517 | 517 | ||
518 | |||
519 | /* caller has locked the hub device */ | ||
520 | static void hub_pre_reset(struct usb_hub *hub, int disable_ports) | ||
521 | { | ||
522 | struct usb_device *hdev = hub->hdev; | ||
523 | int port1; | ||
524 | |||
525 | for (port1 = 1; port1 <= hdev->maxchild; ++port1) { | ||
526 | if (hdev->children[port1 - 1]) { | ||
527 | usb_disconnect(&hdev->children[port1 - 1]); | ||
528 | if (disable_ports) | ||
529 | hub_port_disable(hub, port1, 0); | ||
530 | } | ||
531 | } | ||
532 | hub_quiesce(hub); | ||
533 | } | ||
534 | |||
535 | /* caller has locked the hub device */ | ||
536 | static void hub_post_reset(struct usb_hub *hub) | ||
537 | { | ||
538 | hub_activate(hub); | ||
539 | hub_power_on(hub); | ||
540 | } | ||
541 | |||
542 | |||
518 | static int hub_configure(struct usb_hub *hub, | 543 | static int hub_configure(struct usb_hub *hub, |
519 | struct usb_endpoint_descriptor *endpoint) | 544 | struct usb_endpoint_descriptor *endpoint) |
520 | { | 545 | { |
@@ -677,26 +702,40 @@ static int hub_configure(struct usb_hub *hub, | |||
677 | * and battery-powered root hubs (may provide just 8 mA). | 702 | * and battery-powered root hubs (may provide just 8 mA). |
678 | */ | 703 | */ |
679 | ret = usb_get_status(hdev, USB_RECIP_DEVICE, 0, &hubstatus); | 704 | ret = usb_get_status(hdev, USB_RECIP_DEVICE, 0, &hubstatus); |
680 | if (ret < 0) { | 705 | if (ret < 2) { |
681 | message = "can't get hub status"; | 706 | message = "can't get hub status"; |
682 | goto fail; | 707 | goto fail; |
683 | } | 708 | } |
684 | le16_to_cpus(&hubstatus); | 709 | le16_to_cpus(&hubstatus); |
685 | if (hdev == hdev->bus->root_hub) { | 710 | if (hdev == hdev->bus->root_hub) { |
686 | struct usb_hcd *hcd = | 711 | if (hdev->bus_mA == 0 || hdev->bus_mA >= 500) |
687 | container_of(hdev->bus, struct usb_hcd, self); | 712 | hub->mA_per_port = 500; |
688 | 713 | else { | |
689 | hub->power_budget = min(500u, hcd->power_budget) / 2; | 714 | hub->mA_per_port = hdev->bus_mA; |
715 | hub->limited_power = 1; | ||
716 | } | ||
690 | } else if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) { | 717 | } else if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) { |
691 | dev_dbg(hub_dev, "hub controller current requirement: %dmA\n", | 718 | dev_dbg(hub_dev, "hub controller current requirement: %dmA\n", |
692 | hub->descriptor->bHubContrCurrent); | 719 | hub->descriptor->bHubContrCurrent); |
693 | hub->power_budget = (501 - hub->descriptor->bHubContrCurrent) | 720 | hub->limited_power = 1; |
694 | / 2; | 721 | if (hdev->maxchild > 0) { |
722 | int remaining = hdev->bus_mA - | ||
723 | hub->descriptor->bHubContrCurrent; | ||
724 | |||
725 | if (remaining < hdev->maxchild * 100) | ||
726 | dev_warn(hub_dev, | ||
727 | "insufficient power available " | ||
728 | "to use all downstream ports\n"); | ||
729 | hub->mA_per_port = 100; /* 7.2.1.1 */ | ||
730 | } | ||
731 | } else { /* Self-powered external hub */ | ||
732 | /* FIXME: What about battery-powered external hubs that | ||
733 | * provide less current per port? */ | ||
734 | hub->mA_per_port = 500; | ||
695 | } | 735 | } |
696 | if (hub->power_budget) | 736 | if (hub->mA_per_port < 500) |
697 | dev_dbg(hub_dev, "%dmA bus power budget for children\n", | 737 | dev_dbg(hub_dev, "%umA bus power budget for each child\n", |
698 | hub->power_budget * 2); | 738 | hub->mA_per_port); |
699 | |||
700 | 739 | ||
701 | ret = hub_hub_status(hub, &hubstatus, &hubchange); | 740 | ret = hub_hub_status(hub, &hubstatus, &hubchange); |
702 | if (ret < 0) { | 741 | if (ret < 0) { |
@@ -750,29 +789,10 @@ fail: | |||
750 | 789 | ||
751 | static unsigned highspeed_hubs; | 790 | static unsigned highspeed_hubs; |
752 | 791 | ||
753 | /* Called after the hub driver is unbound from a hub with children */ | ||
754 | static void hub_remove_children_work(void *__hub) | ||
755 | { | ||
756 | struct usb_hub *hub = __hub; | ||
757 | struct usb_device *hdev = hub->hdev; | ||
758 | int i; | ||
759 | |||
760 | kfree(hub); | ||
761 | |||
762 | usb_lock_device(hdev); | ||
763 | for (i = 0; i < hdev->maxchild; ++i) { | ||
764 | if (hdev->children[i]) | ||
765 | usb_disconnect(&hdev->children[i]); | ||
766 | } | ||
767 | usb_unlock_device(hdev); | ||
768 | usb_put_dev(hdev); | ||
769 | } | ||
770 | |||
771 | static void hub_disconnect(struct usb_interface *intf) | 792 | static void hub_disconnect(struct usb_interface *intf) |
772 | { | 793 | { |
773 | struct usb_hub *hub = usb_get_intfdata (intf); | 794 | struct usb_hub *hub = usb_get_intfdata (intf); |
774 | struct usb_device *hdev; | 795 | struct usb_device *hdev; |
775 | int n, port1; | ||
776 | 796 | ||
777 | usb_set_intfdata (intf, NULL); | 797 | usb_set_intfdata (intf, NULL); |
778 | hdev = hub->hdev; | 798 | hdev = hub->hdev; |
@@ -780,7 +800,9 @@ static void hub_disconnect(struct usb_interface *intf) | |||
780 | if (hdev->speed == USB_SPEED_HIGH) | 800 | if (hdev->speed == USB_SPEED_HIGH) |
781 | highspeed_hubs--; | 801 | highspeed_hubs--; |
782 | 802 | ||
783 | hub_quiesce(hub); | 803 | /* Disconnect all children and quiesce the hub */ |
804 | hub_pre_reset(hub, 1); | ||
805 | |||
784 | usb_free_urb(hub->urb); | 806 | usb_free_urb(hub->urb); |
785 | hub->urb = NULL; | 807 | hub->urb = NULL; |
786 | 808 | ||
@@ -800,27 +822,7 @@ static void hub_disconnect(struct usb_interface *intf) | |||
800 | hub->buffer = NULL; | 822 | hub->buffer = NULL; |
801 | } | 823 | } |
802 | 824 | ||
803 | /* If there are any children then this is an unbind only, not a | 825 | kfree(hub); |
804 | * physical disconnection. The active ports must be disabled | ||
805 | * and later on we must call usb_disconnect(). We can't call | ||
806 | * it now because we may not hold the hub's device lock. | ||
807 | */ | ||
808 | n = 0; | ||
809 | for (port1 = 1; port1 <= hdev->maxchild; ++port1) { | ||
810 | if (hdev->children[port1 - 1]) { | ||
811 | ++n; | ||
812 | hub_port_disable(hub, port1, 1); | ||
813 | } | ||
814 | } | ||
815 | |||
816 | if (n == 0) | ||
817 | kfree(hub); | ||
818 | else { | ||
819 | /* Reuse the hub->leds work_struct for our own purposes */ | ||
820 | INIT_WORK(&hub->leds, hub_remove_children_work, hub); | ||
821 | schedule_work(&hub->leds); | ||
822 | usb_get_dev(hdev); | ||
823 | } | ||
824 | } | 826 | } |
825 | 827 | ||
826 | static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) | 828 | static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) |
@@ -917,26 +919,6 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data) | |||
917 | } | 919 | } |
918 | } | 920 | } |
919 | 921 | ||
920 | /* caller has locked the hub device */ | ||
921 | static void hub_pre_reset(struct usb_hub *hub) | ||
922 | { | ||
923 | struct usb_device *hdev = hub->hdev; | ||
924 | int i; | ||
925 | |||
926 | for (i = 0; i < hdev->maxchild; ++i) { | ||
927 | if (hdev->children[i]) | ||
928 | usb_disconnect(&hdev->children[i]); | ||
929 | } | ||
930 | hub_quiesce(hub); | ||
931 | } | ||
932 | |||
933 | /* caller has locked the hub device */ | ||
934 | static void hub_post_reset(struct usb_hub *hub) | ||
935 | { | ||
936 | hub_activate(hub); | ||
937 | hub_power_on(hub); | ||
938 | } | ||
939 | |||
940 | 922 | ||
941 | /* grab device/port lock, returning index of that port (zero based). | 923 | /* grab device/port lock, returning index of that port (zero based). |
942 | * protects the upstream link used by this device from concurrent | 924 | * protects the upstream link used by this device from concurrent |
@@ -964,24 +946,21 @@ static int locktree(struct usb_device *udev) | |||
964 | t = locktree(hdev); | 946 | t = locktree(hdev); |
965 | if (t < 0) | 947 | if (t < 0) |
966 | return t; | 948 | return t; |
967 | for (t = 0; t < hdev->maxchild; t++) { | ||
968 | if (hdev->children[t] == udev) { | ||
969 | /* everything is fail-fast once disconnect | ||
970 | * processing starts | ||
971 | */ | ||
972 | if (udev->state == USB_STATE_NOTATTACHED) | ||
973 | break; | ||
974 | 949 | ||
975 | /* when everyone grabs locks top->bottom, | 950 | /* everything is fail-fast once disconnect |
976 | * non-overlapping work may be concurrent | 951 | * processing starts |
977 | */ | 952 | */ |
978 | down(&udev->serialize); | 953 | if (udev->state == USB_STATE_NOTATTACHED) { |
979 | up(&hdev->serialize); | 954 | usb_unlock_device(hdev); |
980 | return t + 1; | 955 | return -ENODEV; |
981 | } | ||
982 | } | 956 | } |
957 | |||
958 | /* when everyone grabs locks top->bottom, | ||
959 | * non-overlapping work may be concurrent | ||
960 | */ | ||
961 | usb_lock_device(udev); | ||
983 | usb_unlock_device(hdev); | 962 | usb_unlock_device(hdev); |
984 | return -ENODEV; | 963 | return udev->portnum; |
985 | } | 964 | } |
986 | 965 | ||
987 | static void recursively_mark_NOTATTACHED(struct usb_device *udev) | 966 | static void recursively_mark_NOTATTACHED(struct usb_device *udev) |
@@ -1039,6 +1018,39 @@ void usb_set_device_state(struct usb_device *udev, | |||
1039 | EXPORT_SYMBOL(usb_set_device_state); | 1018 | EXPORT_SYMBOL(usb_set_device_state); |
1040 | 1019 | ||
1041 | 1020 | ||
1021 | #ifdef CONFIG_PM | ||
1022 | |||
1023 | /** | ||
1024 | * usb_root_hub_lost_power - called by HCD if the root hub lost Vbus power | ||
1025 | * @rhdev: struct usb_device for the root hub | ||
1026 | * | ||
1027 | * The USB host controller driver calls this function when its root hub | ||
1028 | * is resumed and Vbus power has been interrupted or the controller | ||
1029 | * has been reset. The routine marks all the children of the root hub | ||
1030 | * as NOTATTACHED and marks logical connect-change events on their ports. | ||
1031 | */ | ||
1032 | void usb_root_hub_lost_power(struct usb_device *rhdev) | ||
1033 | { | ||
1034 | struct usb_hub *hub; | ||
1035 | int port1; | ||
1036 | unsigned long flags; | ||
1037 | |||
1038 | dev_warn(&rhdev->dev, "root hub lost power or was reset\n"); | ||
1039 | spin_lock_irqsave(&device_state_lock, flags); | ||
1040 | hub = hdev_to_hub(rhdev); | ||
1041 | for (port1 = 1; port1 <= rhdev->maxchild; ++port1) { | ||
1042 | if (rhdev->children[port1 - 1]) { | ||
1043 | recursively_mark_NOTATTACHED( | ||
1044 | rhdev->children[port1 - 1]); | ||
1045 | set_bit(port1, hub->change_bits); | ||
1046 | } | ||
1047 | } | ||
1048 | spin_unlock_irqrestore(&device_state_lock, flags); | ||
1049 | } | ||
1050 | EXPORT_SYMBOL_GPL(usb_root_hub_lost_power); | ||
1051 | |||
1052 | #endif | ||
1053 | |||
1042 | static void choose_address(struct usb_device *udev) | 1054 | static void choose_address(struct usb_device *udev) |
1043 | { | 1055 | { |
1044 | int devnum; | 1056 | int devnum; |
@@ -1099,16 +1111,10 @@ void usb_disconnect(struct usb_device **pdev) | |||
1099 | * this quiesces everyting except pending urbs. | 1111 | * this quiesces everyting except pending urbs. |
1100 | */ | 1112 | */ |
1101 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); | 1113 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); |
1102 | |||
1103 | /* lock the bus list on behalf of HCDs unregistering their root hubs */ | ||
1104 | if (!udev->parent) { | ||
1105 | down(&usb_bus_list_lock); | ||
1106 | usb_lock_device(udev); | ||
1107 | } else | ||
1108 | down(&udev->serialize); | ||
1109 | |||
1110 | dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum); | 1114 | dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum); |
1111 | 1115 | ||
1116 | usb_lock_device(udev); | ||
1117 | |||
1112 | /* Free up all the children before we remove this device */ | 1118 | /* Free up all the children before we remove this device */ |
1113 | for (i = 0; i < USB_MAXCHILDREN; i++) { | 1119 | for (i = 0; i < USB_MAXCHILDREN; i++) { |
1114 | if (udev->children[i]) | 1120 | if (udev->children[i]) |
@@ -1136,54 +1142,112 @@ void usb_disconnect(struct usb_device **pdev) | |||
1136 | *pdev = NULL; | 1142 | *pdev = NULL; |
1137 | spin_unlock_irq(&device_state_lock); | 1143 | spin_unlock_irq(&device_state_lock); |
1138 | 1144 | ||
1139 | if (!udev->parent) { | 1145 | usb_unlock_device(udev); |
1140 | usb_unlock_device(udev); | ||
1141 | up(&usb_bus_list_lock); | ||
1142 | } else | ||
1143 | up(&udev->serialize); | ||
1144 | 1146 | ||
1145 | device_unregister(&udev->dev); | 1147 | device_unregister(&udev->dev); |
1146 | } | 1148 | } |
1147 | 1149 | ||
1150 | static inline const char *plural(int n) | ||
1151 | { | ||
1152 | return (n == 1 ? "" : "s"); | ||
1153 | } | ||
1154 | |||
1148 | static int choose_configuration(struct usb_device *udev) | 1155 | static int choose_configuration(struct usb_device *udev) |
1149 | { | 1156 | { |
1150 | int c, i; | 1157 | int i; |
1158 | u16 devstatus; | ||
1159 | int bus_powered; | ||
1160 | int num_configs; | ||
1161 | struct usb_host_config *c, *best; | ||
1162 | |||
1163 | /* If this fails, assume the device is bus-powered */ | ||
1164 | devstatus = 0; | ||
1165 | usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); | ||
1166 | le16_to_cpus(&devstatus); | ||
1167 | bus_powered = ((devstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0); | ||
1168 | dev_dbg(&udev->dev, "device is %s-powered\n", | ||
1169 | bus_powered ? "bus" : "self"); | ||
1170 | |||
1171 | best = NULL; | ||
1172 | c = udev->config; | ||
1173 | num_configs = udev->descriptor.bNumConfigurations; | ||
1174 | for (i = 0; i < num_configs; (i++, c++)) { | ||
1175 | struct usb_interface_descriptor *desc = | ||
1176 | &c->intf_cache[0]->altsetting->desc; | ||
1177 | |||
1178 | /* | ||
1179 | * HP's USB bus-powered keyboard has only one configuration | ||
1180 | * and it claims to be self-powered; other devices may have | ||
1181 | * similar errors in their descriptors. If the next test | ||
1182 | * were allowed to execute, such configurations would always | ||
1183 | * be rejected and the devices would not work as expected. | ||
1184 | */ | ||
1185 | #if 0 | ||
1186 | /* Rule out self-powered configs for a bus-powered device */ | ||
1187 | if (bus_powered && (c->desc.bmAttributes & | ||
1188 | USB_CONFIG_ATT_SELFPOWER)) | ||
1189 | continue; | ||
1190 | #endif | ||
1151 | 1191 | ||
1152 | /* NOTE: this should interact with hub power budgeting */ | 1192 | /* |
1193 | * The next test may not be as effective as it should be. | ||
1194 | * Some hubs have errors in their descriptor, claiming | ||
1195 | * to be self-powered when they are really bus-powered. | ||
1196 | * We will overestimate the amount of current such hubs | ||
1197 | * make available for each port. | ||
1198 | * | ||
1199 | * This is a fairly benign sort of failure. It won't | ||
1200 | * cause us to reject configurations that we should have | ||
1201 | * accepted. | ||
1202 | */ | ||
1153 | 1203 | ||
1154 | c = udev->config[0].desc.bConfigurationValue; | 1204 | /* Rule out configs that draw too much bus current */ |
1155 | if (udev->descriptor.bNumConfigurations != 1) { | 1205 | if (c->desc.bMaxPower * 2 > udev->bus_mA) |
1156 | for (i = 0; i < udev->descriptor.bNumConfigurations; i++) { | 1206 | continue; |
1157 | struct usb_interface_descriptor *desc; | ||
1158 | 1207 | ||
1159 | /* heuristic: Linux is more likely to have class | 1208 | /* If the first config's first interface is COMM/2/0xff |
1160 | * drivers, so avoid vendor-specific interfaces. | 1209 | * (MSFT RNDIS), rule it out unless Linux has host-side |
1161 | */ | 1210 | * RNDIS support. */ |
1162 | desc = &udev->config[i].intf_cache[0] | 1211 | if (i == 0 && desc->bInterfaceClass == USB_CLASS_COMM |
1163 | ->altsetting->desc; | 1212 | && desc->bInterfaceSubClass == 2 |
1164 | if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) | 1213 | && desc->bInterfaceProtocol == 0xff) { |
1165 | continue; | 1214 | #ifndef CONFIG_USB_NET_RNDIS |
1166 | /* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS. | 1215 | continue; |
1167 | * MSFT needs this to be the first config; never use | 1216 | #else |
1168 | * it as the default unless Linux has host-side RNDIS. | 1217 | best = c; |
1169 | * A second config would ideally be CDC-Ethernet, but | 1218 | #endif |
1170 | * may instead be the "vendor specific" CDC subset | 1219 | } |
1171 | * long used by ARM Linux for sa1100 or pxa255. | 1220 | |
1172 | */ | 1221 | /* From the remaining configs, choose the first one whose |
1173 | if (desc->bInterfaceClass == USB_CLASS_COMM | 1222 | * first interface is for a non-vendor-specific class. |
1174 | && desc->bInterfaceSubClass == 2 | 1223 | * Reason: Linux is more likely to have a class driver |
1175 | && desc->bInterfaceProtocol == 0xff) { | 1224 | * than a vendor-specific driver. */ |
1176 | c = udev->config[1].desc.bConfigurationValue; | 1225 | else if (udev->descriptor.bDeviceClass != |
1177 | continue; | 1226 | USB_CLASS_VENDOR_SPEC && |
1178 | } | 1227 | desc->bInterfaceClass != |
1179 | c = udev->config[i].desc.bConfigurationValue; | 1228 | USB_CLASS_VENDOR_SPEC) { |
1229 | best = c; | ||
1180 | break; | 1230 | break; |
1181 | } | 1231 | } |
1232 | |||
1233 | /* If all the remaining configs are vendor-specific, | ||
1234 | * choose the first one. */ | ||
1235 | else if (!best) | ||
1236 | best = c; | ||
1237 | } | ||
1238 | |||
1239 | if (best) { | ||
1240 | i = best->desc.bConfigurationValue; | ||
1182 | dev_info(&udev->dev, | 1241 | dev_info(&udev->dev, |
1183 | "configuration #%d chosen from %d choices\n", | 1242 | "configuration #%d chosen from %d choice%s\n", |
1184 | c, udev->descriptor.bNumConfigurations); | 1243 | i, num_configs, plural(num_configs)); |
1244 | } else { | ||
1245 | i = -1; | ||
1246 | dev_warn(&udev->dev, | ||
1247 | "no configuration chosen from %d choice%s\n", | ||
1248 | num_configs, plural(num_configs)); | ||
1185 | } | 1249 | } |
1186 | return c; | 1250 | return i; |
1187 | } | 1251 | } |
1188 | 1252 | ||
1189 | #ifdef DEBUG | 1253 | #ifdef DEBUG |
@@ -1210,8 +1274,8 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) | |||
1210 | * | 1274 | * |
1211 | * This is called with devices which have been enumerated, but not yet | 1275 | * This is called with devices which have been enumerated, but not yet |
1212 | * configured. The device descriptor is available, but not descriptors | 1276 | * configured. The device descriptor is available, but not descriptors |
1213 | * for any device configuration. The caller must have locked udev and | 1277 | * for any device configuration. The caller must have locked either |
1214 | * either the parent hub (if udev is a normal device) or else the | 1278 | * the parent hub (if udev is a normal device) or else the |
1215 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to | 1279 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to |
1216 | * udev has already been installed, but udev is not yet visible through | 1280 | * udev has already been installed, but udev is not yet visible through |
1217 | * sysfs or other filesystem code. | 1281 | * sysfs or other filesystem code. |
@@ -1221,8 +1285,7 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) | |||
1221 | * | 1285 | * |
1222 | * This call is synchronous, and may not be used in an interrupt context. | 1286 | * This call is synchronous, and may not be used in an interrupt context. |
1223 | * | 1287 | * |
1224 | * Only the hub driver should ever call this; root hub registration | 1288 | * Only the hub driver or root-hub registrar should ever call this. |
1225 | * uses it indirectly. | ||
1226 | */ | 1289 | */ |
1227 | int usb_new_device(struct usb_device *udev) | 1290 | int usb_new_device(struct usb_device *udev) |
1228 | { | 1291 | { |
@@ -1269,15 +1332,9 @@ int usb_new_device(struct usb_device *udev) | |||
1269 | le16_to_cpu(udev->config[0].desc.wTotalLength), | 1332 | le16_to_cpu(udev->config[0].desc.wTotalLength), |
1270 | USB_DT_OTG, (void **) &desc) == 0) { | 1333 | USB_DT_OTG, (void **) &desc) == 0) { |
1271 | if (desc->bmAttributes & USB_OTG_HNP) { | 1334 | if (desc->bmAttributes & USB_OTG_HNP) { |
1272 | unsigned port1; | 1335 | unsigned port1 = udev->portnum; |
1273 | struct usb_device *root = udev->parent; | 1336 | struct usb_device *root = udev->parent; |
1274 | 1337 | ||
1275 | for (port1 = 1; port1 <= root->maxchild; | ||
1276 | port1++) { | ||
1277 | if (root->children[port1-1] == udev) | ||
1278 | break; | ||
1279 | } | ||
1280 | |||
1281 | dev_info(&udev->dev, | 1338 | dev_info(&udev->dev, |
1282 | "Dual-Role OTG device on %sHNP port\n", | 1339 | "Dual-Role OTG device on %sHNP port\n", |
1283 | (port1 == bus->otg_port) | 1340 | (port1 == bus->otg_port) |
@@ -1331,27 +1388,27 @@ int usb_new_device(struct usb_device *udev) | |||
1331 | } | 1388 | } |
1332 | usb_create_sysfs_dev_files (udev); | 1389 | usb_create_sysfs_dev_files (udev); |
1333 | 1390 | ||
1391 | usb_lock_device(udev); | ||
1392 | |||
1334 | /* choose and set the configuration. that registers the interfaces | 1393 | /* choose and set the configuration. that registers the interfaces |
1335 | * with the driver core, and lets usb device drivers bind to them. | 1394 | * with the driver core, and lets usb device drivers bind to them. |
1336 | */ | 1395 | */ |
1337 | c = choose_configuration(udev); | 1396 | c = choose_configuration(udev); |
1338 | if (c < 0) | 1397 | if (c >= 0) { |
1339 | dev_warn(&udev->dev, | ||
1340 | "can't choose an initial configuration\n"); | ||
1341 | else { | ||
1342 | err = usb_set_configuration(udev, c); | 1398 | err = usb_set_configuration(udev, c); |
1343 | if (err) { | 1399 | if (err) { |
1344 | dev_err(&udev->dev, "can't set config #%d, error %d\n", | 1400 | dev_err(&udev->dev, "can't set config #%d, error %d\n", |
1345 | c, err); | 1401 | c, err); |
1346 | usb_remove_sysfs_dev_files(udev); | 1402 | /* This need not be fatal. The user can try to |
1347 | device_del(&udev->dev); | 1403 | * set other configurations. */ |
1348 | goto fail; | ||
1349 | } | 1404 | } |
1350 | } | 1405 | } |
1351 | 1406 | ||
1352 | /* USB device state == configured ... usable */ | 1407 | /* USB device state == configured ... usable */ |
1353 | usb_notify_add_device(udev); | 1408 | usb_notify_add_device(udev); |
1354 | 1409 | ||
1410 | usb_unlock_device(udev); | ||
1411 | |||
1355 | return 0; | 1412 | return 0; |
1356 | 1413 | ||
1357 | fail: | 1414 | fail: |
@@ -1654,15 +1711,9 @@ static int __usb_suspend_device (struct usb_device *udev, int port1) | |||
1654 | int usb_suspend_device(struct usb_device *udev) | 1711 | int usb_suspend_device(struct usb_device *udev) |
1655 | { | 1712 | { |
1656 | #ifdef CONFIG_USB_SUSPEND | 1713 | #ifdef CONFIG_USB_SUSPEND |
1657 | int port1, status; | 1714 | if (udev->state == USB_STATE_NOTATTACHED) |
1658 | 1715 | return -ENODEV; | |
1659 | port1 = locktree(udev); | 1716 | return __usb_suspend_device(udev, udev->portnum); |
1660 | if (port1 < 0) | ||
1661 | return port1; | ||
1662 | |||
1663 | status = __usb_suspend_device(udev, port1); | ||
1664 | usb_unlock_device(udev); | ||
1665 | return status; | ||
1666 | #else | 1717 | #else |
1667 | /* NOTE: udev->state unchanged, it's not lying ... */ | 1718 | /* NOTE: udev->state unchanged, it's not lying ... */ |
1668 | udev->dev.power.power_state = PMSG_SUSPEND; | 1719 | udev->dev.power.power_state = PMSG_SUSPEND; |
@@ -1694,13 +1745,14 @@ static int finish_device_resume(struct usb_device *udev) | |||
1694 | usb_set_device_state(udev, udev->actconfig | 1745 | usb_set_device_state(udev, udev->actconfig |
1695 | ? USB_STATE_CONFIGURED | 1746 | ? USB_STATE_CONFIGURED |
1696 | : USB_STATE_ADDRESS); | 1747 | : USB_STATE_ADDRESS); |
1748 | udev->dev.power.power_state = PMSG_ON; | ||
1697 | 1749 | ||
1698 | /* 10.5.4.5 says be sure devices in the tree are still there. | 1750 | /* 10.5.4.5 says be sure devices in the tree are still there. |
1699 | * For now let's assume the device didn't go crazy on resume, | 1751 | * For now let's assume the device didn't go crazy on resume, |
1700 | * and device drivers will know about any resume quirks. | 1752 | * and device drivers will know about any resume quirks. |
1701 | */ | 1753 | */ |
1702 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); | 1754 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); |
1703 | if (status < 0) | 1755 | if (status < 2) |
1704 | dev_dbg(&udev->dev, | 1756 | dev_dbg(&udev->dev, |
1705 | "gone after usb resume? status %d\n", | 1757 | "gone after usb resume? status %d\n", |
1706 | status); | 1758 | status); |
@@ -1709,7 +1761,7 @@ static int finish_device_resume(struct usb_device *udev) | |||
1709 | int (*resume)(struct device *); | 1761 | int (*resume)(struct device *); |
1710 | 1762 | ||
1711 | le16_to_cpus(&devstatus); | 1763 | le16_to_cpus(&devstatus); |
1712 | if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP) | 1764 | if ((devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) |
1713 | && udev->parent) { | 1765 | && udev->parent) { |
1714 | status = usb_control_msg(udev, | 1766 | status = usb_control_msg(udev, |
1715 | usb_sndctrlpipe(udev, 0), | 1767 | usb_sndctrlpipe(udev, 0), |
@@ -1729,8 +1781,14 @@ static int finish_device_resume(struct usb_device *udev) | |||
1729 | * may have a child resume event to deal with soon | 1781 | * may have a child resume event to deal with soon |
1730 | */ | 1782 | */ |
1731 | resume = udev->dev.bus->resume; | 1783 | resume = udev->dev.bus->resume; |
1732 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) | 1784 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { |
1733 | (void) resume(&udev->actconfig->interface[i]->dev); | 1785 | struct device *dev = |
1786 | &udev->actconfig->interface[i]->dev; | ||
1787 | |||
1788 | down(&dev->sem); | ||
1789 | (void) resume(dev); | ||
1790 | up(&dev->sem); | ||
1791 | } | ||
1734 | status = 0; | 1792 | status = 0; |
1735 | 1793 | ||
1736 | } else if (udev->devnum <= 0) { | 1794 | } else if (udev->devnum <= 0) { |
@@ -1813,11 +1871,10 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev) | |||
1813 | */ | 1871 | */ |
1814 | int usb_resume_device(struct usb_device *udev) | 1872 | int usb_resume_device(struct usb_device *udev) |
1815 | { | 1873 | { |
1816 | int port1, status; | 1874 | int status; |
1817 | 1875 | ||
1818 | port1 = locktree(udev); | 1876 | if (udev->state == USB_STATE_NOTATTACHED) |
1819 | if (port1 < 0) | 1877 | return -ENODEV; |
1820 | return port1; | ||
1821 | 1878 | ||
1822 | #ifdef CONFIG_USB_SUSPEND | 1879 | #ifdef CONFIG_USB_SUSPEND |
1823 | /* selective resume of one downstream hub-to-device port */ | 1880 | /* selective resume of one downstream hub-to-device port */ |
@@ -1826,7 +1883,7 @@ int usb_resume_device(struct usb_device *udev) | |||
1826 | // NOTE swsusp may bork us, device state being wrong... | 1883 | // NOTE swsusp may bork us, device state being wrong... |
1827 | // NOTE this fails if parent is also suspended... | 1884 | // NOTE this fails if parent is also suspended... |
1828 | status = hub_port_resume(hdev_to_hub(udev->parent), | 1885 | status = hub_port_resume(hdev_to_hub(udev->parent), |
1829 | port1, udev); | 1886 | udev->portnum, udev); |
1830 | } else | 1887 | } else |
1831 | status = 0; | 1888 | status = 0; |
1832 | } else | 1889 | } else |
@@ -1836,13 +1893,11 @@ int usb_resume_device(struct usb_device *udev) | |||
1836 | dev_dbg(&udev->dev, "can't resume, status %d\n", | 1893 | dev_dbg(&udev->dev, "can't resume, status %d\n", |
1837 | status); | 1894 | status); |
1838 | 1895 | ||
1839 | usb_unlock_device(udev); | ||
1840 | |||
1841 | /* rebind drivers that had no suspend() */ | 1896 | /* rebind drivers that had no suspend() */ |
1842 | if (status == 0) { | 1897 | if (status == 0) { |
1843 | usb_lock_all_devices(); | 1898 | usb_unlock_device(udev); |
1844 | bus_rescan_devices(&usb_bus_type); | 1899 | bus_rescan_devices(&usb_bus_type); |
1845 | usb_unlock_all_devices(); | 1900 | usb_lock_device(udev); |
1846 | } | 1901 | } |
1847 | return status; | 1902 | return status; |
1848 | } | 1903 | } |
@@ -1856,14 +1911,14 @@ static int remote_wakeup(struct usb_device *udev) | |||
1856 | /* don't repeat RESUME sequence if this device | 1911 | /* don't repeat RESUME sequence if this device |
1857 | * was already woken up by some other task | 1912 | * was already woken up by some other task |
1858 | */ | 1913 | */ |
1859 | down(&udev->serialize); | 1914 | usb_lock_device(udev); |
1860 | if (udev->state == USB_STATE_SUSPENDED) { | 1915 | if (udev->state == USB_STATE_SUSPENDED) { |
1861 | dev_dbg(&udev->dev, "RESUME (wakeup)\n"); | 1916 | dev_dbg(&udev->dev, "RESUME (wakeup)\n"); |
1862 | /* TRSMRCY = 10 msec */ | 1917 | /* TRSMRCY = 10 msec */ |
1863 | msleep(10); | 1918 | msleep(10); |
1864 | status = finish_device_resume(udev); | 1919 | status = finish_device_resume(udev); |
1865 | } | 1920 | } |
1866 | up(&udev->serialize); | 1921 | usb_unlock_device(udev); |
1867 | #endif | 1922 | #endif |
1868 | return status; | 1923 | return status; |
1869 | } | 1924 | } |
@@ -1964,7 +2019,7 @@ static int hub_resume(struct usb_interface *intf) | |||
1964 | 2019 | ||
1965 | if (!udev || status < 0) | 2020 | if (!udev || status < 0) |
1966 | continue; | 2021 | continue; |
1967 | down (&udev->serialize); | 2022 | usb_lock_device(udev); |
1968 | if (portstat & USB_PORT_STAT_SUSPEND) | 2023 | if (portstat & USB_PORT_STAT_SUSPEND) |
1969 | status = hub_port_resume(hub, port1, udev); | 2024 | status = hub_port_resume(hub, port1, udev); |
1970 | else { | 2025 | else { |
@@ -1975,7 +2030,7 @@ static int hub_resume(struct usb_interface *intf) | |||
1975 | hub_port_logical_disconnect(hub, port1); | 2030 | hub_port_logical_disconnect(hub, port1); |
1976 | } | 2031 | } |
1977 | } | 2032 | } |
1978 | up(&udev->serialize); | 2033 | usb_unlock_device(udev); |
1979 | } | 2034 | } |
1980 | } | 2035 | } |
1981 | #endif | 2036 | #endif |
@@ -2359,39 +2414,36 @@ hub_power_remaining (struct usb_hub *hub) | |||
2359 | { | 2414 | { |
2360 | struct usb_device *hdev = hub->hdev; | 2415 | struct usb_device *hdev = hub->hdev; |
2361 | int remaining; | 2416 | int remaining; |
2362 | unsigned i; | 2417 | int port1; |
2363 | 2418 | ||
2364 | remaining = hub->power_budget; | 2419 | if (!hub->limited_power) |
2365 | if (!remaining) /* self-powered */ | ||
2366 | return 0; | 2420 | return 0; |
2367 | 2421 | ||
2368 | for (i = 0; i < hdev->maxchild; i++) { | 2422 | remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent; |
2369 | struct usb_device *udev = hdev->children[i]; | 2423 | for (port1 = 1; port1 <= hdev->maxchild; ++port1) { |
2370 | int delta, ceiling; | 2424 | struct usb_device *udev = hdev->children[port1 - 1]; |
2425 | int delta; | ||
2371 | 2426 | ||
2372 | if (!udev) | 2427 | if (!udev) |
2373 | continue; | 2428 | continue; |
2374 | 2429 | ||
2375 | /* 100mA per-port ceiling, or 8mA for OTG ports */ | 2430 | /* Unconfigured devices may not use more than 100mA, |
2376 | if (i != (udev->bus->otg_port - 1) || hdev->parent) | 2431 | * or 8mA for OTG ports */ |
2377 | ceiling = 50; | ||
2378 | else | ||
2379 | ceiling = 4; | ||
2380 | |||
2381 | if (udev->actconfig) | 2432 | if (udev->actconfig) |
2382 | delta = udev->actconfig->desc.bMaxPower; | 2433 | delta = udev->actconfig->desc.bMaxPower * 2; |
2434 | else if (port1 != udev->bus->otg_port || hdev->parent) | ||
2435 | delta = 100; | ||
2383 | else | 2436 | else |
2384 | delta = ceiling; | 2437 | delta = 8; |
2385 | // dev_dbg(&udev->dev, "budgeted %dmA\n", 2 * delta); | 2438 | if (delta > hub->mA_per_port) |
2386 | if (delta > ceiling) | 2439 | dev_warn(&udev->dev, "%dmA is over %umA budget " |
2387 | dev_warn(&udev->dev, "%dmA over %dmA budget!\n", | 2440 | "for port %d!\n", |
2388 | 2 * (delta - ceiling), 2 * ceiling); | 2441 | delta, hub->mA_per_port, port1); |
2389 | remaining -= delta; | 2442 | remaining -= delta; |
2390 | } | 2443 | } |
2391 | if (remaining < 0) { | 2444 | if (remaining < 0) { |
2392 | dev_warn(hub->intfdev, | 2445 | dev_warn(hub->intfdev, "%dmA over power budget!\n", |
2393 | "%dmA over power budget!\n", | 2446 | - remaining); |
2394 | -2 * remaining); | ||
2395 | remaining = 0; | 2447 | remaining = 0; |
2396 | } | 2448 | } |
2397 | return remaining; | 2449 | return remaining; |
@@ -2486,7 +2538,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2486 | 2538 | ||
2487 | usb_set_device_state(udev, USB_STATE_POWERED); | 2539 | usb_set_device_state(udev, USB_STATE_POWERED); |
2488 | udev->speed = USB_SPEED_UNKNOWN; | 2540 | udev->speed = USB_SPEED_UNKNOWN; |
2489 | 2541 | udev->bus_mA = hub->mA_per_port; | |
2542 | |||
2490 | /* set the address */ | 2543 | /* set the address */ |
2491 | choose_address(udev); | 2544 | choose_address(udev); |
2492 | if (udev->devnum <= 0) { | 2545 | if (udev->devnum <= 0) { |
@@ -2506,16 +2559,16 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2506 | * on the parent. | 2559 | * on the parent. |
2507 | */ | 2560 | */ |
2508 | if (udev->descriptor.bDeviceClass == USB_CLASS_HUB | 2561 | if (udev->descriptor.bDeviceClass == USB_CLASS_HUB |
2509 | && hub->power_budget) { | 2562 | && udev->bus_mA <= 100) { |
2510 | u16 devstat; | 2563 | u16 devstat; |
2511 | 2564 | ||
2512 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, | 2565 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, |
2513 | &devstat); | 2566 | &devstat); |
2514 | if (status < 0) { | 2567 | if (status < 2) { |
2515 | dev_dbg(&udev->dev, "get status %d ?\n", status); | 2568 | dev_dbg(&udev->dev, "get status %d ?\n", status); |
2516 | goto loop_disable; | 2569 | goto loop_disable; |
2517 | } | 2570 | } |
2518 | cpu_to_le16s(&devstat); | 2571 | le16_to_cpus(&devstat); |
2519 | if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) { | 2572 | if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) { |
2520 | dev_err(&udev->dev, | 2573 | dev_err(&udev->dev, |
2521 | "can't connect bus-powered hub " | 2574 | "can't connect bus-powered hub " |
@@ -2540,7 +2593,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2540 | * udev becomes globally accessible, although presumably | 2593 | * udev becomes globally accessible, although presumably |
2541 | * no one will look at it until hdev is unlocked. | 2594 | * no one will look at it until hdev is unlocked. |
2542 | */ | 2595 | */ |
2543 | down (&udev->serialize); | ||
2544 | status = 0; | 2596 | status = 0; |
2545 | 2597 | ||
2546 | /* We mustn't add new devices if the parent hub has | 2598 | /* We mustn't add new devices if the parent hub has |
@@ -2564,15 +2616,12 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2564 | } | 2616 | } |
2565 | } | 2617 | } |
2566 | 2618 | ||
2567 | up (&udev->serialize); | ||
2568 | if (status) | 2619 | if (status) |
2569 | goto loop_disable; | 2620 | goto loop_disable; |
2570 | 2621 | ||
2571 | status = hub_power_remaining(hub); | 2622 | status = hub_power_remaining(hub); |
2572 | if (status) | 2623 | if (status) |
2573 | dev_dbg(hub_dev, | 2624 | dev_dbg(hub_dev, "%dmA power budget left\n", status); |
2574 | "%dmA power budget left\n", | ||
2575 | 2 * status); | ||
2576 | 2625 | ||
2577 | return; | 2626 | return; |
2578 | 2627 | ||
@@ -2648,6 +2697,8 @@ static void hub_events(void) | |||
2648 | if (i) { | 2697 | if (i) { |
2649 | dpm_runtime_resume(&hdev->dev); | 2698 | dpm_runtime_resume(&hdev->dev); |
2650 | dpm_runtime_resume(&intf->dev); | 2699 | dpm_runtime_resume(&intf->dev); |
2700 | usb_put_intf(intf); | ||
2701 | continue; | ||
2651 | } | 2702 | } |
2652 | 2703 | ||
2653 | /* Lock the device, then check to see if we were | 2704 | /* Lock the device, then check to see if we were |
@@ -2661,7 +2712,7 @@ static void hub_events(void) | |||
2661 | 2712 | ||
2662 | /* If the hub has died, clean up after it */ | 2713 | /* If the hub has died, clean up after it */ |
2663 | if (hdev->state == USB_STATE_NOTATTACHED) { | 2714 | if (hdev->state == USB_STATE_NOTATTACHED) { |
2664 | hub_pre_reset(hub); | 2715 | hub_pre_reset(hub, 0); |
2665 | goto loop; | 2716 | goto loop; |
2666 | } | 2717 | } |
2667 | 2718 | ||
@@ -2784,6 +2835,11 @@ static void hub_events(void) | |||
2784 | if (hubchange & HUB_CHANGE_LOCAL_POWER) { | 2835 | if (hubchange & HUB_CHANGE_LOCAL_POWER) { |
2785 | dev_dbg (hub_dev, "power change\n"); | 2836 | dev_dbg (hub_dev, "power change\n"); |
2786 | clear_hub_feature(hdev, C_HUB_LOCAL_POWER); | 2837 | clear_hub_feature(hdev, C_HUB_LOCAL_POWER); |
2838 | if (hubstatus & HUB_STATUS_LOCAL_POWER) | ||
2839 | /* FIXME: Is this always true? */ | ||
2840 | hub->limited_power = 0; | ||
2841 | else | ||
2842 | hub->limited_power = 1; | ||
2787 | } | 2843 | } |
2788 | if (hubchange & HUB_CHANGE_OVERCURRENT) { | 2844 | if (hubchange & HUB_CHANGE_OVERCURRENT) { |
2789 | dev_dbg (hub_dev, "overcurrent change\n"); | 2845 | dev_dbg (hub_dev, "overcurrent change\n"); |
@@ -2832,7 +2888,6 @@ static struct usb_device_id hub_id_table [] = { | |||
2832 | MODULE_DEVICE_TABLE (usb, hub_id_table); | 2888 | MODULE_DEVICE_TABLE (usb, hub_id_table); |
2833 | 2889 | ||
2834 | static struct usb_driver hub_driver = { | 2890 | static struct usb_driver hub_driver = { |
2835 | .owner = THIS_MODULE, | ||
2836 | .name = "hub", | 2891 | .name = "hub", |
2837 | .probe = hub_probe, | 2892 | .probe = hub_probe, |
2838 | .disconnect = hub_disconnect, | 2893 | .disconnect = hub_disconnect, |
@@ -2944,7 +2999,8 @@ int usb_reset_device(struct usb_device *udev) | |||
2944 | struct usb_hub *parent_hub; | 2999 | struct usb_hub *parent_hub; |
2945 | struct usb_device_descriptor descriptor = udev->descriptor; | 3000 | struct usb_device_descriptor descriptor = udev->descriptor; |
2946 | struct usb_hub *hub = NULL; | 3001 | struct usb_hub *hub = NULL; |
2947 | int i, ret = 0, port1 = -1; | 3002 | int i, ret = 0; |
3003 | int port1 = udev->portnum; | ||
2948 | 3004 | ||
2949 | if (udev->state == USB_STATE_NOTATTACHED || | 3005 | if (udev->state == USB_STATE_NOTATTACHED || |
2950 | udev->state == USB_STATE_SUSPENDED) { | 3006 | udev->state == USB_STATE_SUSPENDED) { |
@@ -2958,18 +3014,6 @@ int usb_reset_device(struct usb_device *udev) | |||
2958 | dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__); | 3014 | dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__); |
2959 | return -EISDIR; | 3015 | return -EISDIR; |
2960 | } | 3016 | } |
2961 | |||
2962 | for (i = 0; i < parent_hdev->maxchild; i++) | ||
2963 | if (parent_hdev->children[i] == udev) { | ||
2964 | port1 = i + 1; | ||
2965 | break; | ||
2966 | } | ||
2967 | |||
2968 | if (port1 < 0) { | ||
2969 | /* If this ever happens, it's very bad */ | ||
2970 | dev_err(&udev->dev, "Can't locate device's port!\n"); | ||
2971 | return -ENOENT; | ||
2972 | } | ||
2973 | parent_hub = hdev_to_hub(parent_hdev); | 3017 | parent_hub = hdev_to_hub(parent_hdev); |
2974 | 3018 | ||
2975 | /* If we're resetting an active hub, take some special actions */ | 3019 | /* If we're resetting an active hub, take some special actions */ |
@@ -2977,7 +3021,7 @@ int usb_reset_device(struct usb_device *udev) | |||
2977 | udev->actconfig->interface[0]->dev.driver == | 3021 | udev->actconfig->interface[0]->dev.driver == |
2978 | &hub_driver.driver && | 3022 | &hub_driver.driver && |
2979 | (hub = hdev_to_hub(udev)) != NULL) { | 3023 | (hub = hdev_to_hub(udev)) != NULL) { |
2980 | hub_pre_reset(hub); | 3024 | hub_pre_reset(hub, 0); |
2981 | } | 3025 | } |
2982 | 3026 | ||
2983 | set_bit(port1, parent_hub->busy_bits); | 3027 | set_bit(port1, parent_hub->busy_bits); |
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index bf23f8978024..29d5f45a8456 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h | |||
@@ -220,8 +220,9 @@ struct usb_hub { | |||
220 | struct usb_hub_descriptor *descriptor; /* class descriptor */ | 220 | struct usb_hub_descriptor *descriptor; /* class descriptor */ |
221 | struct usb_tt tt; /* Transaction Translator */ | 221 | struct usb_tt tt; /* Transaction Translator */ |
222 | 222 | ||
223 | u8 power_budget; /* in 2mA units; or zero */ | 223 | unsigned mA_per_port; /* current for each child */ |
224 | 224 | ||
225 | unsigned limited_power:1; | ||
225 | unsigned quiescing:1; | 226 | unsigned quiescing:1; |
226 | unsigned activating:1; | 227 | unsigned activating:1; |
227 | unsigned resume_root_hub:1; | 228 | unsigned resume_root_hub:1; |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index fe74f99ca5f4..319de03944e7 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1387,6 +1387,12 @@ free_interfaces: | |||
1387 | if (dev->state != USB_STATE_ADDRESS) | 1387 | if (dev->state != USB_STATE_ADDRESS) |
1388 | usb_disable_device (dev, 1); // Skip ep0 | 1388 | usb_disable_device (dev, 1); // Skip ep0 |
1389 | 1389 | ||
1390 | i = dev->bus_mA - cp->desc.bMaxPower * 2; | ||
1391 | if (i < 0) | ||
1392 | dev_warn(&dev->dev, "new config #%d exceeds power " | ||
1393 | "limit by %dmA\n", | ||
1394 | configuration, -i); | ||
1395 | |||
1390 | if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1396 | if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
1391 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, | 1397 | USB_REQ_SET_CONFIGURATION, 0, configuration, 0, |
1392 | NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) | 1398 | NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index e197ce9353de..56a3520863a9 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
33 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
34 | #include <linux/smp_lock.h> | 34 | #include <linux/smp_lock.h> |
35 | #include <linux/rwsem.h> | ||
36 | #include <linux/usb.h> | 35 | #include <linux/usb.h> |
37 | 36 | ||
38 | #include <asm/io.h> | 37 | #include <asm/io.h> |
@@ -47,165 +46,7 @@ | |||
47 | const char *usbcore_name = "usbcore"; | 46 | const char *usbcore_name = "usbcore"; |
48 | 47 | ||
49 | static int nousb; /* Disable USB when built into kernel image */ | 48 | static int nousb; /* Disable USB when built into kernel image */ |
50 | /* Not honored on modular build */ | ||
51 | 49 | ||
52 | static DECLARE_RWSEM(usb_all_devices_rwsem); | ||
53 | |||
54 | |||
55 | static int generic_probe (struct device *dev) | ||
56 | { | ||
57 | return 0; | ||
58 | } | ||
59 | static int generic_remove (struct device *dev) | ||
60 | { | ||
61 | struct usb_device *udev = to_usb_device(dev); | ||
62 | |||
63 | /* if this is only an unbind, not a physical disconnect, then | ||
64 | * unconfigure the device */ | ||
65 | if (udev->state == USB_STATE_CONFIGURED) | ||
66 | usb_set_configuration(udev, 0); | ||
67 | |||
68 | /* in case the call failed or the device was suspended */ | ||
69 | if (udev->state >= USB_STATE_CONFIGURED) | ||
70 | usb_disable_device(udev, 0); | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static struct device_driver usb_generic_driver = { | ||
75 | .owner = THIS_MODULE, | ||
76 | .name = "usb", | ||
77 | .bus = &usb_bus_type, | ||
78 | .probe = generic_probe, | ||
79 | .remove = generic_remove, | ||
80 | }; | ||
81 | |||
82 | static int usb_generic_driver_data; | ||
83 | |||
84 | /* called from driver core with usb_bus_type.subsys writelock */ | ||
85 | static int usb_probe_interface(struct device *dev) | ||
86 | { | ||
87 | struct usb_interface * intf = to_usb_interface(dev); | ||
88 | struct usb_driver * driver = to_usb_driver(dev->driver); | ||
89 | const struct usb_device_id *id; | ||
90 | int error = -ENODEV; | ||
91 | |||
92 | dev_dbg(dev, "%s\n", __FUNCTION__); | ||
93 | |||
94 | if (!driver->probe) | ||
95 | return error; | ||
96 | /* FIXME we'd much prefer to just resume it ... */ | ||
97 | if (interface_to_usbdev(intf)->state == USB_STATE_SUSPENDED) | ||
98 | return -EHOSTUNREACH; | ||
99 | |||
100 | id = usb_match_id (intf, driver->id_table); | ||
101 | if (id) { | ||
102 | dev_dbg (dev, "%s - got id\n", __FUNCTION__); | ||
103 | |||
104 | /* Interface "power state" doesn't correspond to any hardware | ||
105 | * state whatsoever. We use it to record when it's bound to | ||
106 | * a driver that may start I/0: it's not frozen/quiesced. | ||
107 | */ | ||
108 | mark_active(intf); | ||
109 | intf->condition = USB_INTERFACE_BINDING; | ||
110 | error = driver->probe (intf, id); | ||
111 | if (error) { | ||
112 | mark_quiesced(intf); | ||
113 | intf->condition = USB_INTERFACE_UNBOUND; | ||
114 | } else | ||
115 | intf->condition = USB_INTERFACE_BOUND; | ||
116 | } | ||
117 | |||
118 | return error; | ||
119 | } | ||
120 | |||
121 | /* called from driver core with usb_bus_type.subsys writelock */ | ||
122 | static int usb_unbind_interface(struct device *dev) | ||
123 | { | ||
124 | struct usb_interface *intf = to_usb_interface(dev); | ||
125 | struct usb_driver *driver = to_usb_driver(intf->dev.driver); | ||
126 | |||
127 | intf->condition = USB_INTERFACE_UNBINDING; | ||
128 | |||
129 | /* release all urbs for this interface */ | ||
130 | usb_disable_interface(interface_to_usbdev(intf), intf); | ||
131 | |||
132 | if (driver && driver->disconnect) | ||
133 | driver->disconnect(intf); | ||
134 | |||
135 | /* reset other interface state */ | ||
136 | usb_set_interface(interface_to_usbdev(intf), | ||
137 | intf->altsetting[0].desc.bInterfaceNumber, | ||
138 | 0); | ||
139 | usb_set_intfdata(intf, NULL); | ||
140 | intf->condition = USB_INTERFACE_UNBOUND; | ||
141 | mark_quiesced(intf); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | /** | ||
147 | * usb_register - register a USB driver | ||
148 | * @new_driver: USB operations for the driver | ||
149 | * | ||
150 | * Registers a USB driver with the USB core. The list of unattached | ||
151 | * interfaces will be rescanned whenever a new driver is added, allowing | ||
152 | * the new driver to attach to any recognized devices. | ||
153 | * Returns a negative error code on failure and 0 on success. | ||
154 | * | ||
155 | * NOTE: if you want your driver to use the USB major number, you must call | ||
156 | * usb_register_dev() to enable that functionality. This function no longer | ||
157 | * takes care of that. | ||
158 | */ | ||
159 | int usb_register(struct usb_driver *new_driver) | ||
160 | { | ||
161 | int retval = 0; | ||
162 | |||
163 | if (nousb) | ||
164 | return -ENODEV; | ||
165 | |||
166 | new_driver->driver.name = (char *)new_driver->name; | ||
167 | new_driver->driver.bus = &usb_bus_type; | ||
168 | new_driver->driver.probe = usb_probe_interface; | ||
169 | new_driver->driver.remove = usb_unbind_interface; | ||
170 | new_driver->driver.owner = new_driver->owner; | ||
171 | |||
172 | usb_lock_all_devices(); | ||
173 | retval = driver_register(&new_driver->driver); | ||
174 | usb_unlock_all_devices(); | ||
175 | |||
176 | if (!retval) { | ||
177 | pr_info("%s: registered new driver %s\n", | ||
178 | usbcore_name, new_driver->name); | ||
179 | usbfs_update_special(); | ||
180 | } else { | ||
181 | printk(KERN_ERR "%s: error %d registering driver %s\n", | ||
182 | usbcore_name, retval, new_driver->name); | ||
183 | } | ||
184 | |||
185 | return retval; | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * usb_deregister - unregister a USB driver | ||
190 | * @driver: USB operations of the driver to unregister | ||
191 | * Context: must be able to sleep | ||
192 | * | ||
193 | * Unlinks the specified driver from the internal USB driver list. | ||
194 | * | ||
195 | * NOTE: If you called usb_register_dev(), you still need to call | ||
196 | * usb_deregister_dev() to clean up your driver's allocated minor numbers, | ||
197 | * this * call will no longer do it for you. | ||
198 | */ | ||
199 | void usb_deregister(struct usb_driver *driver) | ||
200 | { | ||
201 | pr_info("%s: deregistering driver %s\n", usbcore_name, driver->name); | ||
202 | |||
203 | usb_lock_all_devices(); | ||
204 | driver_unregister (&driver->driver); | ||
205 | usb_unlock_all_devices(); | ||
206 | |||
207 | usbfs_update_special(); | ||
208 | } | ||
209 | 50 | ||
210 | /** | 51 | /** |
211 | * usb_ifnum_to_if - get the interface object with a given interface number | 52 | * usb_ifnum_to_if - get the interface object with a given interface number |
@@ -351,152 +192,23 @@ void usb_driver_release_interface(struct usb_driver *driver, | |||
351 | iface->condition = USB_INTERFACE_UNBOUND; | 192 | iface->condition = USB_INTERFACE_UNBOUND; |
352 | mark_quiesced(iface); | 193 | mark_quiesced(iface); |
353 | } | 194 | } |
354 | 195 | struct find_interface_arg { | |
355 | /** | 196 | int minor; |
356 | * usb_match_id - find first usb_device_id matching device or interface | 197 | struct usb_interface *interface; |
357 | * @interface: the interface of interest | 198 | }; |
358 | * @id: array of usb_device_id structures, terminated by zero entry | ||
359 | * | ||
360 | * usb_match_id searches an array of usb_device_id's and returns | ||
361 | * the first one matching the device or interface, or null. | ||
362 | * This is used when binding (or rebinding) a driver to an interface. | ||
363 | * Most USB device drivers will use this indirectly, through the usb core, | ||
364 | * but some layered driver frameworks use it directly. | ||
365 | * These device tables are exported with MODULE_DEVICE_TABLE, through | ||
366 | * modutils and "modules.usbmap", to support the driver loading | ||
367 | * functionality of USB hotplugging. | ||
368 | * | ||
369 | * What Matches: | ||
370 | * | ||
371 | * The "match_flags" element in a usb_device_id controls which | ||
372 | * members are used. If the corresponding bit is set, the | ||
373 | * value in the device_id must match its corresponding member | ||
374 | * in the device or interface descriptor, or else the device_id | ||
375 | * does not match. | ||
376 | * | ||
377 | * "driver_info" is normally used only by device drivers, | ||
378 | * but you can create a wildcard "matches anything" usb_device_id | ||
379 | * as a driver's "modules.usbmap" entry if you provide an id with | ||
380 | * only a nonzero "driver_info" field. If you do this, the USB device | ||
381 | * driver's probe() routine should use additional intelligence to | ||
382 | * decide whether to bind to the specified interface. | ||
383 | * | ||
384 | * What Makes Good usb_device_id Tables: | ||
385 | * | ||
386 | * The match algorithm is very simple, so that intelligence in | ||
387 | * driver selection must come from smart driver id records. | ||
388 | * Unless you have good reasons to use another selection policy, | ||
389 | * provide match elements only in related groups, and order match | ||
390 | * specifiers from specific to general. Use the macros provided | ||
391 | * for that purpose if you can. | ||
392 | * | ||
393 | * The most specific match specifiers use device descriptor | ||
394 | * data. These are commonly used with product-specific matches; | ||
395 | * the USB_DEVICE macro lets you provide vendor and product IDs, | ||
396 | * and you can also match against ranges of product revisions. | ||
397 | * These are widely used for devices with application or vendor | ||
398 | * specific bDeviceClass values. | ||
399 | * | ||
400 | * Matches based on device class/subclass/protocol specifications | ||
401 | * are slightly more general; use the USB_DEVICE_INFO macro, or | ||
402 | * its siblings. These are used with single-function devices | ||
403 | * where bDeviceClass doesn't specify that each interface has | ||
404 | * its own class. | ||
405 | * | ||
406 | * Matches based on interface class/subclass/protocol are the | ||
407 | * most general; they let drivers bind to any interface on a | ||
408 | * multiple-function device. Use the USB_INTERFACE_INFO | ||
409 | * macro, or its siblings, to match class-per-interface style | ||
410 | * devices (as recorded in bDeviceClass). | ||
411 | * | ||
412 | * Within those groups, remember that not all combinations are | ||
413 | * meaningful. For example, don't give a product version range | ||
414 | * without vendor and product IDs; or specify a protocol without | ||
415 | * its associated class and subclass. | ||
416 | */ | ||
417 | const struct usb_device_id * | ||
418 | usb_match_id(struct usb_interface *interface, const struct usb_device_id *id) | ||
419 | { | ||
420 | struct usb_host_interface *intf; | ||
421 | struct usb_device *dev; | ||
422 | |||
423 | /* proc_connectinfo in devio.c may call us with id == NULL. */ | ||
424 | if (id == NULL) | ||
425 | return NULL; | ||
426 | |||
427 | intf = interface->cur_altsetting; | ||
428 | dev = interface_to_usbdev(interface); | ||
429 | |||
430 | /* It is important to check that id->driver_info is nonzero, | ||
431 | since an entry that is all zeroes except for a nonzero | ||
432 | id->driver_info is the way to create an entry that | ||
433 | indicates that the driver want to examine every | ||
434 | device and interface. */ | ||
435 | for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass || | ||
436 | id->driver_info; id++) { | ||
437 | |||
438 | if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && | ||
439 | id->idVendor != le16_to_cpu(dev->descriptor.idVendor)) | ||
440 | continue; | ||
441 | |||
442 | if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) && | ||
443 | id->idProduct != le16_to_cpu(dev->descriptor.idProduct)) | ||
444 | continue; | ||
445 | |||
446 | /* No need to test id->bcdDevice_lo != 0, since 0 is never | ||
447 | greater than any unsigned number. */ | ||
448 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) && | ||
449 | (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice))) | ||
450 | continue; | ||
451 | |||
452 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) && | ||
453 | (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice))) | ||
454 | continue; | ||
455 | |||
456 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) && | ||
457 | (id->bDeviceClass != dev->descriptor.bDeviceClass)) | ||
458 | continue; | ||
459 | |||
460 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) && | ||
461 | (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass)) | ||
462 | continue; | ||
463 | |||
464 | if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) && | ||
465 | (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol)) | ||
466 | continue; | ||
467 | |||
468 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && | ||
469 | (id->bInterfaceClass != intf->desc.bInterfaceClass)) | ||
470 | continue; | ||
471 | |||
472 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) && | ||
473 | (id->bInterfaceSubClass != intf->desc.bInterfaceSubClass)) | ||
474 | continue; | ||
475 | |||
476 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) && | ||
477 | (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol)) | ||
478 | continue; | ||
479 | |||
480 | return id; | ||
481 | } | ||
482 | |||
483 | return NULL; | ||
484 | } | ||
485 | |||
486 | 199 | ||
487 | static int __find_interface(struct device * dev, void * data) | 200 | static int __find_interface(struct device * dev, void * data) |
488 | { | 201 | { |
489 | struct usb_interface ** ret = (struct usb_interface **)data; | 202 | struct find_interface_arg *arg = data; |
490 | struct usb_interface * intf = *ret; | 203 | struct usb_interface *intf; |
491 | int *minor = (int *)data; | ||
492 | 204 | ||
493 | /* can't look at usb devices, only interfaces */ | 205 | /* can't look at usb devices, only interfaces */ |
494 | if (dev->driver == &usb_generic_driver) | 206 | if (dev->driver == &usb_generic_driver) |
495 | return 0; | 207 | return 0; |
496 | 208 | ||
497 | intf = to_usb_interface(dev); | 209 | intf = to_usb_interface(dev); |
498 | if (intf->minor != -1 && intf->minor == *minor) { | 210 | if (intf->minor != -1 && intf->minor == arg->minor) { |
499 | *ret = intf; | 211 | arg->interface = intf; |
500 | return 1; | 212 | return 1; |
501 | } | 213 | } |
502 | return 0; | 214 | return 0; |
@@ -513,35 +225,14 @@ static int __find_interface(struct device * dev, void * data) | |||
513 | */ | 225 | */ |
514 | struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) | 226 | struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) |
515 | { | 227 | { |
516 | struct usb_interface *intf = (struct usb_interface *)(long)minor; | 228 | struct find_interface_arg argb; |
517 | int ret; | ||
518 | |||
519 | ret = driver_for_each_device(&drv->driver, NULL, &intf, __find_interface); | ||
520 | 229 | ||
521 | return ret ? intf : NULL; | 230 | argb.minor = minor; |
231 | argb.interface = NULL; | ||
232 | driver_for_each_device(&drv->driver, NULL, &argb, __find_interface); | ||
233 | return argb.interface; | ||
522 | } | 234 | } |
523 | 235 | ||
524 | static int usb_device_match (struct device *dev, struct device_driver *drv) | ||
525 | { | ||
526 | struct usb_interface *intf; | ||
527 | struct usb_driver *usb_drv; | ||
528 | const struct usb_device_id *id; | ||
529 | |||
530 | /* check for generic driver, which we don't match any device with */ | ||
531 | if (drv == &usb_generic_driver) | ||
532 | return 0; | ||
533 | |||
534 | intf = to_usb_interface(dev); | ||
535 | usb_drv = to_usb_driver(drv); | ||
536 | |||
537 | id = usb_match_id (intf, usb_drv->id_table); | ||
538 | if (id) | ||
539 | return 1; | ||
540 | |||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | |||
545 | #ifdef CONFIG_HOTPLUG | 236 | #ifdef CONFIG_HOTPLUG |
546 | 237 | ||
547 | /* | 238 | /* |
@@ -750,12 +441,11 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
750 | /* hub driver sets up TT records */ | 441 | /* hub driver sets up TT records */ |
751 | } | 442 | } |
752 | 443 | ||
444 | dev->portnum = port1; | ||
753 | dev->bus = bus; | 445 | dev->bus = bus; |
754 | dev->parent = parent; | 446 | dev->parent = parent; |
755 | INIT_LIST_HEAD(&dev->filelist); | 447 | INIT_LIST_HEAD(&dev->filelist); |
756 | 448 | ||
757 | init_MUTEX(&dev->serialize); | ||
758 | |||
759 | return dev; | 449 | return dev; |
760 | } | 450 | } |
761 | 451 | ||
@@ -828,76 +518,21 @@ void usb_put_intf(struct usb_interface *intf) | |||
828 | 518 | ||
829 | /* USB device locking | 519 | /* USB device locking |
830 | * | 520 | * |
831 | * Although locking USB devices should be straightforward, it is | 521 | * USB devices and interfaces are locked using the semaphore in their |
832 | * complicated by the way the driver-model core works. When a new USB | 522 | * embedded struct device. The hub driver guarantees that whenever a |
833 | * driver is registered or unregistered, the core will automatically | 523 | * device is connected or disconnected, drivers are called with the |
834 | * probe or disconnect all matching interfaces on all USB devices while | 524 | * USB device locked as well as their particular interface. |
835 | * holding the USB subsystem writelock. There's no good way for us to | ||
836 | * tell which devices will be used or to lock them beforehand; our only | ||
837 | * option is to effectively lock all the USB devices. | ||
838 | * | ||
839 | * We do that by using a private rw-semaphore, usb_all_devices_rwsem. | ||
840 | * When locking an individual device you must first acquire the rwsem's | ||
841 | * readlock. When a driver is registered or unregistered the writelock | ||
842 | * must be held. These actions are encapsulated in the subroutines | ||
843 | * below, so all a driver needs to do is call usb_lock_device() and | ||
844 | * usb_unlock_device(). | ||
845 | * | 525 | * |
846 | * Complications arise when several devices are to be locked at the same | 526 | * Complications arise when several devices are to be locked at the same |
847 | * time. Only hub-aware drivers that are part of usbcore ever have to | 527 | * time. Only hub-aware drivers that are part of usbcore ever have to |
848 | * do this; nobody else needs to worry about it. The problem is that | 528 | * do this; nobody else needs to worry about it. The rule for locking |
849 | * usb_lock_device() must not be called to lock a second device since it | 529 | * is simple: |
850 | * would acquire the rwsem's readlock reentrantly, leading to deadlock if | ||
851 | * another thread was waiting for the writelock. The solution is simple: | ||
852 | * | ||
853 | * When locking more than one device, call usb_lock_device() | ||
854 | * to lock the first one. Lock the others by calling | ||
855 | * down(&udev->serialize) directly. | ||
856 | * | ||
857 | * When unlocking multiple devices, use up(&udev->serialize) | ||
858 | * to unlock all but the last one. Unlock the last one by | ||
859 | * calling usb_unlock_device(). | ||
860 | * | 530 | * |
861 | * When locking both a device and its parent, always lock the | 531 | * When locking both a device and its parent, always lock the |
862 | * the parent first. | 532 | * the parent first. |
863 | */ | 533 | */ |
864 | 534 | ||
865 | /** | 535 | /** |
866 | * usb_lock_device - acquire the lock for a usb device structure | ||
867 | * @udev: device that's being locked | ||
868 | * | ||
869 | * Use this routine when you don't hold any other device locks; | ||
870 | * to acquire nested inner locks call down(&udev->serialize) directly. | ||
871 | * This is necessary for proper interaction with usb_lock_all_devices(). | ||
872 | */ | ||
873 | void usb_lock_device(struct usb_device *udev) | ||
874 | { | ||
875 | down_read(&usb_all_devices_rwsem); | ||
876 | down(&udev->serialize); | ||
877 | } | ||
878 | |||
879 | /** | ||
880 | * usb_trylock_device - attempt to acquire the lock for a usb device structure | ||
881 | * @udev: device that's being locked | ||
882 | * | ||
883 | * Don't use this routine if you already hold a device lock; | ||
884 | * use down_trylock(&udev->serialize) instead. | ||
885 | * This is necessary for proper interaction with usb_lock_all_devices(). | ||
886 | * | ||
887 | * Returns 1 if successful, 0 if contention. | ||
888 | */ | ||
889 | int usb_trylock_device(struct usb_device *udev) | ||
890 | { | ||
891 | if (!down_read_trylock(&usb_all_devices_rwsem)) | ||
892 | return 0; | ||
893 | if (down_trylock(&udev->serialize)) { | ||
894 | up_read(&usb_all_devices_rwsem); | ||
895 | return 0; | ||
896 | } | ||
897 | return 1; | ||
898 | } | ||
899 | |||
900 | /** | ||
901 | * usb_lock_device_for_reset - cautiously acquire the lock for a | 536 | * usb_lock_device_for_reset - cautiously acquire the lock for a |
902 | * usb device structure | 537 | * usb device structure |
903 | * @udev: device that's being locked | 538 | * @udev: device that's being locked |
@@ -935,7 +570,7 @@ int usb_lock_device_for_reset(struct usb_device *udev, | |||
935 | } | 570 | } |
936 | } | 571 | } |
937 | 572 | ||
938 | while (!usb_trylock_device(udev)) { | 573 | while (usb_trylock_device(udev) != 0) { |
939 | 574 | ||
940 | /* If we can't acquire the lock after waiting one second, | 575 | /* If we can't acquire the lock after waiting one second, |
941 | * we're probably deadlocked */ | 576 | * we're probably deadlocked */ |
@@ -953,39 +588,6 @@ int usb_lock_device_for_reset(struct usb_device *udev, | |||
953 | return 1; | 588 | return 1; |
954 | } | 589 | } |
955 | 590 | ||
956 | /** | ||
957 | * usb_unlock_device - release the lock for a usb device structure | ||
958 | * @udev: device that's being unlocked | ||
959 | * | ||
960 | * Use this routine when releasing the only device lock you hold; | ||
961 | * to release inner nested locks call up(&udev->serialize) directly. | ||
962 | * This is necessary for proper interaction with usb_lock_all_devices(). | ||
963 | */ | ||
964 | void usb_unlock_device(struct usb_device *udev) | ||
965 | { | ||
966 | up(&udev->serialize); | ||
967 | up_read(&usb_all_devices_rwsem); | ||
968 | } | ||
969 | |||
970 | /** | ||
971 | * usb_lock_all_devices - acquire the lock for all usb device structures | ||
972 | * | ||
973 | * This is necessary when registering a new driver or probing a bus, | ||
974 | * since the driver-model core may try to use any usb_device. | ||
975 | */ | ||
976 | void usb_lock_all_devices(void) | ||
977 | { | ||
978 | down_write(&usb_all_devices_rwsem); | ||
979 | } | ||
980 | |||
981 | /** | ||
982 | * usb_unlock_all_devices - release the lock for all usb device structures | ||
983 | */ | ||
984 | void usb_unlock_all_devices(void) | ||
985 | { | ||
986 | up_write(&usb_all_devices_rwsem); | ||
987 | } | ||
988 | |||
989 | 591 | ||
990 | static struct usb_device *match_device(struct usb_device *dev, | 592 | static struct usb_device *match_device(struct usb_device *dev, |
991 | u16 vendor_id, u16 product_id) | 593 | u16 vendor_id, u16 product_id) |
@@ -1008,10 +610,10 @@ static struct usb_device *match_device(struct usb_device *dev, | |||
1008 | /* look through all of the children of this device */ | 610 | /* look through all of the children of this device */ |
1009 | for (child = 0; child < dev->maxchild; ++child) { | 611 | for (child = 0; child < dev->maxchild; ++child) { |
1010 | if (dev->children[child]) { | 612 | if (dev->children[child]) { |
1011 | down(&dev->children[child]->serialize); | 613 | usb_lock_device(dev->children[child]); |
1012 | ret_dev = match_device(dev->children[child], | 614 | ret_dev = match_device(dev->children[child], |
1013 | vendor_id, product_id); | 615 | vendor_id, product_id); |
1014 | up(&dev->children[child]->serialize); | 616 | usb_unlock_device(dev->children[child]); |
1015 | if (ret_dev) | 617 | if (ret_dev) |
1016 | goto exit; | 618 | goto exit; |
1017 | } | 619 | } |
@@ -1432,7 +1034,8 @@ static int usb_generic_suspend(struct device *dev, pm_message_t message) | |||
1432 | mark_quiesced(intf); | 1034 | mark_quiesced(intf); |
1433 | } else { | 1035 | } else { |
1434 | // FIXME else if there's no suspend method, disconnect... | 1036 | // FIXME else if there's no suspend method, disconnect... |
1435 | dev_warn(dev, "no %s?\n", "suspend"); | 1037 | dev_warn(dev, "no suspend for driver %s?\n", driver->name); |
1038 | mark_quiesced(intf); | ||
1436 | status = 0; | 1039 | status = 0; |
1437 | } | 1040 | } |
1438 | return status; | 1041 | return status; |
@@ -1460,8 +1063,10 @@ static int usb_generic_resume(struct device *dev) | |||
1460 | } | 1063 | } |
1461 | 1064 | ||
1462 | if ((dev->driver == NULL) || | 1065 | if ((dev->driver == NULL) || |
1463 | (dev->driver_data == &usb_generic_driver_data)) | 1066 | (dev->driver_data == &usb_generic_driver_data)) { |
1067 | dev->power.power_state.event = PM_EVENT_FREEZE; | ||
1464 | return 0; | 1068 | return 0; |
1069 | } | ||
1465 | 1070 | ||
1466 | intf = to_usb_interface(dev); | 1071 | intf = to_usb_interface(dev); |
1467 | driver = to_usb_driver(dev->driver); | 1072 | driver = to_usb_driver(dev->driver); |
@@ -1481,7 +1086,7 @@ static int usb_generic_resume(struct device *dev) | |||
1481 | mark_quiesced(intf); | 1086 | mark_quiesced(intf); |
1482 | } | 1087 | } |
1483 | } else | 1088 | } else |
1484 | dev_warn(dev, "no %s?\n", "resume"); | 1089 | dev_warn(dev, "no resume for driver %s?\n", driver->name); |
1485 | return 0; | 1090 | return 0; |
1486 | } | 1091 | } |
1487 | 1092 | ||
@@ -1493,18 +1098,8 @@ struct bus_type usb_bus_type = { | |||
1493 | .resume = usb_generic_resume, | 1098 | .resume = usb_generic_resume, |
1494 | }; | 1099 | }; |
1495 | 1100 | ||
1496 | #ifndef MODULE | ||
1497 | |||
1498 | static int __init usb_setup_disable(char *str) | ||
1499 | { | ||
1500 | nousb = 1; | ||
1501 | return 1; | ||
1502 | } | ||
1503 | |||
1504 | /* format to disable USB on kernel command line is: nousb */ | 1101 | /* format to disable USB on kernel command line is: nousb */ |
1505 | __setup("nousb", usb_setup_disable); | 1102 | __module_param_call("", nousb, param_set_bool, param_get_bool, &nousb, 0444); |
1506 | |||
1507 | #endif | ||
1508 | 1103 | ||
1509 | /* | 1104 | /* |
1510 | * for external read access to <nousb> | 1105 | * for external read access to <nousb> |
@@ -1595,8 +1190,6 @@ module_exit(usb_exit); | |||
1595 | * driver modules to use. | 1190 | * driver modules to use. |
1596 | */ | 1191 | */ |
1597 | 1192 | ||
1598 | EXPORT_SYMBOL(usb_register); | ||
1599 | EXPORT_SYMBOL(usb_deregister); | ||
1600 | EXPORT_SYMBOL(usb_disabled); | 1193 | EXPORT_SYMBOL(usb_disabled); |
1601 | 1194 | ||
1602 | EXPORT_SYMBOL_GPL(usb_get_intf); | 1195 | EXPORT_SYMBOL_GPL(usb_get_intf); |
@@ -1607,14 +1200,10 @@ EXPORT_SYMBOL(usb_put_dev); | |||
1607 | EXPORT_SYMBOL(usb_get_dev); | 1200 | EXPORT_SYMBOL(usb_get_dev); |
1608 | EXPORT_SYMBOL(usb_hub_tt_clear_buffer); | 1201 | EXPORT_SYMBOL(usb_hub_tt_clear_buffer); |
1609 | 1202 | ||
1610 | EXPORT_SYMBOL(usb_lock_device); | ||
1611 | EXPORT_SYMBOL(usb_trylock_device); | ||
1612 | EXPORT_SYMBOL(usb_lock_device_for_reset); | 1203 | EXPORT_SYMBOL(usb_lock_device_for_reset); |
1613 | EXPORT_SYMBOL(usb_unlock_device); | ||
1614 | 1204 | ||
1615 | EXPORT_SYMBOL(usb_driver_claim_interface); | 1205 | EXPORT_SYMBOL(usb_driver_claim_interface); |
1616 | EXPORT_SYMBOL(usb_driver_release_interface); | 1206 | EXPORT_SYMBOL(usb_driver_release_interface); |
1617 | EXPORT_SYMBOL(usb_match_id); | ||
1618 | EXPORT_SYMBOL(usb_find_interface); | 1207 | EXPORT_SYMBOL(usb_find_interface); |
1619 | EXPORT_SYMBOL(usb_ifnum_to_if); | 1208 | EXPORT_SYMBOL(usb_ifnum_to_if); |
1620 | EXPORT_SYMBOL(usb_altnum_to_altsetting); | 1209 | EXPORT_SYMBOL(usb_altnum_to_altsetting); |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 1c4a68499dce..4647e1ebc68d 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -16,9 +16,6 @@ extern int usb_get_device_descriptor(struct usb_device *dev, | |||
16 | extern char *usb_cache_string(struct usb_device *udev, int index); | 16 | extern char *usb_cache_string(struct usb_device *udev, int index); |
17 | extern int usb_set_configuration(struct usb_device *dev, int configuration); | 17 | extern int usb_set_configuration(struct usb_device *dev, int configuration); |
18 | 18 | ||
19 | extern void usb_lock_all_devices(void); | ||
20 | extern void usb_unlock_all_devices(void); | ||
21 | |||
22 | extern void usb_kick_khubd(struct usb_device *dev); | 19 | extern void usb_kick_khubd(struct usb_device *dev); |
23 | extern void usb_suspend_root_hub(struct usb_device *hdev); | 20 | extern void usb_suspend_root_hub(struct usb_device *hdev); |
24 | extern void usb_resume_root_hub(struct usb_device *dev); | 21 | extern void usb_resume_root_hub(struct usb_device *dev); |
@@ -33,6 +30,9 @@ extern void usb_host_cleanup(void); | |||
33 | extern int usb_suspend_device(struct usb_device *dev); | 30 | extern int usb_suspend_device(struct usb_device *dev); |
34 | extern int usb_resume_device(struct usb_device *dev); | 31 | extern int usb_resume_device(struct usb_device *dev); |
35 | 32 | ||
33 | extern struct device_driver usb_generic_driver; | ||
34 | extern int usb_generic_driver_data; | ||
35 | extern int usb_device_match(struct device *dev, struct device_driver *drv); | ||
36 | 36 | ||
37 | /* Interfaces and their "power state" are owned by usbcore */ | 37 | /* Interfaces and their "power state" are owned by usbcore */ |
38 | 38 | ||
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index c655d46c8aed..9734cb76dd6c 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -138,7 +138,7 @@ static const char *const ep_name [] = { | |||
138 | /* or like sa1100: two fixed function endpoints */ | 138 | /* or like sa1100: two fixed function endpoints */ |
139 | "ep1out-bulk", "ep2in-bulk", | 139 | "ep1out-bulk", "ep2in-bulk", |
140 | }; | 140 | }; |
141 | #define DUMMY_ENDPOINTS (sizeof(ep_name)/sizeof(char *)) | 141 | #define DUMMY_ENDPOINTS ARRAY_SIZE(ep_name) |
142 | 142 | ||
143 | /*-------------------------------------------------------------------------*/ | 143 | /*-------------------------------------------------------------------------*/ |
144 | 144 | ||
@@ -896,7 +896,7 @@ dummy_gadget_release (struct device *dev) | |||
896 | #endif | 896 | #endif |
897 | } | 897 | } |
898 | 898 | ||
899 | static int dummy_udc_probe (struct platform_device *dev) | 899 | static int dummy_udc_probe (struct platform_device *pdev) |
900 | { | 900 | { |
901 | struct dummy *dum = the_controller; | 901 | struct dummy *dum = the_controller; |
902 | int rc; | 902 | int rc; |
@@ -909,7 +909,7 @@ static int dummy_udc_probe (struct platform_device *dev) | |||
909 | dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0); | 909 | dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0); |
910 | 910 | ||
911 | strcpy (dum->gadget.dev.bus_id, "gadget"); | 911 | strcpy (dum->gadget.dev.bus_id, "gadget"); |
912 | dum->gadget.dev.parent = &dev->dev; | 912 | dum->gadget.dev.parent = &pdev->dev; |
913 | dum->gadget.dev.release = dummy_gadget_release; | 913 | dum->gadget.dev.release = dummy_gadget_release; |
914 | rc = device_register (&dum->gadget.dev); | 914 | rc = device_register (&dum->gadget.dev); |
915 | if (rc < 0) | 915 | if (rc < 0) |
@@ -919,47 +919,47 @@ static int dummy_udc_probe (struct platform_device *dev) | |||
919 | usb_bus_get (&dummy_to_hcd (dum)->self); | 919 | usb_bus_get (&dummy_to_hcd (dum)->self); |
920 | #endif | 920 | #endif |
921 | 921 | ||
922 | platform_set_drvdata (dev, dum); | 922 | platform_set_drvdata (pdev, dum); |
923 | device_create_file (&dum->gadget.dev, &dev_attr_function); | 923 | device_create_file (&dum->gadget.dev, &dev_attr_function); |
924 | return rc; | 924 | return rc; |
925 | } | 925 | } |
926 | 926 | ||
927 | static int dummy_udc_remove (struct platform_device *dev) | 927 | static int dummy_udc_remove (struct platform_device *pdev) |
928 | { | 928 | { |
929 | struct dummy *dum = platform_get_drvdata (dev); | 929 | struct dummy *dum = platform_get_drvdata (pdev); |
930 | 930 | ||
931 | platform_set_drvdata (dev, NULL); | 931 | platform_set_drvdata (pdev, NULL); |
932 | device_remove_file (&dum->gadget.dev, &dev_attr_function); | 932 | device_remove_file (&dum->gadget.dev, &dev_attr_function); |
933 | device_unregister (&dum->gadget.dev); | 933 | device_unregister (&dum->gadget.dev); |
934 | return 0; | 934 | return 0; |
935 | } | 935 | } |
936 | 936 | ||
937 | static int dummy_udc_suspend (struct platform_device *dev, pm_message_t state) | 937 | static int dummy_udc_suspend (struct platform_device *pdev, pm_message_t state) |
938 | { | 938 | { |
939 | struct dummy *dum = platform_get_drvdata(dev); | 939 | struct dummy *dum = platform_get_drvdata(pdev); |
940 | 940 | ||
941 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 941 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
942 | spin_lock_irq (&dum->lock); | 942 | spin_lock_irq (&dum->lock); |
943 | dum->udc_suspended = 1; | 943 | dum->udc_suspended = 1; |
944 | set_link_state (dum); | 944 | set_link_state (dum); |
945 | spin_unlock_irq (&dum->lock); | 945 | spin_unlock_irq (&dum->lock); |
946 | 946 | ||
947 | dev->dev.power.power_state = state; | 947 | pdev->dev.power.power_state = state; |
948 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); | 948 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); |
949 | return 0; | 949 | return 0; |
950 | } | 950 | } |
951 | 951 | ||
952 | static int dummy_udc_resume (struct platform_device *dev) | 952 | static int dummy_udc_resume (struct platform_device *pdev) |
953 | { | 953 | { |
954 | struct dummy *dum = platform_get_drvdata(dev); | 954 | struct dummy *dum = platform_get_drvdata(pdev); |
955 | 955 | ||
956 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 956 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
957 | spin_lock_irq (&dum->lock); | 957 | spin_lock_irq (&dum->lock); |
958 | dum->udc_suspended = 0; | 958 | dum->udc_suspended = 0; |
959 | set_link_state (dum); | 959 | set_link_state (dum); |
960 | spin_unlock_irq (&dum->lock); | 960 | spin_unlock_irq (&dum->lock); |
961 | 961 | ||
962 | dev->dev.power.power_state = PMSG_ON; | 962 | pdev->dev.power.power_state = PMSG_ON; |
963 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); | 963 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); |
964 | return 0; | 964 | return 0; |
965 | } | 965 | } |
@@ -1576,7 +1576,7 @@ static int dummy_hub_status (struct usb_hcd *hcd, char *buf) | |||
1576 | dum = hcd_to_dummy (hcd); | 1576 | dum = hcd_to_dummy (hcd); |
1577 | 1577 | ||
1578 | spin_lock_irqsave (&dum->lock, flags); | 1578 | spin_lock_irqsave (&dum->lock, flags); |
1579 | if (hcd->state != HC_STATE_RUNNING) | 1579 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) |
1580 | goto done; | 1580 | goto done; |
1581 | 1581 | ||
1582 | if (dum->resuming && time_after_eq (jiffies, dum->re_timeout)) { | 1582 | if (dum->resuming && time_after_eq (jiffies, dum->re_timeout)) { |
@@ -1623,7 +1623,7 @@ static int dummy_hub_control ( | |||
1623 | int retval = 0; | 1623 | int retval = 0; |
1624 | unsigned long flags; | 1624 | unsigned long flags; |
1625 | 1625 | ||
1626 | if (hcd->state != HC_STATE_RUNNING) | 1626 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) |
1627 | return -ETIMEDOUT; | 1627 | return -ETIMEDOUT; |
1628 | 1628 | ||
1629 | dum = hcd_to_dummy (hcd); | 1629 | dum = hcd_to_dummy (hcd); |
@@ -1756,9 +1756,12 @@ static int dummy_bus_suspend (struct usb_hcd *hcd) | |||
1756 | { | 1756 | { |
1757 | struct dummy *dum = hcd_to_dummy (hcd); | 1757 | struct dummy *dum = hcd_to_dummy (hcd); |
1758 | 1758 | ||
1759 | dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__); | ||
1760 | |||
1759 | spin_lock_irq (&dum->lock); | 1761 | spin_lock_irq (&dum->lock); |
1760 | dum->rh_state = DUMMY_RH_SUSPENDED; | 1762 | dum->rh_state = DUMMY_RH_SUSPENDED; |
1761 | set_link_state (dum); | 1763 | set_link_state (dum); |
1764 | hcd->state = HC_STATE_SUSPENDED; | ||
1762 | spin_unlock_irq (&dum->lock); | 1765 | spin_unlock_irq (&dum->lock); |
1763 | return 0; | 1766 | return 0; |
1764 | } | 1767 | } |
@@ -1766,14 +1769,23 @@ static int dummy_bus_suspend (struct usb_hcd *hcd) | |||
1766 | static int dummy_bus_resume (struct usb_hcd *hcd) | 1769 | static int dummy_bus_resume (struct usb_hcd *hcd) |
1767 | { | 1770 | { |
1768 | struct dummy *dum = hcd_to_dummy (hcd); | 1771 | struct dummy *dum = hcd_to_dummy (hcd); |
1772 | int rc = 0; | ||
1773 | |||
1774 | dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__); | ||
1769 | 1775 | ||
1770 | spin_lock_irq (&dum->lock); | 1776 | spin_lock_irq (&dum->lock); |
1771 | dum->rh_state = DUMMY_RH_RUNNING; | 1777 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { |
1772 | set_link_state (dum); | 1778 | dev_warn (&hcd->self.root_hub->dev, "HC isn't running!\n"); |
1773 | if (!list_empty(&dum->urbp_list)) | 1779 | rc = -ENODEV; |
1774 | mod_timer (&dum->timer, jiffies); | 1780 | } else { |
1781 | dum->rh_state = DUMMY_RH_RUNNING; | ||
1782 | set_link_state (dum); | ||
1783 | if (!list_empty(&dum->urbp_list)) | ||
1784 | mod_timer (&dum->timer, jiffies); | ||
1785 | hcd->state = HC_STATE_RUNNING; | ||
1786 | } | ||
1775 | spin_unlock_irq (&dum->lock); | 1787 | spin_unlock_irq (&dum->lock); |
1776 | return 0; | 1788 | return rc; |
1777 | } | 1789 | } |
1778 | 1790 | ||
1779 | /*-------------------------------------------------------------------------*/ | 1791 | /*-------------------------------------------------------------------------*/ |
@@ -1899,14 +1911,14 @@ static const struct hc_driver dummy_hcd = { | |||
1899 | .bus_resume = dummy_bus_resume, | 1911 | .bus_resume = dummy_bus_resume, |
1900 | }; | 1912 | }; |
1901 | 1913 | ||
1902 | static int dummy_hcd_probe (struct platform_device *dev) | 1914 | static int dummy_hcd_probe(struct platform_device *pdev) |
1903 | { | 1915 | { |
1904 | struct usb_hcd *hcd; | 1916 | struct usb_hcd *hcd; |
1905 | int retval; | 1917 | int retval; |
1906 | 1918 | ||
1907 | dev_info(&dev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); | 1919 | dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); |
1908 | 1920 | ||
1909 | hcd = usb_create_hcd (&dummy_hcd, &dev->dev, dev->dev.bus_id); | 1921 | hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, pdev->dev.bus_id); |
1910 | if (!hcd) | 1922 | if (!hcd) |
1911 | return -ENOMEM; | 1923 | return -ENOMEM; |
1912 | the_controller = hcd_to_dummy (hcd); | 1924 | the_controller = hcd_to_dummy (hcd); |
@@ -1919,36 +1931,43 @@ static int dummy_hcd_probe (struct platform_device *dev) | |||
1919 | return retval; | 1931 | return retval; |
1920 | } | 1932 | } |
1921 | 1933 | ||
1922 | static int dummy_hcd_remove (struct platform_device *dev) | 1934 | static int dummy_hcd_remove (struct platform_device *pdev) |
1923 | { | 1935 | { |
1924 | struct usb_hcd *hcd; | 1936 | struct usb_hcd *hcd; |
1925 | 1937 | ||
1926 | hcd = platform_get_drvdata (dev); | 1938 | hcd = platform_get_drvdata (pdev); |
1927 | usb_remove_hcd (hcd); | 1939 | usb_remove_hcd (hcd); |
1928 | usb_put_hcd (hcd); | 1940 | usb_put_hcd (hcd); |
1929 | the_controller = NULL; | 1941 | the_controller = NULL; |
1930 | return 0; | 1942 | return 0; |
1931 | } | 1943 | } |
1932 | 1944 | ||
1933 | static int dummy_hcd_suspend (struct platform_device *dev, pm_message_t state) | 1945 | static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state) |
1934 | { | 1946 | { |
1935 | struct usb_hcd *hcd; | 1947 | struct usb_hcd *hcd; |
1948 | struct dummy *dum; | ||
1949 | int rc = 0; | ||
1936 | 1950 | ||
1937 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 1951 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
1938 | hcd = platform_get_drvdata (dev); | ||
1939 | 1952 | ||
1940 | hcd->state = HC_STATE_SUSPENDED; | 1953 | hcd = platform_get_drvdata (pdev); |
1941 | return 0; | 1954 | dum = hcd_to_dummy (hcd); |
1955 | if (dum->rh_state == DUMMY_RH_RUNNING) { | ||
1956 | dev_warn(&pdev->dev, "Root hub isn't suspended!\n"); | ||
1957 | rc = -EBUSY; | ||
1958 | } else | ||
1959 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
1960 | return rc; | ||
1942 | } | 1961 | } |
1943 | 1962 | ||
1944 | static int dummy_hcd_resume (struct platform_device *dev) | 1963 | static int dummy_hcd_resume (struct platform_device *pdev) |
1945 | { | 1964 | { |
1946 | struct usb_hcd *hcd; | 1965 | struct usb_hcd *hcd; |
1947 | 1966 | ||
1948 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 1967 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
1949 | hcd = platform_get_drvdata (dev); | ||
1950 | hcd->state = HC_STATE_RUNNING; | ||
1951 | 1968 | ||
1969 | hcd = platform_get_drvdata (pdev); | ||
1970 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
1952 | usb_hcd_poll_rh_status (hcd); | 1971 | usb_hcd_poll_rh_status (hcd); |
1953 | return 0; | 1972 | return 0; |
1954 | } | 1973 | } |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index ea09aaa3cab6..0cea9782d7d4 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -224,6 +224,7 @@ | |||
224 | #include <linux/fs.h> | 224 | #include <linux/fs.h> |
225 | #include <linux/init.h> | 225 | #include <linux/init.h> |
226 | #include <linux/kernel.h> | 226 | #include <linux/kernel.h> |
227 | #include <linux/kref.h> | ||
227 | #include <linux/kthread.h> | 228 | #include <linux/kthread.h> |
228 | #include <linux/limits.h> | 229 | #include <linux/limits.h> |
229 | #include <linux/list.h> | 230 | #include <linux/list.h> |
@@ -238,7 +239,6 @@ | |||
238 | #include <linux/string.h> | 239 | #include <linux/string.h> |
239 | #include <linux/suspend.h> | 240 | #include <linux/suspend.h> |
240 | #include <linux/utsname.h> | 241 | #include <linux/utsname.h> |
241 | #include <linux/wait.h> | ||
242 | 242 | ||
243 | #include <linux/usb_ch9.h> | 243 | #include <linux/usb_ch9.h> |
244 | #include <linux/usb_gadget.h> | 244 | #include <linux/usb_gadget.h> |
@@ -250,7 +250,7 @@ | |||
250 | 250 | ||
251 | #define DRIVER_DESC "File-backed Storage Gadget" | 251 | #define DRIVER_DESC "File-backed Storage Gadget" |
252 | #define DRIVER_NAME "g_file_storage" | 252 | #define DRIVER_NAME "g_file_storage" |
253 | #define DRIVER_VERSION "20 October 2004" | 253 | #define DRIVER_VERSION "28 November 2005" |
254 | 254 | ||
255 | static const char longname[] = DRIVER_DESC; | 255 | static const char longname[] = DRIVER_DESC; |
256 | static const char shortname[] = DRIVER_NAME; | 256 | static const char shortname[] = DRIVER_NAME; |
@@ -335,8 +335,8 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
335 | #define MAX_LUNS 8 | 335 | #define MAX_LUNS 8 |
336 | 336 | ||
337 | /* Arggh! There should be a module_param_array_named macro! */ | 337 | /* Arggh! There should be a module_param_array_named macro! */ |
338 | static char *file[MAX_LUNS] = {NULL, }; | 338 | static char *file[MAX_LUNS]; |
339 | static int ro[MAX_LUNS] = {0, }; | 339 | static int ro[MAX_LUNS]; |
340 | 340 | ||
341 | static struct { | 341 | static struct { |
342 | int num_filenames; | 342 | int num_filenames; |
@@ -587,7 +587,7 @@ enum fsg_buffer_state { | |||
587 | struct fsg_buffhd { | 587 | struct fsg_buffhd { |
588 | void *buf; | 588 | void *buf; |
589 | dma_addr_t dma; | 589 | dma_addr_t dma; |
590 | volatile enum fsg_buffer_state state; | 590 | enum fsg_buffer_state state; |
591 | struct fsg_buffhd *next; | 591 | struct fsg_buffhd *next; |
592 | 592 | ||
593 | /* The NetChip 2280 is faster, and handles some protocol faults | 593 | /* The NetChip 2280 is faster, and handles some protocol faults |
@@ -596,9 +596,9 @@ struct fsg_buffhd { | |||
596 | unsigned int bulk_out_intended_length; | 596 | unsigned int bulk_out_intended_length; |
597 | 597 | ||
598 | struct usb_request *inreq; | 598 | struct usb_request *inreq; |
599 | volatile int inreq_busy; | 599 | int inreq_busy; |
600 | struct usb_request *outreq; | 600 | struct usb_request *outreq; |
601 | volatile int outreq_busy; | 601 | int outreq_busy; |
602 | }; | 602 | }; |
603 | 603 | ||
604 | enum fsg_state { | 604 | enum fsg_state { |
@@ -631,13 +631,16 @@ struct fsg_dev { | |||
631 | /* filesem protects: backing files in use */ | 631 | /* filesem protects: backing files in use */ |
632 | struct rw_semaphore filesem; | 632 | struct rw_semaphore filesem; |
633 | 633 | ||
634 | /* reference counting: wait until all LUNs are released */ | ||
635 | struct kref ref; | ||
636 | |||
634 | struct usb_ep *ep0; // Handy copy of gadget->ep0 | 637 | struct usb_ep *ep0; // Handy copy of gadget->ep0 |
635 | struct usb_request *ep0req; // For control responses | 638 | struct usb_request *ep0req; // For control responses |
636 | volatile unsigned int ep0_req_tag; | 639 | unsigned int ep0_req_tag; |
637 | const char *ep0req_name; | 640 | const char *ep0req_name; |
638 | 641 | ||
639 | struct usb_request *intreq; // For interrupt responses | 642 | struct usb_request *intreq; // For interrupt responses |
640 | volatile int intreq_busy; | 643 | int intreq_busy; |
641 | struct fsg_buffhd *intr_buffhd; | 644 | struct fsg_buffhd *intr_buffhd; |
642 | 645 | ||
643 | unsigned int bulk_out_maxpacket; | 646 | unsigned int bulk_out_maxpacket; |
@@ -667,7 +670,6 @@ struct fsg_dev { | |||
667 | struct fsg_buffhd *next_buffhd_to_drain; | 670 | struct fsg_buffhd *next_buffhd_to_drain; |
668 | struct fsg_buffhd buffhds[NUM_BUFFERS]; | 671 | struct fsg_buffhd buffhds[NUM_BUFFERS]; |
669 | 672 | ||
670 | wait_queue_head_t thread_wqh; | ||
671 | int thread_wakeup_needed; | 673 | int thread_wakeup_needed; |
672 | struct completion thread_notifier; | 674 | struct completion thread_notifier; |
673 | struct task_struct *thread_task; | 675 | struct task_struct *thread_task; |
@@ -694,7 +696,6 @@ struct fsg_dev { | |||
694 | unsigned int nluns; | 696 | unsigned int nluns; |
695 | struct lun *luns; | 697 | struct lun *luns; |
696 | struct lun *curlun; | 698 | struct lun *curlun; |
697 | struct completion lun_released; | ||
698 | }; | 699 | }; |
699 | 700 | ||
700 | typedef void (*fsg_routine_t)(struct fsg_dev *); | 701 | typedef void (*fsg_routine_t)(struct fsg_dev *); |
@@ -1073,11 +1074,13 @@ static int populate_config_buf(struct usb_gadget *gadget, | |||
1073 | 1074 | ||
1074 | /* These routines may be called in process context or in_irq */ | 1075 | /* These routines may be called in process context or in_irq */ |
1075 | 1076 | ||
1077 | /* Caller must hold fsg->lock */ | ||
1076 | static void wakeup_thread(struct fsg_dev *fsg) | 1078 | static void wakeup_thread(struct fsg_dev *fsg) |
1077 | { | 1079 | { |
1078 | /* Tell the main thread that something has happened */ | 1080 | /* Tell the main thread that something has happened */ |
1079 | fsg->thread_wakeup_needed = 1; | 1081 | fsg->thread_wakeup_needed = 1; |
1080 | wake_up_all(&fsg->thread_wqh); | 1082 | if (fsg->thread_task) |
1083 | wake_up_process(fsg->thread_task); | ||
1081 | } | 1084 | } |
1082 | 1085 | ||
1083 | 1086 | ||
@@ -1164,11 +1167,12 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) | |||
1164 | usb_ep_fifo_flush(ep); | 1167 | usb_ep_fifo_flush(ep); |
1165 | 1168 | ||
1166 | /* Hold the lock while we update the request and buffer states */ | 1169 | /* Hold the lock while we update the request and buffer states */ |
1170 | smp_wmb(); | ||
1167 | spin_lock(&fsg->lock); | 1171 | spin_lock(&fsg->lock); |
1168 | bh->inreq_busy = 0; | 1172 | bh->inreq_busy = 0; |
1169 | bh->state = BUF_STATE_EMPTY; | 1173 | bh->state = BUF_STATE_EMPTY; |
1170 | spin_unlock(&fsg->lock); | ||
1171 | wakeup_thread(fsg); | 1174 | wakeup_thread(fsg); |
1175 | spin_unlock(&fsg->lock); | ||
1172 | } | 1176 | } |
1173 | 1177 | ||
1174 | static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | 1178 | static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) |
@@ -1185,11 +1189,12 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | |||
1185 | usb_ep_fifo_flush(ep); | 1189 | usb_ep_fifo_flush(ep); |
1186 | 1190 | ||
1187 | /* Hold the lock while we update the request and buffer states */ | 1191 | /* Hold the lock while we update the request and buffer states */ |
1192 | smp_wmb(); | ||
1188 | spin_lock(&fsg->lock); | 1193 | spin_lock(&fsg->lock); |
1189 | bh->outreq_busy = 0; | 1194 | bh->outreq_busy = 0; |
1190 | bh->state = BUF_STATE_FULL; | 1195 | bh->state = BUF_STATE_FULL; |
1191 | spin_unlock(&fsg->lock); | ||
1192 | wakeup_thread(fsg); | 1196 | wakeup_thread(fsg); |
1197 | spin_unlock(&fsg->lock); | ||
1193 | } | 1198 | } |
1194 | 1199 | ||
1195 | 1200 | ||
@@ -1206,11 +1211,12 @@ static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) | |||
1206 | usb_ep_fifo_flush(ep); | 1211 | usb_ep_fifo_flush(ep); |
1207 | 1212 | ||
1208 | /* Hold the lock while we update the request and buffer states */ | 1213 | /* Hold the lock while we update the request and buffer states */ |
1214 | smp_wmb(); | ||
1209 | spin_lock(&fsg->lock); | 1215 | spin_lock(&fsg->lock); |
1210 | fsg->intreq_busy = 0; | 1216 | fsg->intreq_busy = 0; |
1211 | bh->state = BUF_STATE_EMPTY; | 1217 | bh->state = BUF_STATE_EMPTY; |
1212 | spin_unlock(&fsg->lock); | ||
1213 | wakeup_thread(fsg); | 1218 | wakeup_thread(fsg); |
1219 | spin_unlock(&fsg->lock); | ||
1214 | } | 1220 | } |
1215 | 1221 | ||
1216 | #else | 1222 | #else |
@@ -1261,8 +1267,8 @@ static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
1261 | fsg->cbbuf_cmnd_size = req->actual; | 1267 | fsg->cbbuf_cmnd_size = req->actual; |
1262 | memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); | 1268 | memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); |
1263 | 1269 | ||
1264 | spin_unlock(&fsg->lock); | ||
1265 | wakeup_thread(fsg); | 1270 | wakeup_thread(fsg); |
1271 | spin_unlock(&fsg->lock); | ||
1266 | } | 1272 | } |
1267 | 1273 | ||
1268 | #else | 1274 | #else |
@@ -1514,8 +1520,8 @@ static int fsg_setup(struct usb_gadget *gadget, | |||
1514 | 1520 | ||
1515 | /* Use this for bulk or interrupt transfers, not ep0 */ | 1521 | /* Use this for bulk or interrupt transfers, not ep0 */ |
1516 | static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | 1522 | static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, |
1517 | struct usb_request *req, volatile int *pbusy, | 1523 | struct usb_request *req, int *pbusy, |
1518 | volatile enum fsg_buffer_state *state) | 1524 | enum fsg_buffer_state *state) |
1519 | { | 1525 | { |
1520 | int rc; | 1526 | int rc; |
1521 | 1527 | ||
@@ -1523,8 +1529,11 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | |||
1523 | dump_msg(fsg, "bulk-in", req->buf, req->length); | 1529 | dump_msg(fsg, "bulk-in", req->buf, req->length); |
1524 | else if (ep == fsg->intr_in) | 1530 | else if (ep == fsg->intr_in) |
1525 | dump_msg(fsg, "intr-in", req->buf, req->length); | 1531 | dump_msg(fsg, "intr-in", req->buf, req->length); |
1532 | |||
1533 | spin_lock_irq(&fsg->lock); | ||
1526 | *pbusy = 1; | 1534 | *pbusy = 1; |
1527 | *state = BUF_STATE_BUSY; | 1535 | *state = BUF_STATE_BUSY; |
1536 | spin_unlock_irq(&fsg->lock); | ||
1528 | rc = usb_ep_queue(ep, req, GFP_KERNEL); | 1537 | rc = usb_ep_queue(ep, req, GFP_KERNEL); |
1529 | if (rc != 0) { | 1538 | if (rc != 0) { |
1530 | *pbusy = 0; | 1539 | *pbusy = 0; |
@@ -1544,14 +1553,23 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | |||
1544 | 1553 | ||
1545 | static int sleep_thread(struct fsg_dev *fsg) | 1554 | static int sleep_thread(struct fsg_dev *fsg) |
1546 | { | 1555 | { |
1547 | int rc; | 1556 | int rc = 0; |
1548 | 1557 | ||
1549 | /* Wait until a signal arrives or we are woken up */ | 1558 | /* Wait until a signal arrives or we are woken up */ |
1550 | rc = wait_event_interruptible(fsg->thread_wqh, | 1559 | for (;;) { |
1551 | fsg->thread_wakeup_needed); | 1560 | try_to_freeze(); |
1561 | set_current_state(TASK_INTERRUPTIBLE); | ||
1562 | if (signal_pending(current)) { | ||
1563 | rc = -EINTR; | ||
1564 | break; | ||
1565 | } | ||
1566 | if (fsg->thread_wakeup_needed) | ||
1567 | break; | ||
1568 | schedule(); | ||
1569 | } | ||
1570 | __set_current_state(TASK_RUNNING); | ||
1552 | fsg->thread_wakeup_needed = 0; | 1571 | fsg->thread_wakeup_needed = 0; |
1553 | try_to_freeze(); | 1572 | return rc; |
1554 | return (rc ? -EINTR : 0); | ||
1555 | } | 1573 | } |
1556 | 1574 | ||
1557 | 1575 | ||
@@ -1788,6 +1806,7 @@ static int do_write(struct fsg_dev *fsg) | |||
1788 | if (bh->state == BUF_STATE_EMPTY && !get_some_more) | 1806 | if (bh->state == BUF_STATE_EMPTY && !get_some_more) |
1789 | break; // We stopped early | 1807 | break; // We stopped early |
1790 | if (bh->state == BUF_STATE_FULL) { | 1808 | if (bh->state == BUF_STATE_FULL) { |
1809 | smp_rmb(); | ||
1791 | fsg->next_buffhd_to_drain = bh->next; | 1810 | fsg->next_buffhd_to_drain = bh->next; |
1792 | bh->state = BUF_STATE_EMPTY; | 1811 | bh->state = BUF_STATE_EMPTY; |
1793 | 1812 | ||
@@ -2356,6 +2375,7 @@ static int throw_away_data(struct fsg_dev *fsg) | |||
2356 | 2375 | ||
2357 | /* Throw away the data in a filled buffer */ | 2376 | /* Throw away the data in a filled buffer */ |
2358 | if (bh->state == BUF_STATE_FULL) { | 2377 | if (bh->state == BUF_STATE_FULL) { |
2378 | smp_rmb(); | ||
2359 | bh->state = BUF_STATE_EMPTY; | 2379 | bh->state = BUF_STATE_EMPTY; |
2360 | fsg->next_buffhd_to_drain = bh->next; | 2380 | fsg->next_buffhd_to_drain = bh->next; |
2361 | 2381 | ||
@@ -3021,6 +3041,7 @@ static int get_next_command(struct fsg_dev *fsg) | |||
3021 | if ((rc = sleep_thread(fsg)) != 0) | 3041 | if ((rc = sleep_thread(fsg)) != 0) |
3022 | return rc; | 3042 | return rc; |
3023 | } | 3043 | } |
3044 | smp_rmb(); | ||
3024 | rc = received_cbw(fsg, bh); | 3045 | rc = received_cbw(fsg, bh); |
3025 | bh->state = BUF_STATE_EMPTY; | 3046 | bh->state = BUF_STATE_EMPTY; |
3026 | 3047 | ||
@@ -3642,11 +3663,19 @@ static DEVICE_ATTR(file, 0444, show_file, NULL); | |||
3642 | 3663 | ||
3643 | /*-------------------------------------------------------------------------*/ | 3664 | /*-------------------------------------------------------------------------*/ |
3644 | 3665 | ||
3666 | static void fsg_release(struct kref *ref) | ||
3667 | { | ||
3668 | struct fsg_dev *fsg = container_of(ref, struct fsg_dev, ref); | ||
3669 | |||
3670 | kfree(fsg->luns); | ||
3671 | kfree(fsg); | ||
3672 | } | ||
3673 | |||
3645 | static void lun_release(struct device *dev) | 3674 | static void lun_release(struct device *dev) |
3646 | { | 3675 | { |
3647 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); | 3676 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); |
3648 | 3677 | ||
3649 | complete(&fsg->lun_released); | 3678 | kref_put(&fsg->ref, fsg_release); |
3650 | } | 3679 | } |
3651 | 3680 | ||
3652 | static void fsg_unbind(struct usb_gadget *gadget) | 3681 | static void fsg_unbind(struct usb_gadget *gadget) |
@@ -3660,14 +3689,12 @@ static void fsg_unbind(struct usb_gadget *gadget) | |||
3660 | clear_bit(REGISTERED, &fsg->atomic_bitflags); | 3689 | clear_bit(REGISTERED, &fsg->atomic_bitflags); |
3661 | 3690 | ||
3662 | /* Unregister the sysfs attribute files and the LUNs */ | 3691 | /* Unregister the sysfs attribute files and the LUNs */ |
3663 | init_completion(&fsg->lun_released); | ||
3664 | for (i = 0; i < fsg->nluns; ++i) { | 3692 | for (i = 0; i < fsg->nluns; ++i) { |
3665 | curlun = &fsg->luns[i]; | 3693 | curlun = &fsg->luns[i]; |
3666 | if (curlun->registered) { | 3694 | if (curlun->registered) { |
3667 | device_remove_file(&curlun->dev, &dev_attr_ro); | 3695 | device_remove_file(&curlun->dev, &dev_attr_ro); |
3668 | device_remove_file(&curlun->dev, &dev_attr_file); | 3696 | device_remove_file(&curlun->dev, &dev_attr_file); |
3669 | device_unregister(&curlun->dev); | 3697 | device_unregister(&curlun->dev); |
3670 | wait_for_completion(&fsg->lun_released); | ||
3671 | curlun->registered = 0; | 3698 | curlun->registered = 0; |
3672 | } | 3699 | } |
3673 | } | 3700 | } |
@@ -3846,6 +3873,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3846 | curlun->dev.release = lun_release; | 3873 | curlun->dev.release = lun_release; |
3847 | device_create_file(&curlun->dev, &dev_attr_ro); | 3874 | device_create_file(&curlun->dev, &dev_attr_ro); |
3848 | device_create_file(&curlun->dev, &dev_attr_file); | 3875 | device_create_file(&curlun->dev, &dev_attr_file); |
3876 | kref_get(&fsg->ref); | ||
3849 | } | 3877 | } |
3850 | 3878 | ||
3851 | if (file[i] && *file[i]) { | 3879 | if (file[i] && *file[i]) { |
@@ -4061,7 +4089,7 @@ static int __init fsg_alloc(void) | |||
4061 | return -ENOMEM; | 4089 | return -ENOMEM; |
4062 | spin_lock_init(&fsg->lock); | 4090 | spin_lock_init(&fsg->lock); |
4063 | init_rwsem(&fsg->filesem); | 4091 | init_rwsem(&fsg->filesem); |
4064 | init_waitqueue_head(&fsg->thread_wqh); | 4092 | kref_init(&fsg->ref); |
4065 | init_completion(&fsg->thread_notifier); | 4093 | init_completion(&fsg->thread_notifier); |
4066 | 4094 | ||
4067 | the_fsg = fsg; | 4095 | the_fsg = fsg; |
@@ -4069,13 +4097,6 @@ static int __init fsg_alloc(void) | |||
4069 | } | 4097 | } |
4070 | 4098 | ||
4071 | 4099 | ||
4072 | static void fsg_free(struct fsg_dev *fsg) | ||
4073 | { | ||
4074 | kfree(fsg->luns); | ||
4075 | kfree(fsg); | ||
4076 | } | ||
4077 | |||
4078 | |||
4079 | static int __init fsg_init(void) | 4100 | static int __init fsg_init(void) |
4080 | { | 4101 | { |
4081 | int rc; | 4102 | int rc; |
@@ -4085,7 +4106,7 @@ static int __init fsg_init(void) | |||
4085 | return rc; | 4106 | return rc; |
4086 | fsg = the_fsg; | 4107 | fsg = the_fsg; |
4087 | if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) | 4108 | if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) |
4088 | fsg_free(fsg); | 4109 | kref_put(&fsg->ref, fsg_release); |
4089 | return rc; | 4110 | return rc; |
4090 | } | 4111 | } |
4091 | module_init(fsg_init); | 4112 | module_init(fsg_init); |
@@ -4103,6 +4124,6 @@ static void __exit fsg_cleanup(void) | |||
4103 | wait_for_completion(&fsg->thread_notifier); | 4124 | wait_for_completion(&fsg->thread_notifier); |
4104 | 4125 | ||
4105 | close_all_backing_files(fsg); | 4126 | close_all_backing_files(fsg); |
4106 | fsg_free(fsg); | 4127 | kref_put(&fsg->ref, fsg_release); |
4107 | } | 4128 | } |
4108 | module_exit(fsg_cleanup); | 4129 | module_exit(fsg_cleanup); |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index b35ac6d334f8..65e084a2c87e 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -890,10 +890,12 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
890 | /* wait for write buffer to drain, or */ | 890 | /* wait for write buffer to drain, or */ |
891 | /* at most GS_CLOSE_TIMEOUT seconds */ | 891 | /* at most GS_CLOSE_TIMEOUT seconds */ |
892 | if (gs_buf_data_avail(port->port_write_buf) > 0) { | 892 | if (gs_buf_data_avail(port->port_write_buf) > 0) { |
893 | spin_unlock_irqrestore(&port->port_lock, flags); | ||
893 | wait_cond_interruptible_timeout(port->port_write_wait, | 894 | wait_cond_interruptible_timeout(port->port_write_wait, |
894 | port->port_dev == NULL | 895 | port->port_dev == NULL |
895 | || gs_buf_data_avail(port->port_write_buf) == 0, | 896 | || gs_buf_data_avail(port->port_write_buf) == 0, |
896 | &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ); | 897 | &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ); |
898 | spin_lock_irqsave(&port->port_lock, flags); | ||
897 | } | 899 | } |
898 | 900 | ||
899 | /* free disconnected port on final close */ | 901 | /* free disconnected port on final close */ |
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 58321d3f314c..e3020f4b17be 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -2,6 +2,10 @@ | |||
2 | # Makefile for USB Host Controller Drivers | 2 | # Makefile for USB Host Controller Drivers |
3 | # | 3 | # |
4 | 4 | ||
5 | ifeq ($(CONFIG_USB_DEBUG),y) | ||
6 | EXTRA_CFLAGS += -DDEBUG | ||
7 | endif | ||
8 | |||
5 | obj-$(CONFIG_PCI) += pci-quirks.o | 9 | obj-$(CONFIG_PCI) += pci-quirks.o |
6 | 10 | ||
7 | obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o | 11 | obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 29f52a44b928..9dd3d14c64f3 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -17,13 +17,6 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/config.h> | 19 | #include <linux/config.h> |
20 | |||
21 | #ifdef CONFIG_USB_DEBUG | ||
22 | #define DEBUG | ||
23 | #else | ||
24 | #undef DEBUG | ||
25 | #endif | ||
26 | |||
27 | #include <linux/module.h> | 20 | #include <linux/module.h> |
28 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
29 | #include <linux/dmapool.h> | 22 | #include <linux/dmapool.h> |
@@ -624,7 +617,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) | |||
624 | } | 617 | } |
625 | 618 | ||
626 | /* remote wakeup [4.3.1] */ | 619 | /* remote wakeup [4.3.1] */ |
627 | if ((status & STS_PCD) && hcd->remote_wakeup) { | 620 | if (status & STS_PCD) { |
628 | unsigned i = HCS_N_PORTS (ehci->hcs_params); | 621 | unsigned i = HCS_N_PORTS (ehci->hcs_params); |
629 | 622 | ||
630 | /* resume root hub? */ | 623 | /* resume root hub? */ |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 82caf336e9b6..69b0b9be7a64 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -59,7 +59,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
59 | 59 | ||
60 | if ((t1 & PORT_PE) && !(t1 & PORT_OWNER)) | 60 | if ((t1 & PORT_PE) && !(t1 & PORT_OWNER)) |
61 | t2 |= PORT_SUSPEND; | 61 | t2 |= PORT_SUSPEND; |
62 | if (hcd->remote_wakeup) | 62 | if (device_may_wakeup(&hcd->self.root_hub->dev)) |
63 | t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E; | 63 | t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E; |
64 | else | 64 | else |
65 | t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E); | 65 | t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E); |
@@ -517,7 +517,7 @@ static int ehci_hub_control ( | |||
517 | if ((temp & PORT_PE) == 0 | 517 | if ((temp & PORT_PE) == 0 |
518 | || (temp & PORT_RESET) != 0) | 518 | || (temp & PORT_RESET) != 0) |
519 | goto error; | 519 | goto error; |
520 | if (hcd->remote_wakeup) | 520 | if (device_may_wakeup(&hcd->self.root_hub->dev)) |
521 | temp |= PORT_WAKE_BITS; | 521 | temp |= PORT_WAKE_BITS; |
522 | writel (temp | PORT_SUSPEND, | 522 | writel (temp | PORT_SUSPEND, |
523 | &ehci->regs->port_status [wIndex]); | 523 | &ehci->regs->port_status [wIndex]); |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 13f73a836e45..08ca0f849dab 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -210,7 +210,16 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
210 | /* Serial Bus Release Number is at PCI 0x60 offset */ | 210 | /* Serial Bus Release Number is at PCI 0x60 offset */ |
211 | pci_read_config_byte(pdev, 0x60, &ehci->sbrn); | 211 | pci_read_config_byte(pdev, 0x60, &ehci->sbrn); |
212 | 212 | ||
213 | /* REVISIT: per-port wake capability (PCI 0x62) currently unused */ | 213 | /* Workaround current PCI init glitch: wakeup bits aren't |
214 | * being set from PCI PM capability. | ||
215 | */ | ||
216 | if (!device_can_wakeup(&pdev->dev)) { | ||
217 | u16 port_wake; | ||
218 | |||
219 | pci_read_config_word(pdev, 0x62, &port_wake); | ||
220 | if (port_wake & 0x0001) | ||
221 | device_init_wakeup(&pdev->dev, 1); | ||
222 | } | ||
214 | 223 | ||
215 | retval = ehci_pci_reinit(ehci, pdev); | 224 | retval = ehci_pci_reinit(ehci, pdev); |
216 | done: | 225 | done: |
@@ -269,7 +278,6 @@ static int ehci_pci_resume(struct usb_hcd *hcd) | |||
269 | { | 278 | { |
270 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 279 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
271 | unsigned port; | 280 | unsigned port; |
272 | struct usb_device *root = hcd->self.root_hub; | ||
273 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 281 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
274 | int retval = -EINVAL; | 282 | int retval = -EINVAL; |
275 | 283 | ||
@@ -303,13 +311,7 @@ static int ehci_pci_resume(struct usb_hcd *hcd) | |||
303 | 311 | ||
304 | restart: | 312 | restart: |
305 | ehci_dbg(ehci, "lost power, restarting\n"); | 313 | ehci_dbg(ehci, "lost power, restarting\n"); |
306 | for (port = HCS_N_PORTS(ehci->hcs_params); port > 0; ) { | 314 | usb_root_hub_lost_power(hcd->self.root_hub); |
307 | port--; | ||
308 | if (!root->children [port]) | ||
309 | continue; | ||
310 | usb_set_device_state(root->children[port], | ||
311 | USB_STATE_NOTATTACHED); | ||
312 | } | ||
313 | 315 | ||
314 | /* Else reset, to cope with power loss or flush-to-storage | 316 | /* Else reset, to cope with power loss or flush-to-storage |
315 | * style "resume" having let BIOS kick in during reboot. | 317 | * style "resume" having let BIOS kick in during reboot. |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index bf03ec0d8ee2..9b13bf2fa98d 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -514,18 +514,18 @@ qh_urb_transaction ( | |||
514 | qtd->urb = urb; | 514 | qtd->urb = urb; |
515 | qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma); | 515 | qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma); |
516 | list_add_tail (&qtd->qtd_list, head); | 516 | list_add_tail (&qtd->qtd_list, head); |
517 | |||
518 | /* for zero length DATA stages, STATUS is always IN */ | ||
519 | if (len == 0) | ||
520 | token |= (1 /* "in" */ << 8); | ||
517 | } | 521 | } |
518 | 522 | ||
519 | /* | 523 | /* |
520 | * data transfer stage: buffer setup | 524 | * data transfer stage: buffer setup |
521 | */ | 525 | */ |
522 | if (likely (len > 0)) | 526 | buf = urb->transfer_dma; |
523 | buf = urb->transfer_dma; | ||
524 | else | ||
525 | buf = 0; | ||
526 | 527 | ||
527 | /* for zero length DATA stages, STATUS is always IN */ | 528 | if (is_input) |
528 | if (!buf || is_input) | ||
529 | token |= (1 /* "in" */ << 8); | 529 | token |= (1 /* "in" */ << 8); |
530 | /* else it's already initted to "out" pid (0 << 8) */ | 530 | /* else it's already initted to "out" pid (0 << 8) */ |
531 | 531 | ||
@@ -572,7 +572,7 @@ qh_urb_transaction ( | |||
572 | * control requests may need a terminating data "status" ack; | 572 | * control requests may need a terminating data "status" ack; |
573 | * bulk ones may need a terminating short packet (zero length). | 573 | * bulk ones may need a terminating short packet (zero length). |
574 | */ | 574 | */ |
575 | if (likely (buf != 0)) { | 575 | if (likely (urb->transfer_buffer_length != 0)) { |
576 | int one_more = 0; | 576 | int one_more = 0; |
577 | 577 | ||
578 | if (usb_pipecontrol (urb->pipe)) { | 578 | if (usb_pipecontrol (urb->pipe)) { |
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 82f64986bc22..584b8dc65119 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -55,19 +55,13 @@ | |||
55 | /* enqueuing/finishing log of urbs */ | 55 | /* enqueuing/finishing log of urbs */ |
56 | //#define URB_TRACE | 56 | //#define URB_TRACE |
57 | 57 | ||
58 | #include <linux/config.h> | ||
59 | #include <linux/module.h> | 58 | #include <linux/module.h> |
60 | #include <linux/moduleparam.h> | ||
61 | #include <linux/kernel.h> | ||
62 | #include <linux/delay.h> | 59 | #include <linux/delay.h> |
63 | #include <linux/ioport.h> | 60 | #include <linux/debugfs.h> |
64 | #include <linux/sched.h> | 61 | #include <linux/seq_file.h> |
65 | #include <linux/slab.h> | ||
66 | #include <linux/smp_lock.h> | ||
67 | #include <linux/errno.h> | 62 | #include <linux/errno.h> |
68 | #include <linux/init.h> | 63 | #include <linux/init.h> |
69 | #include <linux/list.h> | 64 | #include <linux/list.h> |
70 | #include <linux/interrupt.h> | ||
71 | #include <linux/usb.h> | 65 | #include <linux/usb.h> |
72 | #include <linux/usb_isp116x.h> | 66 | #include <linux/usb_isp116x.h> |
73 | #include <linux/platform_device.h> | 67 | #include <linux/platform_device.h> |
@@ -77,14 +71,10 @@ | |||
77 | #include <asm/system.h> | 71 | #include <asm/system.h> |
78 | #include <asm/byteorder.h> | 72 | #include <asm/byteorder.h> |
79 | 73 | ||
80 | #ifndef DEBUG | ||
81 | # define STUB_DEBUG_FILE | ||
82 | #endif | ||
83 | |||
84 | #include "../core/hcd.h" | 74 | #include "../core/hcd.h" |
85 | #include "isp116x.h" | 75 | #include "isp116x.h" |
86 | 76 | ||
87 | #define DRIVER_VERSION "05 Aug 2005" | 77 | #define DRIVER_VERSION "03 Nov 2005" |
88 | #define DRIVER_DESC "ISP116x USB Host Controller Driver" | 78 | #define DRIVER_DESC "ISP116x USB Host Controller Driver" |
89 | 79 | ||
90 | MODULE_DESCRIPTION(DRIVER_DESC); | 80 | MODULE_DESCRIPTION(DRIVER_DESC); |
@@ -164,13 +154,11 @@ static void pack_fifo(struct isp116x *isp116x) | |||
164 | struct ptd *ptd; | 154 | struct ptd *ptd; |
165 | int buflen = isp116x->atl_last_dir == PTD_DIR_IN | 155 | int buflen = isp116x->atl_last_dir == PTD_DIR_IN |
166 | ? isp116x->atl_bufshrt : isp116x->atl_buflen; | 156 | ? isp116x->atl_bufshrt : isp116x->atl_buflen; |
167 | int ptd_count = 0; | ||
168 | 157 | ||
169 | isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT); | 158 | isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT); |
170 | isp116x_write_reg16(isp116x, HCXFERCTR, buflen); | 159 | isp116x_write_reg16(isp116x, HCXFERCTR, buflen); |
171 | isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET); | 160 | isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET); |
172 | for (ep = isp116x->atl_active; ep; ep = ep->active) { | 161 | for (ep = isp116x->atl_active; ep; ep = ep->active) { |
173 | ++ptd_count; | ||
174 | ptd = &ep->ptd; | 162 | ptd = &ep->ptd; |
175 | dump_ptd(ptd); | 163 | dump_ptd(ptd); |
176 | dump_ptd_out_data(ptd, ep->data); | 164 | dump_ptd_out_data(ptd, ep->data); |
@@ -305,9 +293,8 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
305 | udev = urb->dev; | 293 | udev = urb->dev; |
306 | ptd = &ep->ptd; | 294 | ptd = &ep->ptd; |
307 | cc = PTD_GET_CC(ptd); | 295 | cc = PTD_GET_CC(ptd); |
308 | |||
309 | spin_lock(&urb->lock); | ||
310 | short_not_ok = 1; | 296 | short_not_ok = 1; |
297 | spin_lock(&urb->lock); | ||
311 | 298 | ||
312 | /* Data underrun is special. For allowed underrun | 299 | /* Data underrun is special. For allowed underrun |
313 | we clear the error and continue as normal. For | 300 | we clear the error and continue as normal. For |
@@ -420,7 +407,7 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
420 | ep->nextpid = 0; | 407 | ep->nextpid = 0; |
421 | break; | 408 | break; |
422 | default: | 409 | default: |
423 | BUG_ON(1); | 410 | BUG(); |
424 | } | 411 | } |
425 | spin_unlock(&urb->lock); | 412 | spin_unlock(&urb->lock); |
426 | } | 413 | } |
@@ -628,8 +615,12 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) | |||
628 | u32 intstat = isp116x_read_reg32(isp116x, HCINTSTAT); | 615 | u32 intstat = isp116x_read_reg32(isp116x, HCINTSTAT); |
629 | isp116x_write_reg32(isp116x, HCINTSTAT, intstat); | 616 | isp116x_write_reg32(isp116x, HCINTSTAT, intstat); |
630 | if (intstat & HCINT_UE) { | 617 | if (intstat & HCINT_UE) { |
631 | ERR("Unrecoverable error\n"); | 618 | ERR("Unrecoverable error, HC is dead!\n"); |
632 | /* What should we do here? Reset? */ | 619 | /* IRQ's are off, we do no DMA, |
620 | perfectly ready to die ... */ | ||
621 | hcd->state = HC_STATE_HALT; | ||
622 | ret = IRQ_HANDLED; | ||
623 | goto done; | ||
633 | } | 624 | } |
634 | if (intstat & HCINT_RHSC) | 625 | if (intstat & HCINT_RHSC) |
635 | /* When root hub or any of its ports is going | 626 | /* When root hub or any of its ports is going |
@@ -640,7 +631,6 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) | |||
640 | if (intstat & HCINT_RD) { | 631 | if (intstat & HCINT_RD) { |
641 | DBG("---- remote wakeup\n"); | 632 | DBG("---- remote wakeup\n"); |
642 | usb_hcd_resume_root_hub(hcd); | 633 | usb_hcd_resume_root_hub(hcd); |
643 | ret = IRQ_HANDLED; | ||
644 | } | 634 | } |
645 | irqstat &= ~HCuPINT_OPR; | 635 | irqstat &= ~HCuPINT_OPR; |
646 | ret = IRQ_HANDLED; | 636 | ret = IRQ_HANDLED; |
@@ -651,6 +641,7 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) | |||
651 | } | 641 | } |
652 | 642 | ||
653 | isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb); | 643 | isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb); |
644 | done: | ||
654 | spin_unlock(&isp116x->lock); | 645 | spin_unlock(&isp116x->lock); |
655 | return ret; | 646 | return ret; |
656 | } | 647 | } |
@@ -724,6 +715,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, | |||
724 | 715 | ||
725 | spin_lock_irqsave(&isp116x->lock, flags); | 716 | spin_lock_irqsave(&isp116x->lock, flags); |
726 | if (!HC_IS_RUNNING(hcd->state)) { | 717 | if (!HC_IS_RUNNING(hcd->state)) { |
718 | kfree(ep); | ||
727 | ret = -ENODEV; | 719 | ret = -ENODEV; |
728 | goto fail; | 720 | goto fail; |
729 | } | 721 | } |
@@ -888,7 +880,7 @@ static void isp116x_endpoint_disable(struct usb_hcd *hcd, | |||
888 | struct usb_host_endpoint *hep) | 880 | struct usb_host_endpoint *hep) |
889 | { | 881 | { |
890 | int i; | 882 | int i; |
891 | struct isp116x_ep *ep = hep->hcpriv;; | 883 | struct isp116x_ep *ep = hep->hcpriv; |
892 | 884 | ||
893 | if (!ep) | 885 | if (!ep) |
894 | return; | 886 | return; |
@@ -916,8 +908,6 @@ static int isp116x_get_frame(struct usb_hcd *hcd) | |||
916 | return (int)fmnum; | 908 | return (int)fmnum; |
917 | } | 909 | } |
918 | 910 | ||
919 | /*----------------------------------------------------------------*/ | ||
920 | |||
921 | /* | 911 | /* |
922 | Adapted from ohci-hub.c. Currently we don't support autosuspend. | 912 | Adapted from ohci-hub.c. Currently we don't support autosuspend. |
923 | */ | 913 | */ |
@@ -968,11 +958,10 @@ static void isp116x_hub_descriptor(struct isp116x *isp116x, | |||
968 | desc->bHubContrCurrent = 0; | 958 | desc->bHubContrCurrent = 0; |
969 | desc->bNbrPorts = (u8) (reg & 0x3); | 959 | desc->bNbrPorts = (u8) (reg & 0x3); |
970 | /* Power switching, device type, overcurrent. */ | 960 | /* Power switching, device type, overcurrent. */ |
971 | desc->wHubCharacteristics = | 961 | desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & 0x1f)); |
972 | (__force __u16) cpu_to_le16((u16) ((reg >> 8) & 0x1f)); | ||
973 | desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff); | 962 | desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff); |
974 | /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */ | 963 | /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */ |
975 | desc->bitmap[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1; | 964 | desc->bitmap[0] = 0; |
976 | desc->bitmap[1] = ~0; | 965 | desc->bitmap[1] = ~0; |
977 | } | 966 | } |
978 | 967 | ||
@@ -1159,135 +1148,9 @@ static int isp116x_hub_control(struct usb_hcd *hcd, | |||
1159 | return ret; | 1148 | return ret; |
1160 | } | 1149 | } |
1161 | 1150 | ||
1162 | #ifdef CONFIG_PM | ||
1163 | |||
1164 | static int isp116x_bus_suspend(struct usb_hcd *hcd) | ||
1165 | { | ||
1166 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | ||
1167 | unsigned long flags; | ||
1168 | u32 val; | ||
1169 | int ret = 0; | ||
1170 | |||
1171 | spin_lock_irqsave(&isp116x->lock, flags); | ||
1172 | |||
1173 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
1174 | switch (val & HCCONTROL_HCFS) { | ||
1175 | case HCCONTROL_USB_OPER: | ||
1176 | hcd->state = HC_STATE_QUIESCING; | ||
1177 | val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE); | ||
1178 | val |= HCCONTROL_USB_SUSPEND; | ||
1179 | if (hcd->remote_wakeup) | ||
1180 | val |= HCCONTROL_RWE; | ||
1181 | /* Wait for usb transfers to finish */ | ||
1182 | mdelay(2); | ||
1183 | isp116x_write_reg32(isp116x, HCCONTROL, val); | ||
1184 | hcd->state = HC_STATE_SUSPENDED; | ||
1185 | /* Wait for devices to suspend */ | ||
1186 | mdelay(5); | ||
1187 | case HCCONTROL_USB_SUSPEND: | ||
1188 | break; | ||
1189 | case HCCONTROL_USB_RESUME: | ||
1190 | isp116x_write_reg32(isp116x, HCCONTROL, | ||
1191 | (val & ~HCCONTROL_HCFS) | | ||
1192 | HCCONTROL_USB_RESET); | ||
1193 | case HCCONTROL_USB_RESET: | ||
1194 | ret = -EBUSY; | ||
1195 | break; | ||
1196 | default: | ||
1197 | ret = -EINVAL; | ||
1198 | } | ||
1199 | |||
1200 | spin_unlock_irqrestore(&isp116x->lock, flags); | ||
1201 | return ret; | ||
1202 | } | ||
1203 | |||
1204 | static int isp116x_bus_resume(struct usb_hcd *hcd) | ||
1205 | { | ||
1206 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | ||
1207 | u32 val; | ||
1208 | int ret = -EINPROGRESS; | ||
1209 | |||
1210 | msleep(5); | ||
1211 | spin_lock_irq(&isp116x->lock); | ||
1212 | |||
1213 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
1214 | switch (val & HCCONTROL_HCFS) { | ||
1215 | case HCCONTROL_USB_SUSPEND: | ||
1216 | val &= ~HCCONTROL_HCFS; | ||
1217 | val |= HCCONTROL_USB_RESUME; | ||
1218 | isp116x_write_reg32(isp116x, HCCONTROL, val); | ||
1219 | case HCCONTROL_USB_RESUME: | ||
1220 | break; | ||
1221 | case HCCONTROL_USB_OPER: | ||
1222 | /* Without setting power_state here the | ||
1223 | SUSPENDED state won't be removed from | ||
1224 | sysfs/usbN/power.state as a response to remote | ||
1225 | wakeup. Maybe in the future. */ | ||
1226 | hcd->self.root_hub->dev.power.power_state = PMSG_ON; | ||
1227 | ret = 0; | ||
1228 | break; | ||
1229 | default: | ||
1230 | ret = -EBUSY; | ||
1231 | } | ||
1232 | |||
1233 | if (ret != -EINPROGRESS) { | ||
1234 | spin_unlock_irq(&isp116x->lock); | ||
1235 | return ret; | ||
1236 | } | ||
1237 | |||
1238 | val = isp116x->rhdesca & RH_A_NDP; | ||
1239 | while (val--) { | ||
1240 | u32 stat = | ||
1241 | isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1); | ||
1242 | /* force global, not selective, resume */ | ||
1243 | if (!(stat & RH_PS_PSS)) | ||
1244 | continue; | ||
1245 | DBG("%s: Resuming port %d\n", __func__, val); | ||
1246 | isp116x_write_reg32(isp116x, RH_PS_POCI, val | ||
1247 | ? HCRHPORT2 : HCRHPORT1); | ||
1248 | } | ||
1249 | spin_unlock_irq(&isp116x->lock); | ||
1250 | |||
1251 | hcd->state = HC_STATE_RESUMING; | ||
1252 | mdelay(20); | ||
1253 | |||
1254 | /* Go operational */ | ||
1255 | spin_lock_irq(&isp116x->lock); | ||
1256 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
1257 | isp116x_write_reg32(isp116x, HCCONTROL, | ||
1258 | (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER); | ||
1259 | spin_unlock_irq(&isp116x->lock); | ||
1260 | /* see analogous comment above */ | ||
1261 | hcd->self.root_hub->dev.power.power_state = PMSG_ON; | ||
1262 | hcd->state = HC_STATE_RUNNING; | ||
1263 | |||
1264 | return 0; | ||
1265 | } | ||
1266 | |||
1267 | |||
1268 | #else | ||
1269 | |||
1270 | #define isp116x_bus_suspend NULL | ||
1271 | #define isp116x_bus_resume NULL | ||
1272 | |||
1273 | #endif | ||
1274 | |||
1275 | /*-----------------------------------------------------------------*/ | 1151 | /*-----------------------------------------------------------------*/ |
1276 | 1152 | ||
1277 | #ifdef STUB_DEBUG_FILE | 1153 | #ifdef CONFIG_DEBUG_FS |
1278 | |||
1279 | static inline void create_debug_file(struct isp116x *isp116x) | ||
1280 | { | ||
1281 | } | ||
1282 | |||
1283 | static inline void remove_debug_file(struct isp116x *isp116x) | ||
1284 | { | ||
1285 | } | ||
1286 | |||
1287 | #else | ||
1288 | |||
1289 | #include <linux/proc_fs.h> | ||
1290 | #include <linux/seq_file.h> | ||
1291 | 1154 | ||
1292 | static void dump_irq(struct seq_file *s, char *label, u16 mask) | 1155 | static void dump_irq(struct seq_file *s, char *label, u16 mask) |
1293 | { | 1156 | { |
@@ -1311,13 +1174,9 @@ static void dump_int(struct seq_file *s, char *label, u32 mask) | |||
1311 | mask & HCINT_SF ? " sof" : "", mask & HCINT_SO ? " so" : ""); | 1174 | mask & HCINT_SF ? " sof" : "", mask & HCINT_SO ? " so" : ""); |
1312 | } | 1175 | } |
1313 | 1176 | ||
1314 | static int proc_isp116x_show(struct seq_file *s, void *unused) | 1177 | static int isp116x_show_dbg(struct seq_file *s, void *unused) |
1315 | { | 1178 | { |
1316 | struct isp116x *isp116x = s->private; | 1179 | struct isp116x *isp116x = s->private; |
1317 | struct isp116x_ep *ep; | ||
1318 | struct urb *urb; | ||
1319 | unsigned i; | ||
1320 | char *str; | ||
1321 | 1180 | ||
1322 | seq_printf(s, "%s\n%s version %s\n", | 1181 | seq_printf(s, "%s\n%s version %s\n", |
1323 | isp116x_to_hcd(isp116x)->product_desc, hcd_name, | 1182 | isp116x_to_hcd(isp116x)->product_desc, hcd_name, |
@@ -1333,105 +1192,50 @@ static int proc_isp116x_show(struct seq_file *s, void *unused) | |||
1333 | } | 1192 | } |
1334 | 1193 | ||
1335 | spin_lock_irq(&isp116x->lock); | 1194 | spin_lock_irq(&isp116x->lock); |
1336 | |||
1337 | dump_irq(s, "hc_irq_enable", isp116x_read_reg16(isp116x, HCuPINTENB)); | 1195 | dump_irq(s, "hc_irq_enable", isp116x_read_reg16(isp116x, HCuPINTENB)); |
1338 | dump_irq(s, "hc_irq_status", isp116x_read_reg16(isp116x, HCuPINT)); | 1196 | dump_irq(s, "hc_irq_status", isp116x_read_reg16(isp116x, HCuPINT)); |
1339 | dump_int(s, "hc_int_enable", isp116x_read_reg32(isp116x, HCINTENB)); | 1197 | dump_int(s, "hc_int_enable", isp116x_read_reg32(isp116x, HCINTENB)); |
1340 | dump_int(s, "hc_int_status", isp116x_read_reg32(isp116x, HCINTSTAT)); | 1198 | dump_int(s, "hc_int_status", isp116x_read_reg32(isp116x, HCINTSTAT)); |
1341 | 1199 | isp116x_show_regs_seq(isp116x, s); | |
1342 | list_for_each_entry(ep, &isp116x->async, schedule) { | ||
1343 | |||
1344 | switch (ep->nextpid) { | ||
1345 | case USB_PID_IN: | ||
1346 | str = "in"; | ||
1347 | break; | ||
1348 | case USB_PID_OUT: | ||
1349 | str = "out"; | ||
1350 | break; | ||
1351 | case USB_PID_SETUP: | ||
1352 | str = "setup"; | ||
1353 | break; | ||
1354 | case USB_PID_ACK: | ||
1355 | str = "status"; | ||
1356 | break; | ||
1357 | default: | ||
1358 | str = "?"; | ||
1359 | break; | ||
1360 | }; | ||
1361 | seq_printf(s, "%p, ep%d%s, maxpacket %d:\n", ep, | ||
1362 | ep->epnum, str, ep->maxpacket); | ||
1363 | list_for_each_entry(urb, &ep->hep->urb_list, urb_list) { | ||
1364 | seq_printf(s, " urb%p, %d/%d\n", urb, | ||
1365 | urb->actual_length, | ||
1366 | urb->transfer_buffer_length); | ||
1367 | } | ||
1368 | } | ||
1369 | if (!list_empty(&isp116x->async)) | ||
1370 | seq_printf(s, "\n"); | ||
1371 | |||
1372 | seq_printf(s, "periodic size= %d\n", PERIODIC_SIZE); | ||
1373 | |||
1374 | for (i = 0; i < PERIODIC_SIZE; i++) { | ||
1375 | ep = isp116x->periodic[i]; | ||
1376 | if (!ep) | ||
1377 | continue; | ||
1378 | seq_printf(s, "%2d [%3d]:\n", i, isp116x->load[i]); | ||
1379 | |||
1380 | /* DUMB: prints shared entries multiple times */ | ||
1381 | do { | ||
1382 | seq_printf(s, " %d/%p (%sdev%d ep%d%s max %d)\n", | ||
1383 | ep->period, ep, | ||
1384 | (ep->udev->speed == | ||
1385 | USB_SPEED_FULL) ? "" : "ls ", | ||
1386 | ep->udev->devnum, ep->epnum, | ||
1387 | (ep->epnum == | ||
1388 | 0) ? "" : ((ep->nextpid == | ||
1389 | USB_PID_IN) ? "in" : "out"), | ||
1390 | ep->maxpacket); | ||
1391 | ep = ep->next; | ||
1392 | } while (ep); | ||
1393 | } | ||
1394 | spin_unlock_irq(&isp116x->lock); | 1200 | spin_unlock_irq(&isp116x->lock); |
1395 | seq_printf(s, "\n"); | 1201 | seq_printf(s, "\n"); |
1396 | 1202 | ||
1397 | return 0; | 1203 | return 0; |
1398 | } | 1204 | } |
1399 | 1205 | ||
1400 | static int proc_isp116x_open(struct inode *inode, struct file *file) | 1206 | static int isp116x_open_seq(struct inode *inode, struct file *file) |
1401 | { | 1207 | { |
1402 | return single_open(file, proc_isp116x_show, PDE(inode)->data); | 1208 | return single_open(file, isp116x_show_dbg, inode->u.generic_ip); |
1403 | } | 1209 | } |
1404 | 1210 | ||
1405 | static struct file_operations proc_ops = { | 1211 | static struct file_operations isp116x_debug_fops = { |
1406 | .open = proc_isp116x_open, | 1212 | .open = isp116x_open_seq, |
1407 | .read = seq_read, | 1213 | .read = seq_read, |
1408 | .llseek = seq_lseek, | 1214 | .llseek = seq_lseek, |
1409 | .release = single_release, | 1215 | .release = single_release, |
1410 | }; | 1216 | }; |
1411 | 1217 | ||
1412 | /* expect just one isp116x per system */ | 1218 | static int create_debug_file(struct isp116x *isp116x) |
1413 | static const char proc_filename[] = "driver/isp116x"; | ||
1414 | |||
1415 | static void create_debug_file(struct isp116x *isp116x) | ||
1416 | { | 1219 | { |
1417 | struct proc_dir_entry *pde; | 1220 | isp116x->dentry = debugfs_create_file(hcd_name, |
1418 | 1221 | S_IRUGO, NULL, isp116x, | |
1419 | pde = create_proc_entry(proc_filename, 0, NULL); | 1222 | &isp116x_debug_fops); |
1420 | if (pde == NULL) | 1223 | if (!isp116x->dentry) |
1421 | return; | 1224 | return -ENOMEM; |
1422 | 1225 | return 0; | |
1423 | pde->proc_fops = &proc_ops; | ||
1424 | pde->data = isp116x; | ||
1425 | isp116x->pde = pde; | ||
1426 | } | 1226 | } |
1427 | 1227 | ||
1428 | static void remove_debug_file(struct isp116x *isp116x) | 1228 | static void remove_debug_file(struct isp116x *isp116x) |
1429 | { | 1229 | { |
1430 | if (isp116x->pde) | 1230 | debugfs_remove(isp116x->dentry); |
1431 | remove_proc_entry(proc_filename, NULL); | ||
1432 | } | 1231 | } |
1433 | 1232 | ||
1434 | #endif | 1233 | #else |
1234 | |||
1235 | #define create_debug_file(d) 0 | ||
1236 | #define remove_debug_file(d) do{}while(0) | ||
1237 | |||
1238 | #endif /* CONFIG_DEBUG_FS */ | ||
1435 | 1239 | ||
1436 | /*-----------------------------------------------------------------*/ | 1240 | /*-----------------------------------------------------------------*/ |
1437 | 1241 | ||
@@ -1466,7 +1270,7 @@ static int isp116x_reset(struct usb_hcd *hcd) | |||
1466 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 1270 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
1467 | unsigned long t; | 1271 | unsigned long t; |
1468 | u16 clkrdy = 0; | 1272 | u16 clkrdy = 0; |
1469 | int ret = 0, timeout = 15 /* ms */ ; | 1273 | int ret, timeout = 15 /* ms */ ; |
1470 | 1274 | ||
1471 | ret = isp116x_sw_reset(isp116x); | 1275 | ret = isp116x_sw_reset(isp116x); |
1472 | if (ret) | 1276 | if (ret) |
@@ -1482,7 +1286,7 @@ static int isp116x_reset(struct usb_hcd *hcd) | |||
1482 | break; | 1286 | break; |
1483 | } | 1287 | } |
1484 | if (!clkrdy) { | 1288 | if (!clkrdy) { |
1485 | ERR("Clock not ready after 20ms\n"); | 1289 | ERR("Clock not ready after %dms\n", timeout); |
1486 | /* After sw_reset the clock won't report to be ready, if | 1290 | /* After sw_reset the clock won't report to be ready, if |
1487 | H_WAKEUP pin is high. */ | 1291 | H_WAKEUP pin is high. */ |
1488 | ERR("Please make sure that the H_WAKEUP pin is pulled low!\n"); | 1292 | ERR("Please make sure that the H_WAKEUP pin is pulled low!\n"); |
@@ -1572,7 +1376,8 @@ static int isp116x_start(struct usb_hcd *hcd) | |||
1572 | 1376 | ||
1573 | val = 0; | 1377 | val = 0; |
1574 | if (board->remote_wakeup_enable) { | 1378 | if (board->remote_wakeup_enable) { |
1575 | hcd->can_wakeup = 1; | 1379 | if (!device_can_wakeup(hcd->self.controller)) |
1380 | device_init_wakeup(hcd->self.controller, 1); | ||
1576 | val |= RH_HS_DRWE; | 1381 | val |= RH_HS_DRWE; |
1577 | } | 1382 | } |
1578 | isp116x_write_reg32(isp116x, HCRHSTATUS, val); | 1383 | isp116x_write_reg32(isp116x, HCRHSTATUS, val); |
@@ -1600,12 +1405,126 @@ static int isp116x_start(struct usb_hcd *hcd) | |||
1600 | isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS); | 1405 | isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS); |
1601 | isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS); | 1406 | isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS); |
1602 | 1407 | ||
1603 | isp116x_show_regs(isp116x); | 1408 | isp116x_show_regs_log(isp116x); |
1604 | spin_unlock_irqrestore(&isp116x->lock, flags); | 1409 | spin_unlock_irqrestore(&isp116x->lock, flags); |
1605 | return 0; | 1410 | return 0; |
1606 | } | 1411 | } |
1607 | 1412 | ||
1608 | /*-----------------------------------------------------------------*/ | 1413 | #ifdef CONFIG_PM |
1414 | |||
1415 | static int isp116x_bus_suspend(struct usb_hcd *hcd) | ||
1416 | { | ||
1417 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | ||
1418 | unsigned long flags; | ||
1419 | u32 val; | ||
1420 | int ret = 0; | ||
1421 | |||
1422 | spin_lock_irqsave(&isp116x->lock, flags); | ||
1423 | |||
1424 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
1425 | switch (val & HCCONTROL_HCFS) { | ||
1426 | case HCCONTROL_USB_OPER: | ||
1427 | val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE); | ||
1428 | val |= HCCONTROL_USB_SUSPEND; | ||
1429 | if (device_may_wakeup(&hcd->self.root_hub->dev)) | ||
1430 | val |= HCCONTROL_RWE; | ||
1431 | /* Wait for usb transfers to finish */ | ||
1432 | mdelay(2); | ||
1433 | isp116x_write_reg32(isp116x, HCCONTROL, val); | ||
1434 | /* Wait for devices to suspend */ | ||
1435 | mdelay(5); | ||
1436 | case HCCONTROL_USB_SUSPEND: | ||
1437 | break; | ||
1438 | case HCCONTROL_USB_RESUME: | ||
1439 | isp116x_write_reg32(isp116x, HCCONTROL, | ||
1440 | (val & ~HCCONTROL_HCFS) | | ||
1441 | HCCONTROL_USB_RESET); | ||
1442 | case HCCONTROL_USB_RESET: | ||
1443 | ret = -EBUSY; | ||
1444 | break; | ||
1445 | default: | ||
1446 | ret = -EINVAL; | ||
1447 | } | ||
1448 | |||
1449 | spin_unlock_irqrestore(&isp116x->lock, flags); | ||
1450 | return ret; | ||
1451 | } | ||
1452 | |||
1453 | static int isp116x_bus_resume(struct usb_hcd *hcd) | ||
1454 | { | ||
1455 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | ||
1456 | u32 val; | ||
1457 | |||
1458 | msleep(5); | ||
1459 | spin_lock_irq(&isp116x->lock); | ||
1460 | |||
1461 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
1462 | switch (val & HCCONTROL_HCFS) { | ||
1463 | case HCCONTROL_USB_SUSPEND: | ||
1464 | val &= ~HCCONTROL_HCFS; | ||
1465 | val |= HCCONTROL_USB_RESUME; | ||
1466 | isp116x_write_reg32(isp116x, HCCONTROL, val); | ||
1467 | case HCCONTROL_USB_RESUME: | ||
1468 | break; | ||
1469 | case HCCONTROL_USB_OPER: | ||
1470 | spin_unlock_irq(&isp116x->lock); | ||
1471 | /* Without setting power_state here the | ||
1472 | SUSPENDED state won't be removed from | ||
1473 | sysfs/usbN/power.state as a response to remote | ||
1474 | wakeup. Maybe in the future. */ | ||
1475 | hcd->self.root_hub->dev.power.power_state = PMSG_ON; | ||
1476 | return 0; | ||
1477 | default: | ||
1478 | /* HCCONTROL_USB_RESET: this may happen, when during | ||
1479 | suspension the HC lost power. Reinitialize completely */ | ||
1480 | spin_unlock_irq(&isp116x->lock); | ||
1481 | DBG("Chip has been reset while suspended. Reinit from scratch.\n"); | ||
1482 | isp116x_reset(hcd); | ||
1483 | isp116x_start(hcd); | ||
1484 | isp116x_hub_control(hcd, SetPortFeature, | ||
1485 | USB_PORT_FEAT_POWER, 1, NULL, 0); | ||
1486 | if ((isp116x->rhdesca & RH_A_NDP) == 2) | ||
1487 | isp116x_hub_control(hcd, SetPortFeature, | ||
1488 | USB_PORT_FEAT_POWER, 2, NULL, 0); | ||
1489 | hcd->self.root_hub->dev.power.power_state = PMSG_ON; | ||
1490 | return 0; | ||
1491 | } | ||
1492 | |||
1493 | val = isp116x->rhdesca & RH_A_NDP; | ||
1494 | while (val--) { | ||
1495 | u32 stat = | ||
1496 | isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1); | ||
1497 | /* force global, not selective, resume */ | ||
1498 | if (!(stat & RH_PS_PSS)) | ||
1499 | continue; | ||
1500 | DBG("%s: Resuming port %d\n", __func__, val); | ||
1501 | isp116x_write_reg32(isp116x, RH_PS_POCI, val | ||
1502 | ? HCRHPORT2 : HCRHPORT1); | ||
1503 | } | ||
1504 | spin_unlock_irq(&isp116x->lock); | ||
1505 | |||
1506 | hcd->state = HC_STATE_RESUMING; | ||
1507 | msleep(20); | ||
1508 | |||
1509 | /* Go operational */ | ||
1510 | spin_lock_irq(&isp116x->lock); | ||
1511 | val = isp116x_read_reg32(isp116x, HCCONTROL); | ||
1512 | isp116x_write_reg32(isp116x, HCCONTROL, | ||
1513 | (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER); | ||
1514 | spin_unlock_irq(&isp116x->lock); | ||
1515 | /* see analogous comment above */ | ||
1516 | hcd->self.root_hub->dev.power.power_state = PMSG_ON; | ||
1517 | hcd->state = HC_STATE_RUNNING; | ||
1518 | |||
1519 | return 0; | ||
1520 | } | ||
1521 | |||
1522 | #else | ||
1523 | |||
1524 | #define isp116x_bus_suspend NULL | ||
1525 | #define isp116x_bus_resume NULL | ||
1526 | |||
1527 | #endif | ||
1609 | 1528 | ||
1610 | static struct hc_driver isp116x_hc_driver = { | 1529 | static struct hc_driver isp116x_hc_driver = { |
1611 | .description = hcd_name, | 1530 | .description = hcd_name, |
@@ -1735,12 +1654,19 @@ static int __init isp116x_probe(struct platform_device *pdev) | |||
1735 | } | 1654 | } |
1736 | 1655 | ||
1737 | ret = usb_add_hcd(hcd, irq, SA_INTERRUPT); | 1656 | ret = usb_add_hcd(hcd, irq, SA_INTERRUPT); |
1738 | if (ret != 0) | 1657 | if (ret) |
1739 | goto err6; | 1658 | goto err6; |
1740 | 1659 | ||
1741 | create_debug_file(isp116x); | 1660 | ret = create_debug_file(isp116x); |
1661 | if (ret) { | ||
1662 | ERR("Couldn't create debugfs entry\n"); | ||
1663 | goto err7; | ||
1664 | } | ||
1665 | |||
1742 | return 0; | 1666 | return 0; |
1743 | 1667 | ||
1668 | err7: | ||
1669 | usb_remove_hcd(hcd); | ||
1744 | err6: | 1670 | err6: |
1745 | usb_put_hcd(hcd); | 1671 | usb_put_hcd(hcd); |
1746 | err5: | 1672 | err5: |
@@ -1762,13 +1688,9 @@ static int __init isp116x_probe(struct platform_device *pdev) | |||
1762 | */ | 1688 | */ |
1763 | static int isp116x_suspend(struct platform_device *dev, pm_message_t state) | 1689 | static int isp116x_suspend(struct platform_device *dev, pm_message_t state) |
1764 | { | 1690 | { |
1765 | int ret = 0; | 1691 | VDBG("%s: state %x\n", __func__, state.event); |
1766 | |||
1767 | VDBG("%s: state %x\n", __func__, state); | ||
1768 | |||
1769 | dev->dev.power.power_state = state; | 1692 | dev->dev.power.power_state = state; |
1770 | 1693 | return 0; | |
1771 | return ret; | ||
1772 | } | 1694 | } |
1773 | 1695 | ||
1774 | /* | 1696 | /* |
@@ -1776,13 +1698,9 @@ static int isp116x_suspend(struct platform_device *dev, pm_message_t state) | |||
1776 | */ | 1698 | */ |
1777 | static int isp116x_resume(struct platform_device *dev) | 1699 | static int isp116x_resume(struct platform_device *dev) |
1778 | { | 1700 | { |
1779 | int ret = 0; | 1701 | VDBG("%s: state %x\n", __func__, dev->power.power_state.event); |
1780 | |||
1781 | VDBG("%s: state %x\n", __func__, dev->dev.power.power_state); | ||
1782 | |||
1783 | dev->dev.power.power_state = PMSG_ON; | 1702 | dev->dev.power.power_state = PMSG_ON; |
1784 | 1703 | return 0; | |
1785 | return ret; | ||
1786 | } | 1704 | } |
1787 | 1705 | ||
1788 | #else | 1706 | #else |
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h index c6fec96785fe..a1b7c3813d3a 100644 --- a/drivers/usb/host/isp116x.h +++ b/drivers/usb/host/isp116x.h | |||
@@ -259,7 +259,7 @@ struct isp116x { | |||
259 | 259 | ||
260 | struct isp116x_platform_data *board; | 260 | struct isp116x_platform_data *board; |
261 | 261 | ||
262 | struct proc_dir_entry *pde; | 262 | struct dentry *dentry; |
263 | unsigned long stat1, stat2, stat4, stat8, stat16; | 263 | unsigned long stat1, stat2, stat4, stat8, stat16; |
264 | 264 | ||
265 | /* HC registers */ | 265 | /* HC registers */ |
@@ -450,7 +450,7 @@ static void isp116x_write_reg32(struct isp116x *isp116x, unsigned reg, | |||
450 | isp116x_write_data32(isp116x, (u32) val); | 450 | isp116x_write_data32(isp116x, (u32) val); |
451 | } | 451 | } |
452 | 452 | ||
453 | #define isp116x_show_reg(d,r) { \ | 453 | #define isp116x_show_reg_log(d,r,s) { \ |
454 | if ((r) < 0x20) { \ | 454 | if ((r) < 0x20) { \ |
455 | DBG("%-12s[%02x]: %08x\n", #r, \ | 455 | DBG("%-12s[%02x]: %08x\n", #r, \ |
456 | r, isp116x_read_reg32(d, r)); \ | 456 | r, isp116x_read_reg32(d, r)); \ |
@@ -459,35 +459,60 @@ static void isp116x_write_reg32(struct isp116x *isp116x, unsigned reg, | |||
459 | r, isp116x_read_reg16(d, r)); \ | 459 | r, isp116x_read_reg16(d, r)); \ |
460 | } \ | 460 | } \ |
461 | } | 461 | } |
462 | #define isp116x_show_reg_seq(d,r,s) { \ | ||
463 | if ((r) < 0x20) { \ | ||
464 | seq_printf(s, "%-12s[%02x]: %08x\n", #r, \ | ||
465 | r, isp116x_read_reg32(d, r)); \ | ||
466 | } else { \ | ||
467 | seq_printf(s, "%-12s[%02x]: %04x\n", #r, \ | ||
468 | r, isp116x_read_reg16(d, r)); \ | ||
469 | } \ | ||
470 | } | ||
462 | 471 | ||
463 | static inline void isp116x_show_regs(struct isp116x *isp116x) | 472 | #define isp116x_show_regs(d,type,s) { \ |
473 | isp116x_show_reg_##type(d, HCREVISION, s); \ | ||
474 | isp116x_show_reg_##type(d, HCCONTROL, s); \ | ||
475 | isp116x_show_reg_##type(d, HCCMDSTAT, s); \ | ||
476 | isp116x_show_reg_##type(d, HCINTSTAT, s); \ | ||
477 | isp116x_show_reg_##type(d, HCINTENB, s); \ | ||
478 | isp116x_show_reg_##type(d, HCFMINTVL, s); \ | ||
479 | isp116x_show_reg_##type(d, HCFMREM, s); \ | ||
480 | isp116x_show_reg_##type(d, HCFMNUM, s); \ | ||
481 | isp116x_show_reg_##type(d, HCLSTHRESH, s); \ | ||
482 | isp116x_show_reg_##type(d, HCRHDESCA, s); \ | ||
483 | isp116x_show_reg_##type(d, HCRHDESCB, s); \ | ||
484 | isp116x_show_reg_##type(d, HCRHSTATUS, s); \ | ||
485 | isp116x_show_reg_##type(d, HCRHPORT1, s); \ | ||
486 | isp116x_show_reg_##type(d, HCRHPORT2, s); \ | ||
487 | isp116x_show_reg_##type(d, HCHWCFG, s); \ | ||
488 | isp116x_show_reg_##type(d, HCDMACFG, s); \ | ||
489 | isp116x_show_reg_##type(d, HCXFERCTR, s); \ | ||
490 | isp116x_show_reg_##type(d, HCuPINT, s); \ | ||
491 | isp116x_show_reg_##type(d, HCuPINTENB, s); \ | ||
492 | isp116x_show_reg_##type(d, HCCHIPID, s); \ | ||
493 | isp116x_show_reg_##type(d, HCSCRATCH, s); \ | ||
494 | isp116x_show_reg_##type(d, HCITLBUFLEN, s); \ | ||
495 | isp116x_show_reg_##type(d, HCATLBUFLEN, s); \ | ||
496 | isp116x_show_reg_##type(d, HCBUFSTAT, s); \ | ||
497 | isp116x_show_reg_##type(d, HCRDITL0LEN, s); \ | ||
498 | isp116x_show_reg_##type(d, HCRDITL1LEN, s); \ | ||
499 | } | ||
500 | |||
501 | /* | ||
502 | Dump registers for debugfs. | ||
503 | */ | ||
504 | static inline void isp116x_show_regs_seq(struct isp116x *isp116x, | ||
505 | struct seq_file *s) | ||
506 | { | ||
507 | isp116x_show_regs(isp116x, seq, s); | ||
508 | } | ||
509 | |||
510 | /* | ||
511 | Dump registers to syslog. | ||
512 | */ | ||
513 | static inline void isp116x_show_regs_log(struct isp116x *isp116x) | ||
464 | { | 514 | { |
465 | isp116x_show_reg(isp116x, HCREVISION); | 515 | isp116x_show_regs(isp116x, log, NULL); |
466 | isp116x_show_reg(isp116x, HCCONTROL); | ||
467 | isp116x_show_reg(isp116x, HCCMDSTAT); | ||
468 | isp116x_show_reg(isp116x, HCINTSTAT); | ||
469 | isp116x_show_reg(isp116x, HCINTENB); | ||
470 | isp116x_show_reg(isp116x, HCFMINTVL); | ||
471 | isp116x_show_reg(isp116x, HCFMREM); | ||
472 | isp116x_show_reg(isp116x, HCFMNUM); | ||
473 | isp116x_show_reg(isp116x, HCLSTHRESH); | ||
474 | isp116x_show_reg(isp116x, HCRHDESCA); | ||
475 | isp116x_show_reg(isp116x, HCRHDESCB); | ||
476 | isp116x_show_reg(isp116x, HCRHSTATUS); | ||
477 | isp116x_show_reg(isp116x, HCRHPORT1); | ||
478 | isp116x_show_reg(isp116x, HCRHPORT2); | ||
479 | isp116x_show_reg(isp116x, HCHWCFG); | ||
480 | isp116x_show_reg(isp116x, HCDMACFG); | ||
481 | isp116x_show_reg(isp116x, HCXFERCTR); | ||
482 | isp116x_show_reg(isp116x, HCuPINT); | ||
483 | isp116x_show_reg(isp116x, HCuPINTENB); | ||
484 | isp116x_show_reg(isp116x, HCCHIPID); | ||
485 | isp116x_show_reg(isp116x, HCSCRATCH); | ||
486 | isp116x_show_reg(isp116x, HCITLBUFLEN); | ||
487 | isp116x_show_reg(isp116x, HCATLBUFLEN); | ||
488 | isp116x_show_reg(isp116x, HCBUFSTAT); | ||
489 | isp116x_show_reg(isp116x, HCRDITL0LEN); | ||
490 | isp116x_show_reg(isp116x, HCRDITL1LEN); | ||
491 | } | 516 | } |
492 | 517 | ||
493 | #if defined(URB_TRACE) | 518 | #if defined(URB_TRACE) |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index bf1d9abc07ac..a4b12404ae08 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -75,13 +75,6 @@ | |||
75 | */ | 75 | */ |
76 | 76 | ||
77 | #include <linux/config.h> | 77 | #include <linux/config.h> |
78 | |||
79 | #ifdef CONFIG_USB_DEBUG | ||
80 | # define DEBUG | ||
81 | #else | ||
82 | # undef DEBUG | ||
83 | #endif | ||
84 | |||
85 | #include <linux/module.h> | 78 | #include <linux/module.h> |
86 | #include <linux/moduleparam.h> | 79 | #include <linux/moduleparam.h> |
87 | #include <linux/pci.h> | 80 | #include <linux/pci.h> |
@@ -802,7 +795,6 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
802 | int temp; | 795 | int temp; |
803 | int i; | 796 | int i; |
804 | struct urb_priv *priv; | 797 | struct urb_priv *priv; |
805 | struct usb_device *root = ohci_to_hcd(ohci)->self.root_hub; | ||
806 | 798 | ||
807 | /* mark any devices gone, so they do nothing till khubd disconnects. | 799 | /* mark any devices gone, so they do nothing till khubd disconnects. |
808 | * recycle any "live" eds/tds (and urbs) right away. | 800 | * recycle any "live" eds/tds (and urbs) right away. |
@@ -811,11 +803,7 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
811 | */ | 803 | */ |
812 | spin_lock_irq(&ohci->lock); | 804 | spin_lock_irq(&ohci->lock); |
813 | disable (ohci); | 805 | disable (ohci); |
814 | for (i = 0; i < root->maxchild; i++) { | 806 | usb_root_hub_lost_power(ohci_to_hcd(ohci)->self.root_hub); |
815 | if (root->children [i]) | ||
816 | usb_set_device_state (root->children[i], | ||
817 | USB_STATE_NOTATTACHED); | ||
818 | } | ||
819 | if (!list_empty (&ohci->pending)) | 807 | if (!list_empty (&ohci->pending)) |
820 | ohci_dbg(ohci, "abort schedule...\n"); | 808 | ohci_dbg(ohci, "abort schedule...\n"); |
821 | list_for_each_entry (priv, &ohci->pending, pending) { | 809 | list_for_each_entry (priv, &ohci->pending, pending) { |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 72e3b12a1926..4b2226d77b34 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -372,7 +372,7 @@ done: | |||
372 | & ohci->hc_control) | 372 | & ohci->hc_control) |
373 | == OHCI_USB_OPER | 373 | == OHCI_USB_OPER |
374 | && time_after (jiffies, ohci->next_statechange) | 374 | && time_after (jiffies, ohci->next_statechange) |
375 | && usb_trylock_device (hcd->self.root_hub) | 375 | && usb_trylock_device (hcd->self.root_hub) == 0 |
376 | ) { | 376 | ) { |
377 | ohci_vdbg (ohci, "autosuspend\n"); | 377 | ohci_vdbg (ohci, "autosuspend\n"); |
378 | (void) ohci_bus_suspend (hcd); | 378 | (void) ohci_bus_suspend (hcd); |
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 9d65ec307990..acde8868da21 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
@@ -26,18 +26,12 @@ | |||
26 | #include <asm/mach-types.h> | 26 | #include <asm/mach-types.h> |
27 | #include <asm/hardware.h> | 27 | #include <asm/hardware.h> |
28 | #include <asm/arch/pxa-regs.h> | 28 | #include <asm/arch/pxa-regs.h> |
29 | 29 | #include <asm/arch/ohci.h> | |
30 | |||
31 | #define PMM_NPS_MODE 1 | ||
32 | #define PMM_GLOBAL_MODE 2 | ||
33 | #define PMM_PERPORT_MODE 3 | ||
34 | 30 | ||
35 | #define PXA_UHC_MAX_PORTNUM 3 | 31 | #define PXA_UHC_MAX_PORTNUM 3 |
36 | 32 | ||
37 | #define UHCRHPS(x) __REG2( 0x4C000050, (x)<<2 ) | 33 | #define UHCRHPS(x) __REG2( 0x4C000050, (x)<<2 ) |
38 | 34 | ||
39 | static int pxa27x_ohci_pmm_state; | ||
40 | |||
41 | /* | 35 | /* |
42 | PMM_NPS_MODE -- PMM Non-power switching mode | 36 | PMM_NPS_MODE -- PMM Non-power switching mode |
43 | Ports are powered continuously. | 37 | Ports are powered continuously. |
@@ -50,8 +44,6 @@ static int pxa27x_ohci_pmm_state; | |||
50 | */ | 44 | */ |
51 | static int pxa27x_ohci_select_pmm( int mode ) | 45 | static int pxa27x_ohci_select_pmm( int mode ) |
52 | { | 46 | { |
53 | pxa27x_ohci_pmm_state = mode; | ||
54 | |||
55 | switch ( mode ) { | 47 | switch ( mode ) { |
56 | case PMM_NPS_MODE: | 48 | case PMM_NPS_MODE: |
57 | UHCRHDA |= RH_A_NPS; | 49 | UHCRHDA |= RH_A_NPS; |
@@ -71,7 +63,6 @@ static int pxa27x_ohci_select_pmm( int mode ) | |||
71 | "Invalid mode %d, set to non-power switch mode.\n", | 63 | "Invalid mode %d, set to non-power switch mode.\n", |
72 | mode ); | 64 | mode ); |
73 | 65 | ||
74 | pxa27x_ohci_pmm_state = PMM_NPS_MODE; | ||
75 | UHCRHDA |= RH_A_NPS; | 66 | UHCRHDA |= RH_A_NPS; |
76 | } | 67 | } |
77 | 68 | ||
@@ -82,8 +73,13 @@ extern int usb_disabled(void); | |||
82 | 73 | ||
83 | /*-------------------------------------------------------------------------*/ | 74 | /*-------------------------------------------------------------------------*/ |
84 | 75 | ||
85 | static void pxa27x_start_hc(struct platform_device *dev) | 76 | static int pxa27x_start_hc(struct device *dev) |
86 | { | 77 | { |
78 | int retval = 0; | ||
79 | struct pxaohci_platform_data *inf; | ||
80 | |||
81 | inf = dev->platform_data; | ||
82 | |||
87 | pxa_set_cken(CKEN10_USBHOST, 1); | 83 | pxa_set_cken(CKEN10_USBHOST, 1); |
88 | 84 | ||
89 | UHCHR |= UHCHR_FHR; | 85 | UHCHR |= UHCHR_FHR; |
@@ -94,21 +90,11 @@ static void pxa27x_start_hc(struct platform_device *dev) | |||
94 | while (UHCHR & UHCHR_FSBIR) | 90 | while (UHCHR & UHCHR_FSBIR) |
95 | cpu_relax(); | 91 | cpu_relax(); |
96 | 92 | ||
97 | /* This could be properly abstracted away through the | 93 | if (inf->init) |
98 | device data the day more machines are supported and | 94 | retval = inf->init(dev); |
99 | their differences can be figured out correctly. */ | ||
100 | if (machine_is_mainstone()) { | ||
101 | /* setup Port1 GPIO pin. */ | ||
102 | pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */ | ||
103 | pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */ | ||
104 | |||
105 | /* Set the Power Control Polarity Low and Power Sense | ||
106 | Polarity Low to active low. Supply power to USB ports. */ | ||
107 | UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) & | ||
108 | ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); | ||
109 | 95 | ||
110 | pxa27x_ohci_pmm_state = PMM_PERPORT_MODE; | 96 | if (retval < 0) |
111 | } | 97 | return retval; |
112 | 98 | ||
113 | UHCHR &= ~UHCHR_SSE; | 99 | UHCHR &= ~UHCHR_SSE; |
114 | 100 | ||
@@ -117,10 +103,19 @@ static void pxa27x_start_hc(struct platform_device *dev) | |||
117 | /* Clear any OTG Pin Hold */ | 103 | /* Clear any OTG Pin Hold */ |
118 | if (PSSR & PSSR_OTGPH) | 104 | if (PSSR & PSSR_OTGPH) |
119 | PSSR |= PSSR_OTGPH; | 105 | PSSR |= PSSR_OTGPH; |
106 | |||
107 | return 0; | ||
120 | } | 108 | } |
121 | 109 | ||
122 | static void pxa27x_stop_hc(struct platform_device *dev) | 110 | static void pxa27x_stop_hc(struct device *dev) |
123 | { | 111 | { |
112 | struct pxaohci_platform_data *inf; | ||
113 | |||
114 | inf = dev->platform_data; | ||
115 | |||
116 | if (inf->exit) | ||
117 | inf->exit(dev); | ||
118 | |||
124 | UHCHR |= UHCHR_FHR; | 119 | UHCHR |= UHCHR_FHR; |
125 | udelay(11); | 120 | udelay(11); |
126 | UHCHR &= ~UHCHR_FHR; | 121 | UHCHR &= ~UHCHR_FHR; |
@@ -147,22 +142,27 @@ static void pxa27x_stop_hc(struct platform_device *dev) | |||
147 | * through the hotplug entry's driver_data. | 142 | * through the hotplug entry's driver_data. |
148 | * | 143 | * |
149 | */ | 144 | */ |
150 | int usb_hcd_pxa27x_probe (const struct hc_driver *driver, | 145 | int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device *pdev) |
151 | struct platform_device *dev) | ||
152 | { | 146 | { |
153 | int retval; | 147 | int retval; |
154 | struct usb_hcd *hcd; | 148 | struct usb_hcd *hcd; |
149 | struct pxaohci_platform_data *inf; | ||
155 | 150 | ||
156 | if (dev->resource[1].flags != IORESOURCE_IRQ) { | 151 | inf = pdev->dev.platform_data; |
152 | |||
153 | if (!inf) | ||
154 | return -ENODEV; | ||
155 | |||
156 | if (pdev->resource[1].flags != IORESOURCE_IRQ) { | ||
157 | pr_debug ("resource[1] is not IORESOURCE_IRQ"); | 157 | pr_debug ("resource[1] is not IORESOURCE_IRQ"); |
158 | return -ENOMEM; | 158 | return -ENOMEM; |
159 | } | 159 | } |
160 | 160 | ||
161 | hcd = usb_create_hcd (driver, &dev->dev, "pxa27x"); | 161 | hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x"); |
162 | if (!hcd) | 162 | if (!hcd) |
163 | return -ENOMEM; | 163 | return -ENOMEM; |
164 | hcd->rsrc_start = dev->resource[0].start; | 164 | hcd->rsrc_start = pdev->resource[0].start; |
165 | hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; | 165 | hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; |
166 | 166 | ||
167 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | 167 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { |
168 | pr_debug("request_mem_region failed"); | 168 | pr_debug("request_mem_region failed"); |
@@ -177,18 +177,22 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, | |||
177 | goto err2; | 177 | goto err2; |
178 | } | 178 | } |
179 | 179 | ||
180 | pxa27x_start_hc(dev); | 180 | if ((retval = pxa27x_start_hc(&pdev->dev)) < 0) { |
181 | pr_debug("pxa27x_start_hc failed"); | ||
182 | goto err3; | ||
183 | } | ||
181 | 184 | ||
182 | /* Select Power Management Mode */ | 185 | /* Select Power Management Mode */ |
183 | pxa27x_ohci_select_pmm(pxa27x_ohci_pmm_state); | 186 | pxa27x_ohci_select_pmm(inf->port_mode); |
184 | 187 | ||
185 | ohci_hcd_init(hcd_to_ohci(hcd)); | 188 | ohci_hcd_init(hcd_to_ohci(hcd)); |
186 | 189 | ||
187 | retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT); | 190 | retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT); |
188 | if (retval == 0) | 191 | if (retval == 0) |
189 | return retval; | 192 | return retval; |
190 | 193 | ||
191 | pxa27x_stop_hc(dev); | 194 | pxa27x_stop_hc(&pdev->dev); |
195 | err3: | ||
192 | iounmap(hcd->regs); | 196 | iounmap(hcd->regs); |
193 | err2: | 197 | err2: |
194 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 198 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
@@ -211,10 +215,10 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, | |||
211 | * context, normally "rmmod", "apmd", or something similar. | 215 | * context, normally "rmmod", "apmd", or something similar. |
212 | * | 216 | * |
213 | */ | 217 | */ |
214 | void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *dev) | 218 | void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev) |
215 | { | 219 | { |
216 | usb_remove_hcd(hcd); | 220 | usb_remove_hcd(hcd); |
217 | pxa27x_stop_hc(dev); | 221 | pxa27x_stop_hc(&pdev->dev); |
218 | iounmap(hcd->regs); | 222 | iounmap(hcd->regs); |
219 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 223 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
220 | usb_put_hcd(hcd); | 224 | usb_put_hcd(hcd); |
@@ -292,15 +296,12 @@ static const struct hc_driver ohci_pxa27x_hc_driver = { | |||
292 | 296 | ||
293 | static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev) | 297 | static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev) |
294 | { | 298 | { |
295 | int ret; | ||
296 | |||
297 | pr_debug ("In ohci_hcd_pxa27x_drv_probe"); | 299 | pr_debug ("In ohci_hcd_pxa27x_drv_probe"); |
298 | 300 | ||
299 | if (usb_disabled()) | 301 | if (usb_disabled()) |
300 | return -ENODEV; | 302 | return -ENODEV; |
301 | 303 | ||
302 | ret = usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, pdev); | 304 | return usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, pdev); |
303 | return ret; | ||
304 | } | 305 | } |
305 | 306 | ||
306 | static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev) | 307 | static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev) |
@@ -308,31 +309,55 @@ static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev) | |||
308 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 309 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
309 | 310 | ||
310 | usb_hcd_pxa27x_remove(hcd, pdev); | 311 | usb_hcd_pxa27x_remove(hcd, pdev); |
312 | platform_set_drvdata(pdev, NULL); | ||
311 | return 0; | 313 | return 0; |
312 | } | 314 | } |
313 | 315 | ||
314 | static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *dev, pm_message_t state) | 316 | #ifdef CONFIG_PM |
317 | static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *pdev, pm_message_t state) | ||
315 | { | 318 | { |
316 | // struct usb_hcd *hcd = platform_get_drvdata(dev); | 319 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
317 | printk("%s: not implemented yet\n", __FUNCTION__); | 320 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
321 | |||
322 | if (time_before(jiffies, ohci->next_statechange)) | ||
323 | msleep(5); | ||
324 | ohci->next_statechange = jiffies; | ||
325 | |||
326 | pxa27x_stop_hc(&pdev->dev); | ||
327 | hcd->state = HC_STATE_SUSPENDED; | ||
328 | pdev->dev.power.power_state = PMSG_SUSPEND; | ||
318 | 329 | ||
319 | return 0; | 330 | return 0; |
320 | } | 331 | } |
321 | 332 | ||
322 | static int ohci_hcd_pxa27x_drv_resume(struct platform_device *dev) | 333 | static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev) |
323 | { | 334 | { |
324 | // struct usb_hcd *hcd = platform_get_drvdata(dev); | 335 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
325 | printk("%s: not implemented yet\n", __FUNCTION__); | 336 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
337 | int status; | ||
338 | |||
339 | if (time_before(jiffies, ohci->next_statechange)) | ||
340 | msleep(5); | ||
341 | ohci->next_statechange = jiffies; | ||
342 | |||
343 | if ((status = pxa27x_start_hc(&pdev->dev)) < 0) | ||
344 | return status; | ||
345 | |||
346 | pdev->dev.power.power_state = PMSG_ON; | ||
347 | usb_hcd_resume_root_hub(hcd); | ||
326 | 348 | ||
327 | return 0; | 349 | return 0; |
328 | } | 350 | } |
351 | #endif | ||
329 | 352 | ||
330 | 353 | ||
331 | static struct platform_driver ohci_hcd_pxa27x_driver = { | 354 | static struct platform_driver ohci_hcd_pxa27x_driver = { |
332 | .probe = ohci_hcd_pxa27x_drv_probe, | 355 | .probe = ohci_hcd_pxa27x_drv_probe, |
333 | .remove = ohci_hcd_pxa27x_drv_remove, | 356 | .remove = ohci_hcd_pxa27x_drv_remove, |
357 | #ifdef CONFIG_PM | ||
334 | .suspend = ohci_hcd_pxa27x_drv_suspend, | 358 | .suspend = ohci_hcd_pxa27x_drv_suspend, |
335 | .resume = ohci_hcd_pxa27x_drv_resume, | 359 | .resume = ohci_hcd_pxa27x_drv_resume, |
360 | #endif | ||
336 | .driver = { | 361 | .driver = { |
337 | .name = "pxa27x-ohci", | 362 | .name = "pxa27x-ohci", |
338 | }, | 363 | }, |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index e46528c825bf..3ef2c0cdf1db 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -9,12 +9,6 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/config.h> | 11 | #include <linux/config.h> |
12 | #ifdef CONFIG_USB_DEBUG | ||
13 | #define DEBUG | ||
14 | #else | ||
15 | #undef DEBUG | ||
16 | #endif | ||
17 | |||
18 | #include <linux/types.h> | 12 | #include <linux/types.h> |
19 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
20 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index a7722a6a5a5b..517360b77d8e 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -32,13 +32,6 @@ | |||
32 | #undef PACKET_TRACE | 32 | #undef PACKET_TRACE |
33 | 33 | ||
34 | #include <linux/config.h> | 34 | #include <linux/config.h> |
35 | |||
36 | #ifdef CONFIG_USB_DEBUG | ||
37 | # define DEBUG | ||
38 | #else | ||
39 | # undef DEBUG | ||
40 | #endif | ||
41 | |||
42 | #include <linux/module.h> | 35 | #include <linux/module.h> |
43 | #include <linux/moduleparam.h> | 36 | #include <linux/moduleparam.h> |
44 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
@@ -1581,7 +1574,9 @@ sl811h_start(struct usb_hcd *hcd) | |||
1581 | hcd->state = HC_STATE_RUNNING; | 1574 | hcd->state = HC_STATE_RUNNING; |
1582 | 1575 | ||
1583 | if (sl811->board) { | 1576 | if (sl811->board) { |
1584 | hcd->can_wakeup = sl811->board->can_wakeup; | 1577 | if (!device_can_wakeup(hcd->self.controller)) |
1578 | device_init_wakeup(hcd->self.controller, | ||
1579 | sl811->board->can_wakeup); | ||
1585 | hcd->power_budget = sl811->board->power * 2; | 1580 | hcd->power_budget = sl811->board->power * 2; |
1586 | } | 1581 | } |
1587 | 1582 | ||
@@ -1805,9 +1800,10 @@ sl811h_resume(struct platform_device *dev) | |||
1805 | * let's assume it'd only be powered to enable remote wakeup. | 1800 | * let's assume it'd only be powered to enable remote wakeup. |
1806 | */ | 1801 | */ |
1807 | if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND | 1802 | if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND |
1808 | || !hcd->can_wakeup) { | 1803 | || !device_can_wakeup(&hcd->self.root_hub->dev)) { |
1809 | sl811->port1 = 0; | 1804 | sl811->port1 = 0; |
1810 | port_power(sl811, 1); | 1805 | port_power(sl811, 1); |
1806 | usb_root_hub_lost_power(hcd->self.root_hub); | ||
1811 | return 0; | 1807 | return 0; |
1812 | } | 1808 | } |
1813 | 1809 | ||
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index e73faf831b24..5056b7459994 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c | |||
@@ -38,7 +38,7 @@ MODULE_LICENSE("GPL"); | |||
38 | /* MACROS */ | 38 | /* MACROS */ |
39 | /*====================================================================*/ | 39 | /*====================================================================*/ |
40 | 40 | ||
41 | #if defined(DEBUG) || defined(CONFIG_USB_DEBUG) || defined(PCMCIA_DEBUG) | 41 | #if defined(DEBUG) || defined(PCMCIA_DEBUG) |
42 | 42 | ||
43 | static int pc_debug = 0; | 43 | static int pc_debug = 0; |
44 | module_param(pc_debug, int, 0644); | 44 | module_param(pc_debug, int, 0644); |
@@ -129,7 +129,8 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) | |||
129 | resources[2].end = base_addr + 1; | 129 | resources[2].end = base_addr + 1; |
130 | 130 | ||
131 | /* The driver core will probe for us. We know sl811-hcd has been | 131 | /* The driver core will probe for us. We know sl811-hcd has been |
132 | * initialized already because of the link order dependency. | 132 | * initialized already because of the link order dependency created |
133 | * by referencing "sl811h_driver". | ||
133 | */ | 134 | */ |
134 | platform_dev.name = sl811h_driver.name; | 135 | platform_dev.name = sl811h_driver.name; |
135 | return platform_device_register(&platform_dev); | 136 | return platform_device_register(&platform_dev); |
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 151154df37fa..5832953086f8 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
@@ -2,8 +2,8 @@ | |||
2 | * UHCI-specific debugging code. Invaluable when something | 2 | * UHCI-specific debugging code. Invaluable when something |
3 | * goes wrong, but don't get in my face. | 3 | * goes wrong, but don't get in my face. |
4 | * | 4 | * |
5 | * Kernel visible pointers are surrounded in []'s and bus | 5 | * Kernel visible pointers are surrounded in []s and bus |
6 | * visible pointers are surrounded in ()'s | 6 | * visible pointers are surrounded in ()s |
7 | * | 7 | * |
8 | * (C) Copyright 1999 Linus Torvalds | 8 | * (C) Copyright 1999 Linus Torvalds |
9 | * (C) Copyright 1999-2001 Johannes Erdfelt | 9 | * (C) Copyright 1999-2001 Johannes Erdfelt |
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | static struct dentry *uhci_debugfs_root = NULL; | 20 | static struct dentry *uhci_debugfs_root = NULL; |
21 | 21 | ||
22 | /* Handle REALLY large printk's so we don't overflow buffers */ | 22 | /* Handle REALLY large printks so we don't overflow buffers */ |
23 | static inline void lprintk(char *buf) | 23 | static inline void lprintk(char *buf) |
24 | { | 24 | { |
25 | char *p; | 25 | char *p; |
@@ -160,7 +160,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) | |||
160 | } | 160 | } |
161 | 161 | ||
162 | if (active && ni > i) { | 162 | if (active && ni > i) { |
163 | out += sprintf(out, "%*s[skipped %d active TD's]\n", space, "", ni - i); | 163 | out += sprintf(out, "%*s[skipped %d active TDs]\n", space, "", ni - i); |
164 | tmp = ntmp; | 164 | tmp = ntmp; |
165 | td = ntd; | 165 | td = ntd; |
166 | i = ni; | 166 | i = ni; |
@@ -173,7 +173,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) | |||
173 | if (list_empty(&urbp->queue_list) || urbp->queued) | 173 | if (list_empty(&urbp->queue_list) || urbp->queued) |
174 | goto out; | 174 | goto out; |
175 | 175 | ||
176 | out += sprintf(out, "%*sQueued QH's:\n", -space, "--"); | 176 | out += sprintf(out, "%*sQueued QHs:\n", -space, "--"); |
177 | 177 | ||
178 | head = &urbp->queue_list; | 178 | head = &urbp->queue_list; |
179 | tmp = head->next; | 179 | tmp = head->next; |
@@ -197,7 +197,7 @@ out: | |||
197 | } | 197 | } |
198 | 198 | ||
199 | #ifdef CONFIG_PROC_FS | 199 | #ifdef CONFIG_PROC_FS |
200 | static const char *qh_names[] = { | 200 | static const char * const qh_names[] = { |
201 | "skel_int128_qh", "skel_int64_qh", | 201 | "skel_int128_qh", "skel_int64_qh", |
202 | "skel_int32_qh", "skel_int16_qh", | 202 | "skel_int32_qh", "skel_int16_qh", |
203 | "skel_int8_qh", "skel_int4_qh", | 203 | "skel_int8_qh", "skel_int4_qh", |
@@ -464,7 +464,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
464 | } while (tmp != head); | 464 | } while (tmp != head); |
465 | } | 465 | } |
466 | 466 | ||
467 | out += sprintf(out, "Skeleton QH's\n"); | 467 | out += sprintf(out, "Skeleton QHs\n"); |
468 | 468 | ||
469 | for (i = 0; i < UHCI_NUM_SKELQH; ++i) { | 469 | for (i = 0; i < UHCI_NUM_SKELQH; ++i) { |
470 | int shown = 0; | 470 | int shown = 0; |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index ed550132db0b..dfe121d35887 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -23,11 +23,6 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/config.h> | 25 | #include <linux/config.h> |
26 | #ifdef CONFIG_USB_DEBUG | ||
27 | #define DEBUG | ||
28 | #else | ||
29 | #undef DEBUG | ||
30 | #endif | ||
31 | #include <linux/module.h> | 26 | #include <linux/module.h> |
32 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
33 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
@@ -67,10 +62,10 @@ Alan Stern" | |||
67 | 62 | ||
68 | /* | 63 | /* |
69 | * debug = 0, no debugging messages | 64 | * debug = 0, no debugging messages |
70 | * debug = 1, dump failed URB's except for stalls | 65 | * debug = 1, dump failed URBs except for stalls |
71 | * debug = 2, dump all failed URB's (including stalls) | 66 | * debug = 2, dump all failed URBs (including stalls) |
72 | * show all queues in /debug/uhci/[pci_addr] | 67 | * show all queues in /debug/uhci/[pci_addr] |
73 | * debug = 3, show all TD's in URB's when dumping | 68 | * debug = 3, show all TDs in URBs when dumping |
74 | */ | 69 | */ |
75 | #ifdef DEBUG | 70 | #ifdef DEBUG |
76 | static int debug = 1; | 71 | static int debug = 1; |
@@ -93,7 +88,7 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci); | |||
93 | #define FSBR_DELAY msecs_to_jiffies(50) | 88 | #define FSBR_DELAY msecs_to_jiffies(50) |
94 | 89 | ||
95 | /* When we timeout an idle transfer for FSBR, we'll switch it over to */ | 90 | /* When we timeout an idle transfer for FSBR, we'll switch it over to */ |
96 | /* depth first traversal. We'll do it in groups of this number of TD's */ | 91 | /* depth first traversal. We'll do it in groups of this number of TDs */ |
97 | /* to make sure it doesn't hog all of the bandwidth */ | 92 | /* to make sure it doesn't hog all of the bandwidth */ |
98 | #define DEPTH_INTERVAL 5 | 93 | #define DEPTH_INTERVAL 5 |
99 | 94 | ||
@@ -478,8 +473,6 @@ static int uhci_start(struct usb_hcd *hcd) | |||
478 | struct dentry *dentry; | 473 | struct dentry *dentry; |
479 | 474 | ||
480 | hcd->uses_new_polling = 1; | 475 | hcd->uses_new_polling = 1; |
481 | if (pci_find_capability(to_pci_dev(uhci_dev(uhci)), PCI_CAP_ID_PM)) | ||
482 | hcd->can_wakeup = 1; /* Assume it supports PME# */ | ||
483 | 476 | ||
484 | dentry = debugfs_create_file(hcd->self.bus_name, | 477 | dentry = debugfs_create_file(hcd->self.bus_name, |
485 | S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci, | 478 | S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci, |
@@ -573,7 +566,7 @@ static int uhci_start(struct usb_hcd *hcd) | |||
573 | uhci->skel_bulk_qh->link = cpu_to_le32(uhci->skel_term_qh->dma_handle) | UHCI_PTR_QH; | 566 | uhci->skel_bulk_qh->link = cpu_to_le32(uhci->skel_term_qh->dma_handle) | UHCI_PTR_QH; |
574 | 567 | ||
575 | /* This dummy TD is to work around a bug in Intel PIIX controllers */ | 568 | /* This dummy TD is to work around a bug in Intel PIIX controllers */ |
576 | uhci_fill_td(uhci->term_td, 0, (UHCI_NULL_DATA_SIZE << 21) | | 569 | uhci_fill_td(uhci->term_td, 0, uhci_explen(0) | |
577 | (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0); | 570 | (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0); |
578 | uhci->term_td->link = cpu_to_le32(uhci->term_td->dma_handle); | 571 | uhci->term_td->link = cpu_to_le32(uhci->term_td->dma_handle); |
579 | 572 | ||
@@ -717,6 +710,7 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message) | |||
717 | * at the source, so we must turn off PIRQ. | 710 | * at the source, so we must turn off PIRQ. |
718 | */ | 711 | */ |
719 | pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0); | 712 | pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0); |
713 | mb(); | ||
720 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 714 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
721 | uhci->hc_inaccessible = 1; | 715 | uhci->hc_inaccessible = 1; |
722 | hcd->poll_rh = 0; | 716 | hcd->poll_rh = 0; |
@@ -734,10 +728,12 @@ static int uhci_resume(struct usb_hcd *hcd) | |||
734 | 728 | ||
735 | dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__); | 729 | dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__); |
736 | 730 | ||
737 | /* We aren't in D3 state anymore, we do that even if dead as I | 731 | /* Since we aren't in D3 any more, it's safe to set this flag |
738 | * really don't want to keep a stale HCD_FLAG_HW_ACCESSIBLE=0 | 732 | * even if the controller was dead. It might not even be dead |
733 | * any more, if the firmware or quirks code has reset it. | ||
739 | */ | 734 | */ |
740 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 735 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
736 | mb(); | ||
741 | 737 | ||
742 | if (uhci->rh_state == UHCI_RH_RESET) /* Dead */ | 738 | if (uhci->rh_state == UHCI_RH_RESET) /* Dead */ |
743 | return 0; | 739 | return 0; |
@@ -753,8 +749,12 @@ static int uhci_resume(struct usb_hcd *hcd) | |||
753 | check_and_reset_hc(uhci); | 749 | check_and_reset_hc(uhci); |
754 | configure_hc(uhci); | 750 | configure_hc(uhci); |
755 | 751 | ||
756 | if (uhci->rh_state == UHCI_RH_RESET) | 752 | if (uhci->rh_state == UHCI_RH_RESET) { |
753 | |||
754 | /* The controller had to be reset */ | ||
755 | usb_root_hub_lost_power(hcd->self.root_hub); | ||
757 | suspend_rh(uhci, UHCI_RH_SUSPENDED); | 756 | suspend_rh(uhci, UHCI_RH_SUSPENDED); |
757 | } | ||
758 | 758 | ||
759 | spin_unlock_irq(&uhci->lock); | 759 | spin_unlock_irq(&uhci->lock); |
760 | 760 | ||
@@ -880,7 +880,7 @@ static int __init uhci_hcd_init(void) | |||
880 | 880 | ||
881 | init_failed: | 881 | init_failed: |
882 | if (kmem_cache_destroy(uhci_up_cachep)) | 882 | if (kmem_cache_destroy(uhci_up_cachep)) |
883 | warn("not all urb_priv's were freed!"); | 883 | warn("not all urb_privs were freed!"); |
884 | 884 | ||
885 | up_failed: | 885 | up_failed: |
886 | debugfs_remove(uhci_debugfs_root); | 886 | debugfs_remove(uhci_debugfs_root); |
@@ -898,7 +898,7 @@ static void __exit uhci_hcd_cleanup(void) | |||
898 | pci_unregister_driver(&uhci_pci_driver); | 898 | pci_unregister_driver(&uhci_pci_driver); |
899 | 899 | ||
900 | if (kmem_cache_destroy(uhci_up_cachep)) | 900 | if (kmem_cache_destroy(uhci_up_cachep)) |
901 | warn("not all urb_priv's were freed!"); | 901 | warn("not all urb_privs were freed!"); |
902 | 902 | ||
903 | debugfs_remove(uhci_debugfs_root); | 903 | debugfs_remove(uhci_debugfs_root); |
904 | kfree(errbuf); | 904 | kfree(errbuf); |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index e576db57a926..8b4b887a7d41 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -71,8 +71,6 @@ | |||
71 | #define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ | 71 | #define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ |
72 | #define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ | 72 | #define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ |
73 | 73 | ||
74 | #define UHCI_NULL_DATA_SIZE 0x7FF /* for UHCI controller TD */ | ||
75 | |||
76 | #define UHCI_PTR_BITS cpu_to_le32(0x000F) | 74 | #define UHCI_PTR_BITS cpu_to_le32(0x000F) |
77 | #define UHCI_PTR_TERM cpu_to_le32(0x0001) | 75 | #define UHCI_PTR_TERM cpu_to_le32(0x0001) |
78 | #define UHCI_PTR_QH cpu_to_le32(0x0002) | 76 | #define UHCI_PTR_QH cpu_to_le32(0x0002) |
@@ -168,9 +166,11 @@ static __le32 inline qh_element(struct uhci_qh *qh) { | |||
168 | #define TD_TOKEN_EXPLEN_MASK 0x7FF /* expected length, encoded as n - 1 */ | 166 | #define TD_TOKEN_EXPLEN_MASK 0x7FF /* expected length, encoded as n - 1 */ |
169 | #define TD_TOKEN_PID_MASK 0xFF | 167 | #define TD_TOKEN_PID_MASK 0xFF |
170 | 168 | ||
171 | #define uhci_explen(len) ((len) << TD_TOKEN_EXPLEN_SHIFT) | 169 | #define uhci_explen(len) ((((len) - 1) & TD_TOKEN_EXPLEN_MASK) << \ |
170 | TD_TOKEN_EXPLEN_SHIFT) | ||
172 | 171 | ||
173 | #define uhci_expected_length(token) ((((token) >> 21) + 1) & TD_TOKEN_EXPLEN_MASK) | 172 | #define uhci_expected_length(token) ((((token) >> TD_TOKEN_EXPLEN_SHIFT) + \ |
173 | 1) & TD_TOKEN_EXPLEN_MASK) | ||
174 | #define uhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE_SHIFT) & 1) | 174 | #define uhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE_SHIFT) & 1) |
175 | #define uhci_endpoint(token) (((token) >> 15) & 0xf) | 175 | #define uhci_endpoint(token) (((token) >> 15) & 0xf) |
176 | #define uhci_devaddr(token) (((token) >> TD_TOKEN_DEVADDR_SHIFT) & 0x7f) | 176 | #define uhci_devaddr(token) (((token) >> TD_TOKEN_DEVADDR_SHIFT) & 0x7f) |
@@ -223,10 +223,10 @@ static u32 inline td_status(struct uhci_td *td) { | |||
223 | */ | 223 | */ |
224 | 224 | ||
225 | /* | 225 | /* |
226 | * The UHCI driver places Interrupt, Control and Bulk into QH's both | 226 | * The UHCI driver places Interrupt, Control and Bulk into QHs both |
227 | * to group together TD's for one transfer, and also to faciliate queuing | 227 | * to group together TDs for one transfer, and also to facilitate queuing |
228 | * of URB's. To make it easy to insert entries into the schedule, we have | 228 | * of URBs. To make it easy to insert entries into the schedule, we have |
229 | * a skeleton of QH's for each predefined Interrupt latency, low-speed | 229 | * a skeleton of QHs for each predefined Interrupt latency, low-speed |
230 | * control, full-speed control and terminating QH (see explanation for | 230 | * control, full-speed control and terminating QH (see explanation for |
231 | * the terminating QH below). | 231 | * the terminating QH below). |
232 | * | 232 | * |
@@ -257,8 +257,8 @@ static u32 inline td_status(struct uhci_td *td) { | |||
257 | * reclamation. | 257 | * reclamation. |
258 | * | 258 | * |
259 | * Isochronous transfers are stored before the start of the skeleton | 259 | * Isochronous transfers are stored before the start of the skeleton |
260 | * schedule and don't use QH's. While the UHCI spec doesn't forbid the | 260 | * schedule and don't use QHs. While the UHCI spec doesn't forbid the |
261 | * use of QH's for Isochronous, it doesn't use them either. And the spec | 261 | * use of QHs for Isochronous, it doesn't use them either. And the spec |
262 | * says that queues never advance on an error completion status, which | 262 | * says that queues never advance on an error completion status, which |
263 | * makes them totally unsuitable for Isochronous transfers. | 263 | * makes them totally unsuitable for Isochronous transfers. |
264 | */ | 264 | */ |
@@ -359,7 +359,7 @@ struct uhci_hcd { | |||
359 | struct dma_pool *td_pool; | 359 | struct dma_pool *td_pool; |
360 | 360 | ||
361 | struct uhci_td *term_td; /* Terminating TD, see UHCI bug */ | 361 | struct uhci_td *term_td; /* Terminating TD, see UHCI bug */ |
362 | struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */ | 362 | struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QHs */ |
363 | 363 | ||
364 | spinlock_t lock; | 364 | spinlock_t lock; |
365 | 365 | ||
@@ -389,22 +389,22 @@ struct uhci_hcd { | |||
389 | unsigned long resuming_ports; | 389 | unsigned long resuming_ports; |
390 | unsigned long ports_timeout; /* Time to stop signalling */ | 390 | unsigned long ports_timeout; /* Time to stop signalling */ |
391 | 391 | ||
392 | /* Main list of URB's currently controlled by this HC */ | 392 | /* Main list of URBs currently controlled by this HC */ |
393 | struct list_head urb_list; | 393 | struct list_head urb_list; |
394 | 394 | ||
395 | /* List of QH's that are done, but waiting to be unlinked (race) */ | 395 | /* List of QHs that are done, but waiting to be unlinked (race) */ |
396 | struct list_head qh_remove_list; | 396 | struct list_head qh_remove_list; |
397 | unsigned int qh_remove_age; /* Age in frames */ | 397 | unsigned int qh_remove_age; /* Age in frames */ |
398 | 398 | ||
399 | /* List of TD's that are done, but waiting to be freed (race) */ | 399 | /* List of TDs that are done, but waiting to be freed (race) */ |
400 | struct list_head td_remove_list; | 400 | struct list_head td_remove_list; |
401 | unsigned int td_remove_age; /* Age in frames */ | 401 | unsigned int td_remove_age; /* Age in frames */ |
402 | 402 | ||
403 | /* List of asynchronously unlinked URB's */ | 403 | /* List of asynchronously unlinked URBs */ |
404 | struct list_head urb_remove_list; | 404 | struct list_head urb_remove_list; |
405 | unsigned int urb_remove_age; /* Age in frames */ | 405 | unsigned int urb_remove_age; /* Age in frames */ |
406 | 406 | ||
407 | /* List of URB's awaiting completion callback */ | 407 | /* List of URBs awaiting completion callback */ |
408 | struct list_head complete_list; | 408 | struct list_head complete_list; |
409 | 409 | ||
410 | int rh_numports; /* Number of root-hub ports */ | 410 | int rh_numports; /* Number of root-hub ports */ |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 7e46887d9e12..b6076004a437 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -80,7 +80,7 @@ static inline void uhci_fill_td(struct uhci_td *td, u32 status, | |||
80 | } | 80 | } |
81 | 81 | ||
82 | /* | 82 | /* |
83 | * We insert Isochronous URB's directly into the frame list at the beginning | 83 | * We insert Isochronous URBs directly into the frame list at the beginning |
84 | */ | 84 | */ |
85 | static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, unsigned framenum) | 85 | static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, unsigned framenum) |
86 | { | 86 | { |
@@ -369,7 +369,7 @@ static void uhci_append_queued_urb(struct uhci_hcd *uhci, struct urb *eurb, stru | |||
369 | uhci_fixup_toggle(urb, | 369 | uhci_fixup_toggle(urb, |
370 | uhci_toggle(td_token(lltd)) ^ 1)); | 370 | uhci_toggle(td_token(lltd)) ^ 1)); |
371 | 371 | ||
372 | /* All qh's in the queue need to link to the next queue */ | 372 | /* All qhs in the queue need to link to the next queue */ |
373 | urbp->qh->link = eurbp->qh->link; | 373 | urbp->qh->link = eurbp->qh->link; |
374 | 374 | ||
375 | wmb(); /* Make sure we flush everything */ | 375 | wmb(); /* Make sure we flush everything */ |
@@ -502,7 +502,7 @@ static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb) | |||
502 | } | 502 | } |
503 | 503 | ||
504 | /* Check to see if the remove list is empty. Set the IOC bit */ | 504 | /* Check to see if the remove list is empty. Set the IOC bit */ |
505 | /* to force an interrupt so we can remove the TD's*/ | 505 | /* to force an interrupt so we can remove the TDs*/ |
506 | if (list_empty(&uhci->td_remove_list)) | 506 | if (list_empty(&uhci->td_remove_list)) |
507 | uhci_set_next_interrupt(uhci); | 507 | uhci_set_next_interrupt(uhci); |
508 | 508 | ||
@@ -596,7 +596,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur | |||
596 | return -ENOMEM; | 596 | return -ENOMEM; |
597 | 597 | ||
598 | uhci_add_td_to_urb(urb, td); | 598 | uhci_add_td_to_urb(urb, td); |
599 | uhci_fill_td(td, status, destination | uhci_explen(7), | 599 | uhci_fill_td(td, status, destination | uhci_explen(8), |
600 | urb->setup_dma); | 600 | urb->setup_dma); |
601 | 601 | ||
602 | /* | 602 | /* |
@@ -612,7 +612,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur | |||
612 | } | 612 | } |
613 | 613 | ||
614 | /* | 614 | /* |
615 | * Build the DATA TD's | 615 | * Build the DATA TDs |
616 | */ | 616 | */ |
617 | while (len > 0) { | 617 | while (len > 0) { |
618 | int pktsze = len; | 618 | int pktsze = len; |
@@ -628,7 +628,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur | |||
628 | destination ^= TD_TOKEN_TOGGLE; | 628 | destination ^= TD_TOKEN_TOGGLE; |
629 | 629 | ||
630 | uhci_add_td_to_urb(urb, td); | 630 | uhci_add_td_to_urb(urb, td); |
631 | uhci_fill_td(td, status, destination | uhci_explen(pktsze - 1), | 631 | uhci_fill_td(td, status, destination | uhci_explen(pktsze), |
632 | data); | 632 | data); |
633 | 633 | ||
634 | data += pktsze; | 634 | data += pktsze; |
@@ -658,7 +658,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur | |||
658 | 658 | ||
659 | uhci_add_td_to_urb(urb, td); | 659 | uhci_add_td_to_urb(urb, td); |
660 | uhci_fill_td(td, status | TD_CTRL_IOC, | 660 | uhci_fill_td(td, status | TD_CTRL_IOC, |
661 | destination | uhci_explen(UHCI_NULL_DATA_SIZE), 0); | 661 | destination | uhci_explen(0), 0); |
662 | 662 | ||
663 | qh = uhci_alloc_qh(uhci); | 663 | qh = uhci_alloc_qh(uhci); |
664 | if (!qh) | 664 | if (!qh) |
@@ -744,7 +744,7 @@ static int uhci_result_control(struct uhci_hcd *uhci, struct urb *urb) | |||
744 | 744 | ||
745 | urb->actual_length = 0; | 745 | urb->actual_length = 0; |
746 | 746 | ||
747 | /* The rest of the TD's (but the last) are data */ | 747 | /* The rest of the TDs (but the last) are data */ |
748 | tmp = tmp->next; | 748 | tmp = tmp->next; |
749 | while (tmp != head && tmp->next != head) { | 749 | while (tmp != head && tmp->next != head) { |
750 | unsigned int ctrlstat; | 750 | unsigned int ctrlstat; |
@@ -848,7 +848,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb | |||
848 | status |= TD_CTRL_SPD; | 848 | status |= TD_CTRL_SPD; |
849 | 849 | ||
850 | /* | 850 | /* |
851 | * Build the DATA TD's | 851 | * Build the DATA TDs |
852 | */ | 852 | */ |
853 | do { /* Allow zero length packets */ | 853 | do { /* Allow zero length packets */ |
854 | int pktsze = maxsze; | 854 | int pktsze = maxsze; |
@@ -864,7 +864,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb | |||
864 | return -ENOMEM; | 864 | return -ENOMEM; |
865 | 865 | ||
866 | uhci_add_td_to_urb(urb, td); | 866 | uhci_add_td_to_urb(urb, td); |
867 | uhci_fill_td(td, status, destination | uhci_explen(pktsze - 1) | | 867 | uhci_fill_td(td, status, destination | uhci_explen(pktsze) | |
868 | (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), | 868 | (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), |
869 | usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), | 869 | usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), |
870 | data); | 870 | data); |
@@ -890,7 +890,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb | |||
890 | return -ENOMEM; | 890 | return -ENOMEM; |
891 | 891 | ||
892 | uhci_add_td_to_urb(urb, td); | 892 | uhci_add_td_to_urb(urb, td); |
893 | uhci_fill_td(td, status, destination | uhci_explen(UHCI_NULL_DATA_SIZE) | | 893 | uhci_fill_td(td, status, destination | uhci_explen(0) | |
894 | (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), | 894 | (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), |
895 | usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), | 895 | usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), |
896 | data); | 896 | data); |
@@ -1025,7 +1025,7 @@ static int isochronous_find_limits(struct uhci_hcd *uhci, struct urb *urb, unsig | |||
1025 | list_for_each_entry(up, &uhci->urb_list, urb_list) { | 1025 | list_for_each_entry(up, &uhci->urb_list, urb_list) { |
1026 | struct urb *u = up->urb; | 1026 | struct urb *u = up->urb; |
1027 | 1027 | ||
1028 | /* look for pending URB's with identical pipe handle */ | 1028 | /* look for pending URBs with identical pipe handle */ |
1029 | if ((urb->pipe == u->pipe) && (urb->dev == u->dev) && | 1029 | if ((urb->pipe == u->pipe) && (urb->dev == u->dev) && |
1030 | (u->status == -EINPROGRESS) && (u != urb)) { | 1030 | (u->status == -EINPROGRESS) && (u != urb)) { |
1031 | if (!last_urb) | 1031 | if (!last_urb) |
@@ -1092,7 +1092,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1092 | return -ENOMEM; | 1092 | return -ENOMEM; |
1093 | 1093 | ||
1094 | uhci_add_td_to_urb(urb, td); | 1094 | uhci_add_td_to_urb(urb, td); |
1095 | uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length - 1), | 1095 | uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length), |
1096 | urb->transfer_dma + urb->iso_frame_desc[i].offset); | 1096 | urb->transfer_dma + urb->iso_frame_desc[i].offset); |
1097 | 1097 | ||
1098 | if (i + 1 >= urb->number_of_packets) | 1098 | if (i + 1 >= urb->number_of_packets) |
@@ -1355,7 +1355,7 @@ static void uhci_unlink_generic(struct uhci_hcd *uhci, struct urb *urb) | |||
1355 | 1355 | ||
1356 | uhci_delete_queued_urb(uhci, urb); | 1356 | uhci_delete_queued_urb(uhci, urb); |
1357 | 1357 | ||
1358 | /* The interrupt loop will reclaim the QH's */ | 1358 | /* The interrupt loop will reclaim the QHs */ |
1359 | uhci_remove_qh(uhci, urbp->qh); | 1359 | uhci_remove_qh(uhci, urbp->qh); |
1360 | urbp->qh = NULL; | 1360 | urbp->qh = NULL; |
1361 | } | 1361 | } |
@@ -1413,7 +1413,7 @@ static int uhci_fsbr_timeout(struct uhci_hcd *uhci, struct urb *urb) | |||
1413 | list_for_each_entry(td, head, list) { | 1413 | list_for_each_entry(td, head, list) { |
1414 | /* | 1414 | /* |
1415 | * Make sure we don't do the last one (since it'll have the | 1415 | * Make sure we don't do the last one (since it'll have the |
1416 | * TERM bit set) as well as we skip every so many TD's to | 1416 | * TERM bit set) as well as we skip every so many TDs to |
1417 | * make sure it doesn't hog the bandwidth | 1417 | * make sure it doesn't hog the bandwidth |
1418 | */ | 1418 | */ |
1419 | if (td->list.next != head && (count % DEPTH_INTERVAL) == | 1419 | if (td->list.next != head && (count % DEPTH_INTERVAL) == |
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 1d973bcf56aa..049871145d63 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c | |||
@@ -962,7 +962,6 @@ MODULE_DEVICE_TABLE (usb, mdc800_table); | |||
962 | */ | 962 | */ |
963 | static struct usb_driver mdc800_usb_driver = | 963 | static struct usb_driver mdc800_usb_driver = |
964 | { | 964 | { |
965 | .owner = THIS_MODULE, | ||
966 | .name = "mdc800", | 965 | .name = "mdc800", |
967 | .probe = mdc800_usb_probe, | 966 | .probe = mdc800_usb_probe, |
968 | .disconnect = mdc800_usb_disconnect, | 967 | .disconnect = mdc800_usb_disconnect, |
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 950543aa5ac7..458f2acdeb0a 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c | |||
@@ -160,7 +160,6 @@ static void mts_usb_disconnect(struct usb_interface *intf); | |||
160 | static struct usb_device_id mts_usb_ids []; | 160 | static struct usb_device_id mts_usb_ids []; |
161 | 161 | ||
162 | static struct usb_driver mts_usb_driver = { | 162 | static struct usb_driver mts_usb_driver = { |
163 | .owner = THIS_MODULE, | ||
164 | .name = "microtekX6", | 163 | .name = "microtekX6", |
165 | .probe = mts_usb_probe, | 164 | .probe = mts_usb_probe, |
166 | .disconnect = mts_usb_disconnect, | 165 | .disconnect = mts_usb_disconnect, |
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index 1e53934907c0..509dd0a04c54 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig | |||
@@ -273,6 +273,20 @@ config USB_ATI_REMOTE | |||
273 | To compile this driver as a module, choose M here: the module will be | 273 | To compile this driver as a module, choose M here: the module will be |
274 | called ati_remote. | 274 | called ati_remote. |
275 | 275 | ||
276 | config USB_ATI_REMOTE2 | ||
277 | tristate "ATI / Philips USB RF remote control" | ||
278 | depends on USB && INPUT | ||
279 | ---help--- | ||
280 | Say Y here if you want to use an ATI or Philips USB RF remote control. | ||
281 | These are RF remotes with USB receivers. | ||
282 | ATI Remote Wonder II comes with some ATI's All-In-Wonder video cards | ||
283 | and is also available as a separate product. | ||
284 | This driver provides mouse pointer, left and right mouse buttons, | ||
285 | and maps all the other remote buttons to keypress events. | ||
286 | |||
287 | To compile this driver as a module, choose M here: the module will be | ||
288 | called ati_remote2. | ||
289 | |||
276 | config USB_KEYSPAN_REMOTE | 290 | config USB_KEYSPAN_REMOTE |
277 | tristate "Keyspan DMR USB remote control (EXPERIMENTAL)" | 291 | tristate "Keyspan DMR USB remote control (EXPERIMENTAL)" |
278 | depends on USB && INPUT && EXPERIMENTAL | 292 | depends on USB && INPUT && EXPERIMENTAL |
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile index 07cb17db42fc..d512d9f488fe 100644 --- a/drivers/usb/input/Makefile +++ b/drivers/usb/input/Makefile | |||
@@ -28,6 +28,7 @@ endif | |||
28 | 28 | ||
29 | obj-$(CONFIG_USB_AIPTEK) += aiptek.o | 29 | obj-$(CONFIG_USB_AIPTEK) += aiptek.o |
30 | obj-$(CONFIG_USB_ATI_REMOTE) += ati_remote.o | 30 | obj-$(CONFIG_USB_ATI_REMOTE) += ati_remote.o |
31 | obj-$(CONFIG_USB_ATI_REMOTE2) += ati_remote2.o | ||
31 | obj-$(CONFIG_USB_HID) += usbhid.o | 32 | obj-$(CONFIG_USB_HID) += usbhid.o |
32 | obj-$(CONFIG_USB_KBD) += usbkbd.o | 33 | obj-$(CONFIG_USB_KBD) += usbkbd.o |
33 | obj-$(CONFIG_USB_KBTAB) += kbtab.o | 34 | obj-$(CONFIG_USB_KBTAB) += kbtab.o |
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c index a32558b4048e..df29b8078b54 100644 --- a/drivers/usb/input/acecad.c +++ b/drivers/usb/input/acecad.c | |||
@@ -261,7 +261,6 @@ static struct usb_device_id usb_acecad_id_table [] = { | |||
261 | MODULE_DEVICE_TABLE(usb, usb_acecad_id_table); | 261 | MODULE_DEVICE_TABLE(usb, usb_acecad_id_table); |
262 | 262 | ||
263 | static struct usb_driver usb_acecad_driver = { | 263 | static struct usb_driver usb_acecad_driver = { |
264 | .owner = THIS_MODULE, | ||
265 | .name = "usb_acecad", | 264 | .name = "usb_acecad", |
266 | .probe = usb_acecad_probe, | 265 | .probe = usb_acecad_probe, |
267 | .disconnect = usb_acecad_disconnect, | 266 | .disconnect = usb_acecad_disconnect, |
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index 1c3b472a3bca..a6693b0d1c4c 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c | |||
@@ -338,7 +338,7 @@ struct aiptek { | |||
338 | * the bitmap which comes from the tablet. This hides the | 338 | * the bitmap which comes from the tablet. This hides the |
339 | * issue that the F_keys are not sequentially numbered. | 339 | * issue that the F_keys are not sequentially numbered. |
340 | */ | 340 | */ |
341 | static int macroKeyEvents[] = { | 341 | static const int macroKeyEvents[] = { |
342 | KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, | 342 | KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, |
343 | KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, | 343 | KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, |
344 | KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17, | 344 | KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17, |
@@ -2093,7 +2093,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
2093 | /* Programming the tablet macro keys needs to be done with a for loop | 2093 | /* Programming the tablet macro keys needs to be done with a for loop |
2094 | * as the keycodes are discontiguous. | 2094 | * as the keycodes are discontiguous. |
2095 | */ | 2095 | */ |
2096 | for (i = 0; i < sizeof(macroKeyEvents) / sizeof(macroKeyEvents[0]); ++i) | 2096 | for (i = 0; i < ARRAY_SIZE(macroKeyEvents); ++i) |
2097 | set_bit(macroKeyEvents[i], inputdev->keybit); | 2097 | set_bit(macroKeyEvents[i], inputdev->keybit); |
2098 | 2098 | ||
2099 | /* | 2099 | /* |
@@ -2103,7 +2103,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
2103 | * values. | 2103 | * values. |
2104 | */ | 2104 | */ |
2105 | input_set_abs_params(inputdev, ABS_X, 0, 2999, 0, 0); | 2105 | input_set_abs_params(inputdev, ABS_X, 0, 2999, 0, 0); |
2106 | input_set_abs_params(inputdev, ABS_X, 0, 2249, 0, 0); | 2106 | input_set_abs_params(inputdev, ABS_Y, 0, 2249, 0, 0); |
2107 | input_set_abs_params(inputdev, ABS_PRESSURE, 0, 511, 0, 0); | 2107 | input_set_abs_params(inputdev, ABS_PRESSURE, 0, 511, 0, 0); |
2108 | input_set_abs_params(inputdev, ABS_TILT_X, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0); | 2108 | input_set_abs_params(inputdev, ABS_TILT_X, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0); |
2109 | input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0); | 2109 | input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0); |
@@ -2135,7 +2135,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
2135 | * not an error :-) | 2135 | * not an error :-) |
2136 | */ | 2136 | */ |
2137 | 2137 | ||
2138 | for (i = 0; i < sizeof(speeds) / sizeof(speeds[0]); ++i) { | 2138 | for (i = 0; i < ARRAY_SIZE(speeds); ++i) { |
2139 | aiptek->curSetting.programmableDelay = speeds[i]; | 2139 | aiptek->curSetting.programmableDelay = speeds[i]; |
2140 | (void)aiptek_program_tablet(aiptek); | 2140 | (void)aiptek_program_tablet(aiptek); |
2141 | if (aiptek->inputdev->absmax[ABS_X] > 0) { | 2141 | if (aiptek->inputdev->absmax[ABS_X] > 0) { |
@@ -2190,7 +2190,6 @@ fail1: input_free_device(inputdev); | |||
2190 | static void aiptek_disconnect(struct usb_interface *intf); | 2190 | static void aiptek_disconnect(struct usb_interface *intf); |
2191 | 2191 | ||
2192 | static struct usb_driver aiptek_driver = { | 2192 | static struct usb_driver aiptek_driver = { |
2193 | .owner = THIS_MODULE, | ||
2194 | .name = "aiptek", | 2193 | .name = "aiptek", |
2195 | .probe = aiptek_probe, | 2194 | .probe = aiptek_probe, |
2196 | .disconnect = aiptek_disconnect, | 2195 | .disconnect = aiptek_disconnect, |
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c index 15840db092a5..1949b54f41f2 100644 --- a/drivers/usb/input/appletouch.c +++ b/drivers/usb/input/appletouch.c | |||
@@ -452,7 +452,6 @@ static int atp_resume(struct usb_interface *iface) | |||
452 | } | 452 | } |
453 | 453 | ||
454 | static struct usb_driver atp_driver = { | 454 | static struct usb_driver atp_driver = { |
455 | .owner = THIS_MODULE, | ||
456 | .name = "appletouch", | 455 | .name = "appletouch", |
457 | .probe = atp_probe, | 456 | .probe = atp_probe, |
458 | .disconnect = atp_disconnect, | 457 | .disconnect = atp_disconnect, |
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index 9a2a47db9494..f7bdc506e613 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c | |||
@@ -96,6 +96,7 @@ | |||
96 | #include <linux/usb.h> | 96 | #include <linux/usb.h> |
97 | #include <linux/usb_input.h> | 97 | #include <linux/usb_input.h> |
98 | #include <linux/wait.h> | 98 | #include <linux/wait.h> |
99 | #include <linux/jiffies.h> | ||
99 | 100 | ||
100 | /* | 101 | /* |
101 | * Module and Version Information, Module Parameters | 102 | * Module and Version Information, Module Parameters |
@@ -146,7 +147,7 @@ static char init1[] = { 0x01, 0x00, 0x20, 0x14 }; | |||
146 | static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 }; | 147 | static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 }; |
147 | 148 | ||
148 | /* Acceleration curve for directional control pad */ | 149 | /* Acceleration curve for directional control pad */ |
149 | static char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; | 150 | static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; |
150 | 151 | ||
151 | /* Duplicate event filtering time. | 152 | /* Duplicate event filtering time. |
152 | * Sequential, identical KIND_FILTERED inputs with less than | 153 | * Sequential, identical KIND_FILTERED inputs with less than |
@@ -197,7 +198,7 @@ struct ati_remote { | |||
197 | #define KIND_ACCEL 7 /* Directional keypad - left, right, up, down.*/ | 198 | #define KIND_ACCEL 7 /* Directional keypad - left, right, up, down.*/ |
198 | 199 | ||
199 | /* Translation table from hardware messages to input events. */ | 200 | /* Translation table from hardware messages to input events. */ |
200 | static struct { | 201 | static const struct { |
201 | short kind; | 202 | short kind; |
202 | unsigned char data1, data2; | 203 | unsigned char data1, data2; |
203 | int type; | 204 | int type; |
@@ -295,7 +296,6 @@ static void ati_remote_disconnect (struct usb_interface *interface); | |||
295 | 296 | ||
296 | /* usb specific object to register with the usb subsystem */ | 297 | /* usb specific object to register with the usb subsystem */ |
297 | static struct usb_driver ati_remote_driver = { | 298 | static struct usb_driver ati_remote_driver = { |
298 | .owner = THIS_MODULE, | ||
299 | .name = "ati_remote", | 299 | .name = "ati_remote", |
300 | .probe = ati_remote_probe, | 300 | .probe = ati_remote_probe, |
301 | .disconnect = ati_remote_disconnect, | 301 | .disconnect = ati_remote_disconnect, |
@@ -472,7 +472,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
472 | /* Filter duplicate events which happen "too close" together. */ | 472 | /* Filter duplicate events which happen "too close" together. */ |
473 | if ((ati_remote->old_data[0] == data[1]) && | 473 | if ((ati_remote->old_data[0] == data[1]) && |
474 | (ati_remote->old_data[1] == data[2]) && | 474 | (ati_remote->old_data[1] == data[2]) && |
475 | ((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) { | 475 | time_before(jiffies, ati_remote->old_jiffies + FILTER_TIME)) { |
476 | ati_remote->repeat_count++; | 476 | ati_remote->repeat_count++; |
477 | } else { | 477 | } else { |
478 | ati_remote->repeat_count = 0; | 478 | ati_remote->repeat_count = 0; |
@@ -507,16 +507,16 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
507 | * pad down, so we increase acceleration, ramping up over two seconds to | 507 | * pad down, so we increase acceleration, ramping up over two seconds to |
508 | * a maximum speed. The acceleration curve is #defined above. | 508 | * a maximum speed. The acceleration curve is #defined above. |
509 | */ | 509 | */ |
510 | if ((jiffies - ati_remote->old_jiffies) > (HZ >> 2)) { | 510 | if (time_after(jiffies, ati_remote->old_jiffies + (HZ >> 2))) { |
511 | acc = 1; | 511 | acc = 1; |
512 | ati_remote->acc_jiffies = jiffies; | 512 | ati_remote->acc_jiffies = jiffies; |
513 | } | 513 | } |
514 | else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 3)) acc = accel[0]; | 514 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 3))) acc = accel[0]; |
515 | else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 2)) acc = accel[1]; | 515 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 2))) acc = accel[1]; |
516 | else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 1)) acc = accel[2]; | 516 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 1))) acc = accel[2]; |
517 | else if ((jiffies - ati_remote->acc_jiffies) < HZ ) acc = accel[3]; | 517 | else if (time_before(jiffies, ati_remote->acc_jiffies + HZ)) acc = accel[3]; |
518 | else if ((jiffies - ati_remote->acc_jiffies) < HZ+(HZ>>1)) acc = accel[4]; | 518 | else if (time_before(jiffies, ati_remote->acc_jiffies + HZ+(HZ>>1))) acc = accel[4]; |
519 | else if ((jiffies - ati_remote->acc_jiffies) < (HZ << 1)) acc = accel[5]; | 519 | else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ << 1))) acc = accel[5]; |
520 | else acc = accel[6]; | 520 | else acc = accel[6]; |
521 | 521 | ||
522 | input_regs(dev, regs); | 522 | input_regs(dev, regs); |
diff --git a/drivers/usb/input/ati_remote2.c b/drivers/usb/input/ati_remote2.c new file mode 100644 index 000000000000..ab1a1ae24be9 --- /dev/null +++ b/drivers/usb/input/ati_remote2.c | |||
@@ -0,0 +1,477 @@ | |||
1 | /* | ||
2 | * ati_remote2 - ATI/Philips USB RF remote driver | ||
3 | * | ||
4 | * Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/usb_input.h> | ||
12 | |||
13 | #define DRIVER_DESC "ATI/Philips USB RF remote driver" | ||
14 | #define DRIVER_VERSION "0.1" | ||
15 | |||
16 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
17 | MODULE_VERSION(DRIVER_VERSION); | ||
18 | MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>"); | ||
19 | MODULE_LICENSE("GPL"); | ||
20 | |||
21 | static unsigned int mode_mask = 0x1F; | ||
22 | module_param(mode_mask, uint, 0644); | ||
23 | MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>"); | ||
24 | |||
25 | static struct usb_device_id ati_remote2_id_table[] = { | ||
26 | { USB_DEVICE(0x0471, 0x0602) }, /* ATI Remote Wonder II */ | ||
27 | { } | ||
28 | }; | ||
29 | MODULE_DEVICE_TABLE(usb, ati_remote2_id_table); | ||
30 | |||
31 | static struct { | ||
32 | int hw_code; | ||
33 | int key_code; | ||
34 | } ati_remote2_key_table[] = { | ||
35 | { 0x00, KEY_0 }, | ||
36 | { 0x01, KEY_1 }, | ||
37 | { 0x02, KEY_2 }, | ||
38 | { 0x03, KEY_3 }, | ||
39 | { 0x04, KEY_4 }, | ||
40 | { 0x05, KEY_5 }, | ||
41 | { 0x06, KEY_6 }, | ||
42 | { 0x07, KEY_7 }, | ||
43 | { 0x08, KEY_8 }, | ||
44 | { 0x09, KEY_9 }, | ||
45 | { 0x0c, KEY_POWER }, | ||
46 | { 0x0d, KEY_MUTE }, | ||
47 | { 0x10, KEY_VOLUMEUP }, | ||
48 | { 0x11, KEY_VOLUMEDOWN }, | ||
49 | { 0x20, KEY_CHANNELUP }, | ||
50 | { 0x21, KEY_CHANNELDOWN }, | ||
51 | { 0x28, KEY_FORWARD }, | ||
52 | { 0x29, KEY_REWIND }, | ||
53 | { 0x2c, KEY_PLAY }, | ||
54 | { 0x30, KEY_PAUSE }, | ||
55 | { 0x31, KEY_STOP }, | ||
56 | { 0x37, KEY_RECORD }, | ||
57 | { 0x38, KEY_DVD }, | ||
58 | { 0x39, KEY_TV }, | ||
59 | { 0x54, KEY_MENU }, | ||
60 | { 0x58, KEY_UP }, | ||
61 | { 0x59, KEY_DOWN }, | ||
62 | { 0x5a, KEY_LEFT }, | ||
63 | { 0x5b, KEY_RIGHT }, | ||
64 | { 0x5c, KEY_OK }, | ||
65 | { 0x78, KEY_A }, | ||
66 | { 0x79, KEY_B }, | ||
67 | { 0x7a, KEY_C }, | ||
68 | { 0x7b, KEY_D }, | ||
69 | { 0x7c, KEY_E }, | ||
70 | { 0x7d, KEY_F }, | ||
71 | { 0x82, KEY_ENTER }, | ||
72 | { 0x8e, KEY_VENDOR }, | ||
73 | { 0x96, KEY_COFFEE }, | ||
74 | { 0xa9, BTN_LEFT }, | ||
75 | { 0xaa, BTN_RIGHT }, | ||
76 | { 0xbe, KEY_QUESTION }, | ||
77 | { 0xd5, KEY_FRONT }, | ||
78 | { 0xd0, KEY_EDIT }, | ||
79 | { 0xf9, KEY_INFO }, | ||
80 | { (0x00 << 8) | 0x3f, KEY_PROG1 }, | ||
81 | { (0x01 << 8) | 0x3f, KEY_PROG2 }, | ||
82 | { (0x02 << 8) | 0x3f, KEY_PROG3 }, | ||
83 | { (0x03 << 8) | 0x3f, KEY_PROG4 }, | ||
84 | { (0x04 << 8) | 0x3f, KEY_PC }, | ||
85 | { 0, KEY_RESERVED } | ||
86 | }; | ||
87 | |||
88 | struct ati_remote2 { | ||
89 | struct input_dev *idev; | ||
90 | struct usb_device *udev; | ||
91 | |||
92 | struct usb_interface *intf[2]; | ||
93 | struct usb_endpoint_descriptor *ep[2]; | ||
94 | struct urb *urb[2]; | ||
95 | void *buf[2]; | ||
96 | dma_addr_t buf_dma[2]; | ||
97 | |||
98 | unsigned long jiffies; | ||
99 | int mode; | ||
100 | |||
101 | char name[64]; | ||
102 | char phys[64]; | ||
103 | }; | ||
104 | |||
105 | static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id); | ||
106 | static void ati_remote2_disconnect(struct usb_interface *interface); | ||
107 | |||
108 | static struct usb_driver ati_remote2_driver = { | ||
109 | .name = "ati_remote2", | ||
110 | .probe = ati_remote2_probe, | ||
111 | .disconnect = ati_remote2_disconnect, | ||
112 | .id_table = ati_remote2_id_table, | ||
113 | }; | ||
114 | |||
115 | static int ati_remote2_open(struct input_dev *idev) | ||
116 | { | ||
117 | struct ati_remote2 *ar2 = idev->private; | ||
118 | int r; | ||
119 | |||
120 | r = usb_submit_urb(ar2->urb[0], GFP_KERNEL); | ||
121 | if (r) { | ||
122 | dev_err(&ar2->intf[0]->dev, | ||
123 | "%s: usb_submit_urb() = %d\n", __FUNCTION__, r); | ||
124 | return r; | ||
125 | } | ||
126 | r = usb_submit_urb(ar2->urb[1], GFP_KERNEL); | ||
127 | if (r) { | ||
128 | usb_kill_urb(ar2->urb[0]); | ||
129 | dev_err(&ar2->intf[1]->dev, | ||
130 | "%s: usb_submit_urb() = %d\n", __FUNCTION__, r); | ||
131 | return r; | ||
132 | } | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static void ati_remote2_close(struct input_dev *idev) | ||
138 | { | ||
139 | struct ati_remote2 *ar2 = idev->private; | ||
140 | |||
141 | usb_kill_urb(ar2->urb[0]); | ||
142 | usb_kill_urb(ar2->urb[1]); | ||
143 | } | ||
144 | |||
145 | static void ati_remote2_input_mouse(struct ati_remote2 *ar2, struct pt_regs *regs) | ||
146 | { | ||
147 | struct input_dev *idev = ar2->idev; | ||
148 | u8 *data = ar2->buf[0]; | ||
149 | |||
150 | if (data[0] > 4) { | ||
151 | dev_err(&ar2->intf[0]->dev, | ||
152 | "Unknown mode byte (%02x %02x %02x %02x)\n", | ||
153 | data[3], data[2], data[1], data[0]); | ||
154 | return; | ||
155 | } | ||
156 | |||
157 | if (!((1 << data[0]) & mode_mask)) | ||
158 | return; | ||
159 | |||
160 | input_regs(idev, regs); | ||
161 | input_event(idev, EV_REL, REL_X, (s8) data[1]); | ||
162 | input_event(idev, EV_REL, REL_Y, (s8) data[2]); | ||
163 | input_sync(idev); | ||
164 | } | ||
165 | |||
166 | static int ati_remote2_lookup(unsigned int hw_code) | ||
167 | { | ||
168 | int i; | ||
169 | |||
170 | for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++) | ||
171 | if (ati_remote2_key_table[i].hw_code == hw_code) | ||
172 | return i; | ||
173 | |||
174 | return -1; | ||
175 | } | ||
176 | |||
177 | static void ati_remote2_input_key(struct ati_remote2 *ar2, struct pt_regs *regs) | ||
178 | { | ||
179 | struct input_dev *idev = ar2->idev; | ||
180 | u8 *data = ar2->buf[1]; | ||
181 | int hw_code, index; | ||
182 | |||
183 | if (data[0] > 4) { | ||
184 | dev_err(&ar2->intf[1]->dev, | ||
185 | "Unknown mode byte (%02x %02x %02x %02x)\n", | ||
186 | data[3], data[2], data[1], data[0]); | ||
187 | return; | ||
188 | } | ||
189 | |||
190 | hw_code = data[2]; | ||
191 | /* | ||
192 | * Mode keys (AUX1-AUX4, PC) all generate the same code byte. | ||
193 | * Use the mode byte to figure out which one was pressed. | ||
194 | */ | ||
195 | if (hw_code == 0x3f) { | ||
196 | /* | ||
197 | * For some incomprehensible reason the mouse pad generates | ||
198 | * events which look identical to the events from the last | ||
199 | * pressed mode key. Naturally we don't want to generate key | ||
200 | * events for the mouse pad so we filter out any subsequent | ||
201 | * events from the same mode key. | ||
202 | */ | ||
203 | if (ar2->mode == data[0]) | ||
204 | return; | ||
205 | |||
206 | if (data[1] == 0) | ||
207 | ar2->mode = data[0]; | ||
208 | |||
209 | hw_code |= data[0] << 8; | ||
210 | } | ||
211 | |||
212 | if (!((1 << data[0]) & mode_mask)) | ||
213 | return; | ||
214 | |||
215 | index = ati_remote2_lookup(hw_code); | ||
216 | if (index < 0) { | ||
217 | dev_err(&ar2->intf[1]->dev, | ||
218 | "Unknown code byte (%02x %02x %02x %02x)\n", | ||
219 | data[3], data[2], data[1], data[0]); | ||
220 | return; | ||
221 | } | ||
222 | |||
223 | switch (data[1]) { | ||
224 | case 0: /* release */ | ||
225 | break; | ||
226 | case 1: /* press */ | ||
227 | ar2->jiffies = jiffies + msecs_to_jiffies(idev->rep[REP_DELAY]); | ||
228 | break; | ||
229 | case 2: /* repeat */ | ||
230 | |||
231 | /* No repeat for mouse buttons. */ | ||
232 | if (ati_remote2_key_table[index].key_code == BTN_LEFT || | ||
233 | ati_remote2_key_table[index].key_code == BTN_RIGHT) | ||
234 | return; | ||
235 | |||
236 | if (!time_after_eq(jiffies, ar2->jiffies)) | ||
237 | return; | ||
238 | |||
239 | ar2->jiffies = jiffies + msecs_to_jiffies(idev->rep[REP_PERIOD]); | ||
240 | break; | ||
241 | default: | ||
242 | dev_err(&ar2->intf[1]->dev, | ||
243 | "Unknown state byte (%02x %02x %02x %02x)\n", | ||
244 | data[3], data[2], data[1], data[0]); | ||
245 | return; | ||
246 | } | ||
247 | |||
248 | input_regs(idev, regs); | ||
249 | input_event(idev, EV_KEY, ati_remote2_key_table[index].key_code, data[1]); | ||
250 | input_sync(idev); | ||
251 | } | ||
252 | |||
253 | static void ati_remote2_complete_mouse(struct urb *urb, struct pt_regs *regs) | ||
254 | { | ||
255 | struct ati_remote2 *ar2 = urb->context; | ||
256 | int r; | ||
257 | |||
258 | switch (urb->status) { | ||
259 | case 0: | ||
260 | ati_remote2_input_mouse(ar2, regs); | ||
261 | break; | ||
262 | case -ENOENT: | ||
263 | case -EILSEQ: | ||
264 | case -ECONNRESET: | ||
265 | case -ESHUTDOWN: | ||
266 | dev_dbg(&ar2->intf[0]->dev, | ||
267 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | ||
268 | return; | ||
269 | default: | ||
270 | dev_err(&ar2->intf[0]->dev, | ||
271 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | ||
272 | } | ||
273 | |||
274 | r = usb_submit_urb(urb, GFP_ATOMIC); | ||
275 | if (r) | ||
276 | dev_err(&ar2->intf[0]->dev, | ||
277 | "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r); | ||
278 | } | ||
279 | |||
280 | static void ati_remote2_complete_key(struct urb *urb, struct pt_regs *regs) | ||
281 | { | ||
282 | struct ati_remote2 *ar2 = urb->context; | ||
283 | int r; | ||
284 | |||
285 | switch (urb->status) { | ||
286 | case 0: | ||
287 | ati_remote2_input_key(ar2, regs); | ||
288 | break; | ||
289 | case -ENOENT: | ||
290 | case -EILSEQ: | ||
291 | case -ECONNRESET: | ||
292 | case -ESHUTDOWN: | ||
293 | dev_dbg(&ar2->intf[1]->dev, | ||
294 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | ||
295 | return; | ||
296 | default: | ||
297 | dev_err(&ar2->intf[1]->dev, | ||
298 | "%s(): urb status = %d\n", __FUNCTION__, urb->status); | ||
299 | } | ||
300 | |||
301 | r = usb_submit_urb(urb, GFP_ATOMIC); | ||
302 | if (r) | ||
303 | dev_err(&ar2->intf[1]->dev, | ||
304 | "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r); | ||
305 | } | ||
306 | |||
307 | static int ati_remote2_input_init(struct ati_remote2 *ar2) | ||
308 | { | ||
309 | struct input_dev *idev; | ||
310 | int i; | ||
311 | |||
312 | idev = input_allocate_device(); | ||
313 | if (!idev) | ||
314 | return -ENOMEM; | ||
315 | |||
316 | ar2->idev = idev; | ||
317 | idev->private = ar2; | ||
318 | |||
319 | idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL); | ||
320 | idev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); | ||
321 | idev->relbit[0] = BIT(REL_X) | BIT(REL_Y); | ||
322 | for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++) | ||
323 | set_bit(ati_remote2_key_table[i].key_code, idev->keybit); | ||
324 | |||
325 | idev->rep[REP_DELAY] = 250; | ||
326 | idev->rep[REP_PERIOD] = 33; | ||
327 | |||
328 | idev->open = ati_remote2_open; | ||
329 | idev->close = ati_remote2_close; | ||
330 | |||
331 | idev->name = ar2->name; | ||
332 | idev->phys = ar2->phys; | ||
333 | |||
334 | usb_to_input_id(ar2->udev, &idev->id); | ||
335 | idev->cdev.dev = &ar2->udev->dev; | ||
336 | |||
337 | i = input_register_device(idev); | ||
338 | if (i) | ||
339 | input_free_device(idev); | ||
340 | |||
341 | return i; | ||
342 | } | ||
343 | |||
344 | static int ati_remote2_urb_init(struct ati_remote2 *ar2) | ||
345 | { | ||
346 | struct usb_device *udev = ar2->udev; | ||
347 | int i, pipe, maxp; | ||
348 | |||
349 | for (i = 0; i < 2; i++) { | ||
350 | ar2->buf[i] = usb_buffer_alloc(udev, 4, GFP_KERNEL, &ar2->buf_dma[i]); | ||
351 | if (!ar2->buf[i]) | ||
352 | return -ENOMEM; | ||
353 | |||
354 | ar2->urb[i] = usb_alloc_urb(0, GFP_KERNEL); | ||
355 | if (!ar2->urb[i]) | ||
356 | return -ENOMEM; | ||
357 | |||
358 | pipe = usb_rcvintpipe(udev, ar2->ep[i]->bEndpointAddress); | ||
359 | maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); | ||
360 | maxp = maxp > 4 ? 4 : maxp; | ||
361 | |||
362 | usb_fill_int_urb(ar2->urb[i], udev, pipe, ar2->buf[i], maxp, | ||
363 | i ? ati_remote2_complete_key : ati_remote2_complete_mouse, | ||
364 | ar2, ar2->ep[i]->bInterval); | ||
365 | ar2->urb[i]->transfer_dma = ar2->buf_dma[i]; | ||
366 | ar2->urb[i]->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
367 | } | ||
368 | |||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2) | ||
373 | { | ||
374 | int i; | ||
375 | |||
376 | for (i = 0; i < 2; i++) { | ||
377 | if (ar2->urb[i]) | ||
378 | usb_free_urb(ar2->urb[i]); | ||
379 | |||
380 | if (ar2->buf[i]) | ||
381 | usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]); | ||
382 | } | ||
383 | } | ||
384 | |||
385 | static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id) | ||
386 | { | ||
387 | struct usb_device *udev = interface_to_usbdev(interface); | ||
388 | struct usb_host_interface *alt = interface->cur_altsetting; | ||
389 | struct ati_remote2 *ar2; | ||
390 | int r; | ||
391 | |||
392 | if (alt->desc.bInterfaceNumber) | ||
393 | return -ENODEV; | ||
394 | |||
395 | ar2 = kzalloc(sizeof (struct ati_remote2), GFP_KERNEL); | ||
396 | if (!ar2) | ||
397 | return -ENOMEM; | ||
398 | |||
399 | ar2->udev = udev; | ||
400 | |||
401 | ar2->intf[0] = interface; | ||
402 | ar2->ep[0] = &alt->endpoint[0].desc; | ||
403 | |||
404 | ar2->intf[1] = usb_ifnum_to_if(udev, 1); | ||
405 | r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2); | ||
406 | if (r) | ||
407 | goto fail1; | ||
408 | alt = ar2->intf[1]->cur_altsetting; | ||
409 | ar2->ep[1] = &alt->endpoint[0].desc; | ||
410 | |||
411 | r = ati_remote2_urb_init(ar2); | ||
412 | if (r) | ||
413 | goto fail2; | ||
414 | |||
415 | usb_make_path(udev, ar2->phys, sizeof(ar2->phys)); | ||
416 | strlcat(ar2->phys, "/input0", sizeof(ar2->phys)); | ||
417 | |||
418 | strlcat(ar2->name, "ATI Remote Wonder II", sizeof(ar2->name)); | ||
419 | |||
420 | r = ati_remote2_input_init(ar2); | ||
421 | if (r) | ||
422 | goto fail2; | ||
423 | |||
424 | usb_set_intfdata(interface, ar2); | ||
425 | |||
426 | return 0; | ||
427 | |||
428 | fail2: | ||
429 | ati_remote2_urb_cleanup(ar2); | ||
430 | |||
431 | usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); | ||
432 | fail1: | ||
433 | kfree(ar2); | ||
434 | |||
435 | return r; | ||
436 | } | ||
437 | |||
438 | static void ati_remote2_disconnect(struct usb_interface *interface) | ||
439 | { | ||
440 | struct ati_remote2 *ar2; | ||
441 | struct usb_host_interface *alt = interface->cur_altsetting; | ||
442 | |||
443 | if (alt->desc.bInterfaceNumber) | ||
444 | return; | ||
445 | |||
446 | ar2 = usb_get_intfdata(interface); | ||
447 | usb_set_intfdata(interface, NULL); | ||
448 | |||
449 | input_unregister_device(ar2->idev); | ||
450 | |||
451 | ati_remote2_urb_cleanup(ar2); | ||
452 | |||
453 | usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); | ||
454 | |||
455 | kfree(ar2); | ||
456 | } | ||
457 | |||
458 | static int __init ati_remote2_init(void) | ||
459 | { | ||
460 | int r; | ||
461 | |||
462 | r = usb_register(&ati_remote2_driver); | ||
463 | if (r) | ||
464 | printk(KERN_ERR "ati_remote2: usb_register() = %d\n", r); | ||
465 | else | ||
466 | printk(KERN_INFO "ati_remote2: " DRIVER_DESC " " DRIVER_VERSION "\n"); | ||
467 | |||
468 | return r; | ||
469 | } | ||
470 | |||
471 | static void __exit ati_remote2_exit(void) | ||
472 | { | ||
473 | usb_deregister(&ati_remote2_driver); | ||
474 | } | ||
475 | |||
476 | module_init(ati_remote2_init); | ||
477 | module_exit(ati_remote2_exit); | ||
diff --git a/drivers/usb/input/fixp-arith.h b/drivers/usb/input/fixp-arith.h index 26ca5b890a61..b44d398de071 100644 --- a/drivers/usb/input/fixp-arith.h +++ b/drivers/usb/input/fixp-arith.h | |||
@@ -38,7 +38,7 @@ typedef s16 fixp_t; | |||
38 | #define FRAC_MASK ((1<<FRAC_N)-1) | 38 | #define FRAC_MASK ((1<<FRAC_N)-1) |
39 | 39 | ||
40 | // Not to be used directly. Use fixp_{cos,sin} | 40 | // Not to be used directly. Use fixp_{cos,sin} |
41 | static fixp_t cos_table[45] = { | 41 | static const fixp_t cos_table[45] = { |
42 | 0x0100, 0x00FF, 0x00FF, 0x00FE, 0x00FD, 0x00FC, 0x00FA, 0x00F8, | 42 | 0x0100, 0x00FF, 0x00FF, 0x00FE, 0x00FD, 0x00FC, 0x00FA, 0x00F8, |
43 | 0x00F6, 0x00F3, 0x00F0, 0x00ED, 0x00E9, 0x00E6, 0x00E2, 0x00DD, | 43 | 0x00F6, 0x00F3, 0x00F0, 0x00ED, 0x00E9, 0x00E6, 0x00E2, 0x00DD, |
44 | 0x00D9, 0x00D4, 0x00CF, 0x00C9, 0x00C4, 0x00BE, 0x00B8, 0x00B1, | 44 | 0x00D9, 0x00D4, 0x00CF, 0x00C9, 0x00C4, 0x00BE, 0x00B8, 0x00B1, |
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index a3e44ef1df43..5f52979af1c7 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -1454,7 +1454,7 @@ void hid_init_reports(struct hid_device *hid) | |||
1454 | * Alphabetically sorted blacklist by quirk type. | 1454 | * Alphabetically sorted blacklist by quirk type. |
1455 | */ | 1455 | */ |
1456 | 1456 | ||
1457 | static struct hid_blacklist { | 1457 | static const struct hid_blacklist { |
1458 | __u16 idVendor; | 1458 | __u16 idVendor; |
1459 | __u16 idProduct; | 1459 | __u16 idProduct; |
1460 | unsigned quirks; | 1460 | unsigned quirks; |
@@ -1930,7 +1930,6 @@ static struct usb_device_id hid_usb_ids [] = { | |||
1930 | MODULE_DEVICE_TABLE (usb, hid_usb_ids); | 1930 | MODULE_DEVICE_TABLE (usb, hid_usb_ids); |
1931 | 1931 | ||
1932 | static struct usb_driver hid_driver = { | 1932 | static struct usb_driver hid_driver = { |
1933 | .owner = THIS_MODULE, | ||
1934 | .name = "usbhid", | 1933 | .name = "usbhid", |
1935 | .probe = hid_probe, | 1934 | .probe = hid_probe, |
1936 | .disconnect = hid_disconnect, | 1935 | .disconnect = hid_disconnect, |
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 9ff25eb520a6..192a03b28971 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c | |||
@@ -39,7 +39,7 @@ | |||
39 | 39 | ||
40 | #define unk KEY_UNKNOWN | 40 | #define unk KEY_UNKNOWN |
41 | 41 | ||
42 | static unsigned char hid_keyboard[256] = { | 42 | static const unsigned char hid_keyboard[256] = { |
43 | 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, | 43 | 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, |
44 | 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, | 44 | 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, |
45 | 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, | 45 | 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, |
@@ -58,7 +58,7 @@ static unsigned char hid_keyboard[256] = { | |||
58 | 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk | 58 | 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk |
59 | }; | 59 | }; |
60 | 60 | ||
61 | static struct { | 61 | static const struct { |
62 | __s32 x; | 62 | __s32 x; |
63 | __s32 y; | 63 | __s32 y; |
64 | } hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}}; | 64 | } hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}}; |
@@ -137,6 +137,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
137 | switch (usage->hid & 0xffff) { | 137 | switch (usage->hid & 0xffff) { |
138 | case 0xba: map_abs(ABS_RUDDER); break; | 138 | case 0xba: map_abs(ABS_RUDDER); break; |
139 | case 0xbb: map_abs(ABS_THROTTLE); break; | 139 | case 0xbb: map_abs(ABS_THROTTLE); break; |
140 | default: goto ignore; | ||
140 | } | 141 | } |
141 | break; | 142 | break; |
142 | 143 | ||
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index 440377c7a0da..4dff8473553d 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c | |||
@@ -826,7 +826,6 @@ static int hiddev_usbd_probe(struct usb_interface *intf, | |||
826 | 826 | ||
827 | 827 | ||
828 | static /* const */ struct usb_driver hiddev_driver = { | 828 | static /* const */ struct usb_driver hiddev_driver = { |
829 | .owner = THIS_MODULE, | ||
830 | .name = "hiddev", | 829 | .name = "hiddev", |
831 | .probe = hiddev_usbd_probe, | 830 | .probe = hiddev_usbd_probe, |
832 | }; | 831 | }; |
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c index 4a50acb39d29..7618ae5c104f 100644 --- a/drivers/usb/input/itmtouch.c +++ b/drivers/usb/input/itmtouch.c | |||
@@ -250,7 +250,6 @@ static void itmtouch_disconnect(struct usb_interface *intf) | |||
250 | MODULE_DEVICE_TABLE(usb, itmtouch_ids); | 250 | MODULE_DEVICE_TABLE(usb, itmtouch_ids); |
251 | 251 | ||
252 | static struct usb_driver itmtouch_driver = { | 252 | static struct usb_driver itmtouch_driver = { |
253 | .owner = THIS_MODULE, | ||
254 | .name = "itmtouch", | 253 | .name = "itmtouch", |
255 | .probe = itmtouch_probe, | 254 | .probe = itmtouch_probe, |
256 | .disconnect = itmtouch_disconnect, | 255 | .disconnect = itmtouch_disconnect, |
diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c index a248664b5d1d..f6d5cead542b 100644 --- a/drivers/usb/input/kbtab.c +++ b/drivers/usb/input/kbtab.c | |||
@@ -159,7 +159,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
159 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH); | 159 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH); |
160 | input_dev->mscbit[0] |= BIT(MSC_SERIAL); | 160 | input_dev->mscbit[0] |= BIT(MSC_SERIAL); |
161 | input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0); | 161 | input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0); |
162 | input_set_abs_params(input_dev, ABS_X, 0, 0x1750, 4, 0); | 162 | input_set_abs_params(input_dev, ABS_Y, 0, 0x1750, 4, 0); |
163 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0); | 163 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0); |
164 | 164 | ||
165 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | 165 | endpoint = &intf->cur_altsetting->endpoint[0].desc; |
@@ -197,7 +197,6 @@ static void kbtab_disconnect(struct usb_interface *intf) | |||
197 | } | 197 | } |
198 | 198 | ||
199 | static struct usb_driver kbtab_driver = { | 199 | static struct usb_driver kbtab_driver = { |
200 | .owner = THIS_MODULE, | ||
201 | .name = "kbtab", | 200 | .name = "kbtab", |
202 | .probe = kbtab_probe, | 201 | .probe = kbtab_probe, |
203 | .disconnect = kbtab_disconnect, | 202 | .disconnect = kbtab_disconnect, |
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c index a32cfe51b77d..b4a051b549d1 100644 --- a/drivers/usb/input/keyspan_remote.c +++ b/drivers/usb/input/keyspan_remote.c | |||
@@ -95,7 +95,7 @@ struct usb_keyspan { | |||
95 | * Currently there are 15 and 17 button models so RESERVED codes | 95 | * Currently there are 15 and 17 button models so RESERVED codes |
96 | * are blank areas in the mapping. | 96 | * are blank areas in the mapping. |
97 | */ | 97 | */ |
98 | static int keyspan_key_table[] = { | 98 | static const int keyspan_key_table[] = { |
99 | KEY_RESERVED, /* 0 is just a place holder. */ | 99 | KEY_RESERVED, /* 0 is just a place holder. */ |
100 | KEY_RESERVED, | 100 | KEY_RESERVED, |
101 | KEY_STOP, | 101 | KEY_STOP, |
@@ -559,7 +559,6 @@ static void keyspan_disconnect(struct usb_interface *interface) | |||
559 | */ | 559 | */ |
560 | static struct usb_driver keyspan_driver = | 560 | static struct usb_driver keyspan_driver = |
561 | { | 561 | { |
562 | .owner = THIS_MODULE, | ||
563 | .name = "keyspan_remote", | 562 | .name = "keyspan_remote", |
564 | .probe = keyspan_probe, | 563 | .probe = keyspan_probe, |
565 | .disconnect = keyspan_disconnect, | 564 | .disconnect = keyspan_disconnect, |
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c index 52cc18cd247d..f018953a5485 100644 --- a/drivers/usb/input/mtouchusb.c +++ b/drivers/usb/input/mtouchusb.c | |||
@@ -310,7 +310,6 @@ static void mtouchusb_disconnect(struct usb_interface *intf) | |||
310 | MODULE_DEVICE_TABLE(usb, mtouchusb_devices); | 310 | MODULE_DEVICE_TABLE(usb, mtouchusb_devices); |
311 | 311 | ||
312 | static struct usb_driver mtouchusb_driver = { | 312 | static struct usb_driver mtouchusb_driver = { |
313 | .owner = THIS_MODULE, | ||
314 | .name = "mtouchusb", | 313 | .name = "mtouchusb", |
315 | .probe = mtouchusb_probe, | 314 | .probe = mtouchusb_probe, |
316 | .disconnect = mtouchusb_disconnect, | 315 | .disconnect = mtouchusb_disconnect, |
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c index b7476233ef5d..fdf0f788062c 100644 --- a/drivers/usb/input/powermate.c +++ b/drivers/usb/input/powermate.c | |||
@@ -441,7 +441,6 @@ static struct usb_device_id powermate_devices [] = { | |||
441 | MODULE_DEVICE_TABLE (usb, powermate_devices); | 441 | MODULE_DEVICE_TABLE (usb, powermate_devices); |
442 | 442 | ||
443 | static struct usb_driver powermate_driver = { | 443 | static struct usb_driver powermate_driver = { |
444 | .owner = THIS_MODULE, | ||
445 | .name = "powermate", | 444 | .name = "powermate", |
446 | .probe = powermate_probe, | 445 | .probe = powermate_probe, |
447 | .disconnect = powermate_disconnect, | 446 | .disconnect = powermate_disconnect, |
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c index 7420c6b84284..3b3c7b4120a2 100644 --- a/drivers/usb/input/touchkitusb.c +++ b/drivers/usb/input/touchkitusb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * touchkitusb.c -- Driver for eGalax TouchKit USB Touchscreens | 2 | * touchkitusb.c -- Driver for eGalax TouchKit USB Touchscreens |
3 | * | 3 | * |
4 | * Copyright (C) 2004 by Daniel Ritz | 4 | * Copyright (C) 2004-2005 by Daniel Ritz <daniel.ritz@gmx.ch> |
5 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) | 5 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
@@ -41,15 +41,13 @@ | |||
41 | #define TOUCHKIT_MAX_YC 0x07ff | 41 | #define TOUCHKIT_MAX_YC 0x07ff |
42 | #define TOUCHKIT_YC_FUZZ 0x0 | 42 | #define TOUCHKIT_YC_FUZZ 0x0 |
43 | #define TOUCHKIT_YC_FLAT 0x0 | 43 | #define TOUCHKIT_YC_FLAT 0x0 |
44 | #define TOUCHKIT_REPORT_DATA_SIZE 8 | 44 | #define TOUCHKIT_REPORT_DATA_SIZE 16 |
45 | 45 | ||
46 | #define TOUCHKIT_DOWN 0x01 | 46 | #define TOUCHKIT_DOWN 0x01 |
47 | #define TOUCHKIT_POINT_TOUCH 0x81 | ||
48 | #define TOUCHKIT_POINT_NOTOUCH 0x80 | ||
49 | 47 | ||
50 | #define TOUCHKIT_GET_TOUCHED(dat) ((((dat)[0]) & TOUCHKIT_DOWN) ? 1 : 0) | 48 | #define TOUCHKIT_PKT_TYPE_MASK 0xFE |
51 | #define TOUCHKIT_GET_X(dat) (((dat)[3] << 7) | (dat)[4]) | 49 | #define TOUCHKIT_PKT_TYPE_REPT 0x80 |
52 | #define TOUCHKIT_GET_Y(dat) (((dat)[1] << 7) | (dat)[2]) | 50 | #define TOUCHKIT_PKT_TYPE_DIAG 0x0A |
53 | 51 | ||
54 | #define DRIVER_VERSION "v0.1" | 52 | #define DRIVER_VERSION "v0.1" |
55 | #define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>" | 53 | #define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>" |
@@ -62,6 +60,8 @@ MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); | |||
62 | struct touchkit_usb { | 60 | struct touchkit_usb { |
63 | unsigned char *data; | 61 | unsigned char *data; |
64 | dma_addr_t data_dma; | 62 | dma_addr_t data_dma; |
63 | char buffer[TOUCHKIT_REPORT_DATA_SIZE]; | ||
64 | int buf_len; | ||
65 | struct urb *irq; | 65 | struct urb *irq; |
66 | struct usb_device *udev; | 66 | struct usb_device *udev; |
67 | struct input_dev *input; | 67 | struct input_dev *input; |
@@ -77,11 +77,128 @@ static struct usb_device_id touchkit_devices[] = { | |||
77 | {} | 77 | {} |
78 | }; | 78 | }; |
79 | 79 | ||
80 | /* helpers to read the data */ | ||
81 | static inline int touchkit_get_touched(char *data) | ||
82 | { | ||
83 | return (data[0] & TOUCHKIT_DOWN) ? 1 : 0; | ||
84 | } | ||
85 | |||
86 | static inline int touchkit_get_x(char *data) | ||
87 | { | ||
88 | return ((data[3] & 0x0F) << 7) | (data[4] & 0x7F); | ||
89 | } | ||
90 | |||
91 | static inline int touchkit_get_y(char *data) | ||
92 | { | ||
93 | return ((data[1] & 0x0F) << 7) | (data[2] & 0x7F); | ||
94 | } | ||
95 | |||
96 | |||
97 | /* processes one input packet. */ | ||
98 | static void touchkit_process_pkt(struct touchkit_usb *touchkit, | ||
99 | struct pt_regs *regs, char *pkt) | ||
100 | { | ||
101 | int x, y; | ||
102 | |||
103 | /* only process report packets */ | ||
104 | if ((pkt[0] & TOUCHKIT_PKT_TYPE_MASK) != TOUCHKIT_PKT_TYPE_REPT) | ||
105 | return; | ||
106 | |||
107 | if (swap_xy) { | ||
108 | y = touchkit_get_x(pkt); | ||
109 | x = touchkit_get_y(pkt); | ||
110 | } else { | ||
111 | x = touchkit_get_x(pkt); | ||
112 | y = touchkit_get_y(pkt); | ||
113 | } | ||
114 | |||
115 | input_regs(touchkit->input, regs); | ||
116 | input_report_key(touchkit->input, BTN_TOUCH, touchkit_get_touched(pkt)); | ||
117 | input_report_abs(touchkit->input, ABS_X, x); | ||
118 | input_report_abs(touchkit->input, ABS_Y, y); | ||
119 | input_sync(touchkit->input); | ||
120 | } | ||
121 | |||
122 | |||
123 | static int touchkit_get_pkt_len(char *buf) | ||
124 | { | ||
125 | switch (buf[0] & TOUCHKIT_PKT_TYPE_MASK) { | ||
126 | case TOUCHKIT_PKT_TYPE_REPT: | ||
127 | return 5; | ||
128 | |||
129 | case TOUCHKIT_PKT_TYPE_DIAG: | ||
130 | return buf[1] + 2; | ||
131 | } | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static void touchkit_process(struct touchkit_usb *touchkit, int len, | ||
137 | struct pt_regs *regs) | ||
138 | { | ||
139 | char *buffer; | ||
140 | int pkt_len, buf_len, pos; | ||
141 | |||
142 | /* if the buffer contains data, append */ | ||
143 | if (unlikely(touchkit->buf_len)) { | ||
144 | int tmp; | ||
145 | |||
146 | /* if only 1 byte in buffer, add another one to get length */ | ||
147 | if (touchkit->buf_len == 1) | ||
148 | touchkit->buffer[1] = touchkit->data[0]; | ||
149 | |||
150 | pkt_len = touchkit_get_pkt_len(touchkit->buffer); | ||
151 | |||
152 | /* unknown packet: drop everything */ | ||
153 | if (!pkt_len) | ||
154 | return; | ||
155 | |||
156 | /* append, process */ | ||
157 | tmp = pkt_len - touchkit->buf_len; | ||
158 | memcpy(touchkit->buffer + touchkit->buf_len, touchkit->data, tmp); | ||
159 | touchkit_process_pkt(touchkit, regs, touchkit->buffer); | ||
160 | |||
161 | buffer = touchkit->data + tmp; | ||
162 | buf_len = len - tmp; | ||
163 | } else { | ||
164 | buffer = touchkit->data; | ||
165 | buf_len = len; | ||
166 | } | ||
167 | |||
168 | /* only one byte left in buffer */ | ||
169 | if (unlikely(buf_len == 1)) { | ||
170 | touchkit->buffer[0] = buffer[0]; | ||
171 | touchkit->buf_len = 1; | ||
172 | return; | ||
173 | } | ||
174 | |||
175 | /* loop over the buffer */ | ||
176 | pos = 0; | ||
177 | while (pos < buf_len) { | ||
178 | /* get packet len */ | ||
179 | pkt_len = touchkit_get_pkt_len(buffer + pos); | ||
180 | |||
181 | /* unknown packet: drop everything */ | ||
182 | if (unlikely(!pkt_len)) | ||
183 | return; | ||
184 | |||
185 | /* full packet: process */ | ||
186 | if (likely(pkt_len <= buf_len)) { | ||
187 | touchkit_process_pkt(touchkit, regs, buffer + pos); | ||
188 | } else { | ||
189 | /* incomplete packet: save in buffer */ | ||
190 | memcpy(touchkit->buffer, buffer + pos, buf_len - pos); | ||
191 | touchkit->buf_len = buf_len - pos; | ||
192 | } | ||
193 | pos += pkt_len; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | |||
80 | static void touchkit_irq(struct urb *urb, struct pt_regs *regs) | 198 | static void touchkit_irq(struct urb *urb, struct pt_regs *regs) |
81 | { | 199 | { |
82 | struct touchkit_usb *touchkit = urb->context; | 200 | struct touchkit_usb *touchkit = urb->context; |
83 | int retval; | 201 | int retval; |
84 | int x, y; | ||
85 | 202 | ||
86 | switch (urb->status) { | 203 | switch (urb->status) { |
87 | case 0: | 204 | case 0: |
@@ -105,20 +222,7 @@ static void touchkit_irq(struct urb *urb, struct pt_regs *regs) | |||
105 | goto exit; | 222 | goto exit; |
106 | } | 223 | } |
107 | 224 | ||
108 | if (swap_xy) { | 225 | touchkit_process(touchkit, urb->actual_length, regs); |
109 | y = TOUCHKIT_GET_X(touchkit->data); | ||
110 | x = TOUCHKIT_GET_Y(touchkit->data); | ||
111 | } else { | ||
112 | x = TOUCHKIT_GET_X(touchkit->data); | ||
113 | y = TOUCHKIT_GET_Y(touchkit->data); | ||
114 | } | ||
115 | |||
116 | input_regs(touchkit->input, regs); | ||
117 | input_report_key(touchkit->input, BTN_TOUCH, | ||
118 | TOUCHKIT_GET_TOUCHED(touchkit->data)); | ||
119 | input_report_abs(touchkit->input, ABS_X, x); | ||
120 | input_report_abs(touchkit->input, ABS_Y, y); | ||
121 | input_sync(touchkit->input); | ||
122 | 226 | ||
123 | exit: | 227 | exit: |
124 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 228 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -267,7 +371,6 @@ static void touchkit_disconnect(struct usb_interface *intf) | |||
267 | MODULE_DEVICE_TABLE(usb, touchkit_devices); | 371 | MODULE_DEVICE_TABLE(usb, touchkit_devices); |
268 | 372 | ||
269 | static struct usb_driver touchkit_driver = { | 373 | static struct usb_driver touchkit_driver = { |
270 | .owner = THIS_MODULE, | ||
271 | .name = "touchkitusb", | 374 | .name = "touchkitusb", |
272 | .probe = touchkit_probe, | 375 | .probe = touchkit_probe, |
273 | .disconnect = touchkit_disconnect, | 376 | .disconnect = touchkit_disconnect, |
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c index 226b6f90a907..2f3edc26cb50 100644 --- a/drivers/usb/input/usbkbd.c +++ b/drivers/usb/input/usbkbd.c | |||
@@ -345,7 +345,6 @@ static struct usb_device_id usb_kbd_id_table [] = { | |||
345 | MODULE_DEVICE_TABLE (usb, usb_kbd_id_table); | 345 | MODULE_DEVICE_TABLE (usb, usb_kbd_id_table); |
346 | 346 | ||
347 | static struct usb_driver usb_kbd_driver = { | 347 | static struct usb_driver usb_kbd_driver = { |
348 | .owner = THIS_MODULE, | ||
349 | .name = "usbkbd", | 348 | .name = "usbkbd", |
350 | .probe = usb_kbd_probe, | 349 | .probe = usb_kbd_probe, |
351 | .disconnect = usb_kbd_disconnect, | 350 | .disconnect = usb_kbd_disconnect, |
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c index 230f6b1b314a..af526135d210 100644 --- a/drivers/usb/input/usbmouse.c +++ b/drivers/usb/input/usbmouse.c | |||
@@ -226,7 +226,6 @@ static struct usb_device_id usb_mouse_id_table [] = { | |||
226 | MODULE_DEVICE_TABLE (usb, usb_mouse_id_table); | 226 | MODULE_DEVICE_TABLE (usb, usb_mouse_id_table); |
227 | 227 | ||
228 | static struct usb_driver usb_mouse_driver = { | 228 | static struct usb_driver usb_mouse_driver = { |
229 | .owner = THIS_MODULE, | ||
230 | .name = "usbmouse", | 229 | .name = "usbmouse", |
231 | .probe = usb_mouse_probe, | 230 | .probe = usb_mouse_probe, |
232 | .disconnect = usb_mouse_disconnect, | 231 | .disconnect = usb_mouse_disconnect, |
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index aea1cfae34cc..48df4cfd5a42 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c | |||
@@ -854,7 +854,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
854 | 854 | ||
855 | input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); | 855 | input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); |
856 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS); | 856 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS); |
857 | input_set_abs_params(input_dev, ABS_X, 0, wacom->features->y_max, 4, 0); | 857 | input_set_abs_params(input_dev, ABS_X, 0, wacom->features->x_max, 4, 0); |
858 | input_set_abs_params(input_dev, ABS_Y, 0, wacom->features->y_max, 4, 0); | 858 | input_set_abs_params(input_dev, ABS_Y, 0, wacom->features->y_max, 4, 0); |
859 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0); | 859 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0); |
860 | 860 | ||
@@ -945,7 +945,6 @@ static void wacom_disconnect(struct usb_interface *intf) | |||
945 | } | 945 | } |
946 | 946 | ||
947 | static struct usb_driver wacom_driver = { | 947 | static struct usb_driver wacom_driver = { |
948 | .owner = THIS_MODULE, | ||
949 | .name = "wacom", | 948 | .name = "wacom", |
950 | .probe = wacom_probe, | 949 | .probe = wacom_probe, |
951 | .disconnect = wacom_disconnect, | 950 | .disconnect = wacom_disconnect, |
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index 43112f040b6d..e278489a80c6 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c | |||
@@ -70,7 +70,7 @@ | |||
70 | 70 | ||
71 | #define XPAD_PKT_LEN 32 | 71 | #define XPAD_PKT_LEN 32 |
72 | 72 | ||
73 | static struct xpad_device { | 73 | static const struct xpad_device { |
74 | u16 idVendor; | 74 | u16 idVendor; |
75 | u16 idProduct; | 75 | u16 idProduct; |
76 | char *name; | 76 | char *name; |
@@ -81,13 +81,13 @@ static struct xpad_device { | |||
81 | { 0x0000, 0x0000, "X-Box pad" } | 81 | { 0x0000, 0x0000, "X-Box pad" } |
82 | }; | 82 | }; |
83 | 83 | ||
84 | static signed short xpad_btn[] = { | 84 | static const signed short xpad_btn[] = { |
85 | BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, /* "analog" buttons */ | 85 | BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, /* "analog" buttons */ |
86 | BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ | 86 | BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ |
87 | -1 /* terminating entry */ | 87 | -1 /* terminating entry */ |
88 | }; | 88 | }; |
89 | 89 | ||
90 | static signed short xpad_abs[] = { | 90 | static const signed short xpad_abs[] = { |
91 | ABS_X, ABS_Y, /* left stick */ | 91 | ABS_X, ABS_Y, /* left stick */ |
92 | ABS_RX, ABS_RY, /* right stick */ | 92 | ABS_RX, ABS_RY, /* right stick */ |
93 | ABS_Z, ABS_RZ, /* triggers left/right */ | 93 | ABS_Z, ABS_RZ, /* triggers left/right */ |
@@ -316,7 +316,6 @@ static void xpad_disconnect(struct usb_interface *intf) | |||
316 | } | 316 | } |
317 | 317 | ||
318 | static struct usb_driver xpad_driver = { | 318 | static struct usb_driver xpad_driver = { |
319 | .owner = THIS_MODULE, | ||
320 | .name = "xpad", | 319 | .name = "xpad", |
321 | .probe = xpad_probe, | 320 | .probe = xpad_probe, |
322 | .disconnect = xpad_disconnect, | 321 | .disconnect = xpad_disconnect, |
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c index f526aebea502..1bfc105ad4d6 100644 --- a/drivers/usb/input/yealink.c +++ b/drivers/usb/input/yealink.c | |||
@@ -987,7 +987,6 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
987 | } | 987 | } |
988 | 988 | ||
989 | static struct usb_driver yealink_driver = { | 989 | static struct usb_driver yealink_driver = { |
990 | .owner = THIS_MODULE, | ||
991 | .name = "yealink", | 990 | .name = "yealink", |
992 | .probe = usb_probe, | 991 | .probe = usb_probe, |
993 | .disconnect = usb_disconnect, | 992 | .disconnect = usb_disconnect, |
diff --git a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c index 27b23c55bbc7..18d8eaf408d5 100644 --- a/drivers/usb/media/dabusb.c +++ b/drivers/usb/media/dabusb.c | |||
@@ -812,7 +812,6 @@ static struct usb_device_id dabusb_ids [] = { | |||
812 | MODULE_DEVICE_TABLE (usb, dabusb_ids); | 812 | MODULE_DEVICE_TABLE (usb, dabusb_ids); |
813 | 813 | ||
814 | static struct usb_driver dabusb_driver = { | 814 | static struct usb_driver dabusb_driver = { |
815 | .owner = THIS_MODULE, | ||
816 | .name = "dabusb", | 815 | .name = "dabusb", |
817 | .probe = dabusb_probe, | 816 | .probe = dabusb_probe, |
818 | .disconnect = dabusb_disconnect, | 817 | .disconnect = dabusb_disconnect, |
diff --git a/drivers/usb/media/dsbr100.c b/drivers/usb/media/dsbr100.c index 7503f5b96f59..6a5700e9d428 100644 --- a/drivers/usb/media/dsbr100.c +++ b/drivers/usb/media/dsbr100.c | |||
@@ -150,7 +150,6 @@ MODULE_DEVICE_TABLE (usb, usb_dsbr100_device_table); | |||
150 | 150 | ||
151 | /* USB subsystem interface */ | 151 | /* USB subsystem interface */ |
152 | static struct usb_driver usb_dsbr100_driver = { | 152 | static struct usb_driver usb_dsbr100_driver = { |
153 | .owner = THIS_MODULE, | ||
154 | .name = "dsbr100", | 153 | .name = "dsbr100", |
155 | .probe = usb_dsbr100_probe, | 154 | .probe = usb_dsbr100_probe, |
156 | .disconnect = usb_dsbr100_disconnect, | 155 | .disconnect = usb_dsbr100_disconnect, |
diff --git a/drivers/usb/media/ibmcam.c b/drivers/usb/media/ibmcam.c index ba41fc7b95c2..a42c22294124 100644 --- a/drivers/usb/media/ibmcam.c +++ b/drivers/usb/media/ibmcam.c | |||
@@ -3457,7 +3457,7 @@ static void ibmcam_model3_setup_after_video_if(struct uvd *uvd) | |||
3457 | if(init_model3_input) { | 3457 | if(init_model3_input) { |
3458 | if (debug > 0) | 3458 | if (debug > 0) |
3459 | info("Setting input to RCA."); | 3459 | info("Setting input to RCA."); |
3460 | for (i=0; i < (sizeof(initData)/sizeof(initData[0])); i++) { | 3460 | for (i=0; i < ARRAY_SIZE(initData); i++) { |
3461 | ibmcam_veio(uvd, initData[i].req, initData[i].value, initData[i].index); | 3461 | ibmcam_veio(uvd, initData[i].req, initData[i].value, initData[i].index); |
3462 | } | 3462 | } |
3463 | } | 3463 | } |
diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c index 9fe2c2710d13..e2ede583518f 100644 --- a/drivers/usb/media/konicawc.c +++ b/drivers/usb/media/konicawc.c | |||
@@ -77,14 +77,14 @@ static int saturation = MAX_SATURATION/2; | |||
77 | static int sharpness = MAX_SHARPNESS/2; | 77 | static int sharpness = MAX_SHARPNESS/2; |
78 | static int whitebal = 3*(MAX_WHITEBAL/4); | 78 | static int whitebal = 3*(MAX_WHITEBAL/4); |
79 | 79 | ||
80 | static int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 }; | 80 | static const int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 }; |
81 | 81 | ||
82 | /* These FPS speeds are from the windows config box. They are | 82 | /* These FPS speeds are from the windows config box. They are |
83 | * indexed on size (0-2) and speed (0-6). Divide by 3 to get the | 83 | * indexed on size (0-2) and speed (0-6). Divide by 3 to get the |
84 | * real fps. | 84 | * real fps. |
85 | */ | 85 | */ |
86 | 86 | ||
87 | static int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 }, | 87 | static const int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 }, |
88 | { 24, 40, 48, 60, 72, 80, 100 }, | 88 | { 24, 40, 48, 60, 72, 80, 100 }, |
89 | { 18, 30, 36, 45, 54, 60, 75 }, | 89 | { 18, 30, 36, 45, 54, 60, 75 }, |
90 | { 6, 10, 12, 15, 18, 21, 25 } }; | 90 | { 6, 10, 12, 15, 18, 21, 25 } }; |
@@ -95,7 +95,7 @@ struct cam_size { | |||
95 | u8 cmd; | 95 | u8 cmd; |
96 | }; | 96 | }; |
97 | 97 | ||
98 | static struct cam_size camera_sizes[] = { { 160, 120, 0x7 }, | 98 | static const struct cam_size camera_sizes[] = { { 160, 120, 0x7 }, |
99 | { 160, 136, 0xa }, | 99 | { 160, 136, 0xa }, |
100 | { 176, 144, 0x4 }, | 100 | { 176, 144, 0x4 }, |
101 | { 320, 240, 0x5 } }; | 101 | { 320, 240, 0x5 } }; |
diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c index 036c485d1d1e..3a0e8ce67ebe 100644 --- a/drivers/usb/media/ov511.c +++ b/drivers/usb/media/ov511.c | |||
@@ -211,7 +211,7 @@ static struct ov51x_decomp_ops *ov518_mmx_decomp_ops; | |||
211 | 211 | ||
212 | /* Number of times to retry a failed I2C transaction. Increase this if you | 212 | /* Number of times to retry a failed I2C transaction. Increase this if you |
213 | * are getting "Failed to read sensor ID..." */ | 213 | * are getting "Failed to read sensor ID..." */ |
214 | static int i2c_detect_tries = 5; | 214 | static const int i2c_detect_tries = 5; |
215 | 215 | ||
216 | /* MMX support is present in kernel and CPU. Checked upon decomp module load. */ | 216 | /* MMX support is present in kernel and CPU. Checked upon decomp module load. */ |
217 | #if defined(__i386__) || defined(__x86_64__) | 217 | #if defined(__i386__) || defined(__x86_64__) |
@@ -6008,7 +6008,6 @@ ov51x_disconnect(struct usb_interface *intf) | |||
6008 | } | 6008 | } |
6009 | 6009 | ||
6010 | static struct usb_driver ov511_driver = { | 6010 | static struct usb_driver ov511_driver = { |
6011 | .owner = THIS_MODULE, | ||
6012 | .name = "ov511", | 6011 | .name = "ov511", |
6013 | .id_table = device_table, | 6012 | .id_table = device_table, |
6014 | .probe = ov51x_probe, | 6013 | .probe = ov51x_probe, |
diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c index 53099190952c..359c4b2df735 100644 --- a/drivers/usb/media/pwc/pwc-ctrl.c +++ b/drivers/usb/media/pwc/pwc-ctrl.c | |||
@@ -109,7 +109,7 @@ | |||
109 | #define PT_RESET_CONTROL_FORMATTER 0x02 | 109 | #define PT_RESET_CONTROL_FORMATTER 0x02 |
110 | #define PT_STATUS_FORMATTER 0x03 | 110 | #define PT_STATUS_FORMATTER 0x03 |
111 | 111 | ||
112 | static char *size2name[PSZ_MAX] = | 112 | static const char *size2name[PSZ_MAX] = |
113 | { | 113 | { |
114 | "subQCIF", | 114 | "subQCIF", |
115 | "QSIF", | 115 | "QSIF", |
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c index 5524fd70210b..09ca6128ac20 100644 --- a/drivers/usb/media/pwc/pwc-if.c +++ b/drivers/usb/media/pwc/pwc-if.c | |||
@@ -111,7 +111,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
111 | static void usb_pwc_disconnect(struct usb_interface *intf); | 111 | static void usb_pwc_disconnect(struct usb_interface *intf); |
112 | 112 | ||
113 | static struct usb_driver pwc_driver = { | 113 | static struct usb_driver pwc_driver = { |
114 | .owner = THIS_MODULE, | ||
115 | .name = "Philips webcam", /* name */ | 114 | .name = "Philips webcam", /* name */ |
116 | .id_table = pwc_device_table, | 115 | .id_table = pwc_device_table, |
117 | .probe = usb_pwc_probe, /* probe() */ | 116 | .probe = usb_pwc_probe, /* probe() */ |
diff --git a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c index f69e443cd1bc..b2ae29af5940 100644 --- a/drivers/usb/media/se401.c +++ b/drivers/usb/media/se401.c | |||
@@ -1401,7 +1401,6 @@ static void se401_disconnect(struct usb_interface *intf) | |||
1401 | } | 1401 | } |
1402 | 1402 | ||
1403 | static struct usb_driver se401_driver = { | 1403 | static struct usb_driver se401_driver = { |
1404 | .owner = THIS_MODULE, | ||
1405 | .name = "se401", | 1404 | .name = "se401", |
1406 | .id_table = device_table, | 1405 | .id_table = device_table, |
1407 | .probe = se401_probe, | 1406 | .probe = se401_probe, |
diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c index b2e66e3b90aa..8d1a1c357d5a 100644 --- a/drivers/usb/media/sn9c102_core.c +++ b/drivers/usb/media/sn9c102_core.c | |||
@@ -1316,7 +1316,7 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
1316 | struct v4l2_control ctrl; | 1316 | struct v4l2_control ctrl; |
1317 | struct v4l2_queryctrl *qctrl; | 1317 | struct v4l2_queryctrl *qctrl; |
1318 | struct v4l2_rect* rect; | 1318 | struct v4l2_rect* rect; |
1319 | u8 i = 0, n = 0; | 1319 | u8 i = 0; |
1320 | int err = 0; | 1320 | int err = 0; |
1321 | 1321 | ||
1322 | if (!(cam->state & DEV_INITIALIZED)) { | 1322 | if (!(cam->state & DEV_INITIALIZED)) { |
@@ -1352,7 +1352,7 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
1352 | return err; | 1352 | return err; |
1353 | 1353 | ||
1354 | if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) | 1354 | if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X) |
1355 | DBG(3, "Compressed video format is active, quality %d", | 1355 | DBG(3, "Compressed video format is active, quality %d", |
1356 | cam->compression.quality) | 1356 | cam->compression.quality) |
1357 | else | 1357 | else |
1358 | DBG(3, "Uncompressed video format is active") | 1358 | DBG(3, "Uncompressed video format is active") |
@@ -1364,9 +1364,8 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
1364 | } | 1364 | } |
1365 | 1365 | ||
1366 | if (s->set_ctrl) { | 1366 | if (s->set_ctrl) { |
1367 | n = sizeof(s->qctrl) / sizeof(s->qctrl[0]); | 1367 | for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) |
1368 | for (i = 0; i < n; i++) | 1368 | if (s->qctrl[i].id != 0 && |
1369 | if (s->qctrl[i].id != 0 && | ||
1370 | !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) { | 1369 | !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) { |
1371 | ctrl.id = s->qctrl[i].id; | 1370 | ctrl.id = s->qctrl[i].id; |
1372 | ctrl.value = qctrl[i].default_value; | 1371 | ctrl.value = qctrl[i].default_value; |
@@ -1388,7 +1387,7 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
1388 | init_waitqueue_head(&cam->wait_stream); | 1387 | init_waitqueue_head(&cam->wait_stream); |
1389 | cam->nreadbuffers = 2; | 1388 | cam->nreadbuffers = 2; |
1390 | memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl)); | 1389 | memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl)); |
1391 | memcpy(&(s->_rect), &(s->cropcap.defrect), | 1390 | memcpy(&(s->_rect), &(s->cropcap.defrect), |
1392 | sizeof(struct v4l2_rect)); | 1391 | sizeof(struct v4l2_rect)); |
1393 | cam->state |= DEV_INITIALIZED; | 1392 | cam->state |= DEV_INITIALIZED; |
1394 | } | 1393 | } |
@@ -1810,13 +1809,12 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
1810 | { | 1809 | { |
1811 | struct sn9c102_sensor* s = cam->sensor; | 1810 | struct sn9c102_sensor* s = cam->sensor; |
1812 | struct v4l2_queryctrl qc; | 1811 | struct v4l2_queryctrl qc; |
1813 | u8 i, n; | 1812 | u8 i; |
1814 | 1813 | ||
1815 | if (copy_from_user(&qc, arg, sizeof(qc))) | 1814 | if (copy_from_user(&qc, arg, sizeof(qc))) |
1816 | return -EFAULT; | 1815 | return -EFAULT; |
1817 | 1816 | ||
1818 | n = sizeof(s->qctrl) / sizeof(s->qctrl[0]); | 1817 | for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) |
1819 | for (i = 0; i < n; i++) | ||
1820 | if (qc.id && qc.id == s->qctrl[i].id) { | 1818 | if (qc.id && qc.id == s->qctrl[i].id) { |
1821 | memcpy(&qc, &(s->qctrl[i]), sizeof(qc)); | 1819 | memcpy(&qc, &(s->qctrl[i]), sizeof(qc)); |
1822 | if (copy_to_user(arg, &qc, sizeof(qc))) | 1820 | if (copy_to_user(arg, &qc, sizeof(qc))) |
@@ -1852,7 +1850,7 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
1852 | { | 1850 | { |
1853 | struct sn9c102_sensor* s = cam->sensor; | 1851 | struct sn9c102_sensor* s = cam->sensor; |
1854 | struct v4l2_control ctrl; | 1852 | struct v4l2_control ctrl; |
1855 | u8 i, n; | 1853 | u8 i; |
1856 | int err = 0; | 1854 | int err = 0; |
1857 | 1855 | ||
1858 | if (!s->set_ctrl) | 1856 | if (!s->set_ctrl) |
@@ -1861,8 +1859,7 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp, | |||
1861 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) | 1859 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) |
1862 | return -EFAULT; | 1860 | return -EFAULT; |
1863 | 1861 | ||
1864 | n = sizeof(s->qctrl) / sizeof(s->qctrl[0]); | 1862 | for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) |
1865 | for (i = 0; i < n; i++) | ||
1866 | if (ctrl.id == s->qctrl[i].id) { | 1863 | if (ctrl.id == s->qctrl[i].id) { |
1867 | if (ctrl.value < s->qctrl[i].minimum || | 1864 | if (ctrl.value < s->qctrl[i].minimum || |
1868 | ctrl.value > s->qctrl[i].maximum) | 1865 | ctrl.value > s->qctrl[i].maximum) |
@@ -2544,7 +2541,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2544 | unsigned int i, n; | 2541 | unsigned int i, n; |
2545 | int err = 0, r; | 2542 | int err = 0, r; |
2546 | 2543 | ||
2547 | n = sizeof(sn9c102_id_table)/sizeof(sn9c102_id_table[0]); | 2544 | n = ARRAY_SIZE(sn9c102_id_table); |
2548 | for (i = 0; i < n-1; i++) | 2545 | for (i = 0; i < n-1; i++) |
2549 | if (le16_to_cpu(udev->descriptor.idVendor) == | 2546 | if (le16_to_cpu(udev->descriptor.idVendor) == |
2550 | sn9c102_id_table[i].idVendor && | 2547 | sn9c102_id_table[i].idVendor && |
@@ -2711,7 +2708,6 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf) | |||
2711 | 2708 | ||
2712 | 2709 | ||
2713 | static struct usb_driver sn9c102_usb_driver = { | 2710 | static struct usb_driver sn9c102_usb_driver = { |
2714 | .owner = THIS_MODULE, | ||
2715 | .name = "sn9c102", | 2711 | .name = "sn9c102", |
2716 | .id_table = sn9c102_id_table, | 2712 | .id_table = sn9c102_id_table, |
2717 | .probe = sn9c102_usb_probe, | 2713 | .probe = sn9c102_usb_probe, |
diff --git a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c index 0fd0fa9fec21..774038b352cd 100644 --- a/drivers/usb/media/stv680.c +++ b/drivers/usb/media/stv680.c | |||
@@ -1477,7 +1477,6 @@ static void stv680_disconnect (struct usb_interface *intf) | |||
1477 | } | 1477 | } |
1478 | 1478 | ||
1479 | static struct usb_driver stv680_driver = { | 1479 | static struct usb_driver stv680_driver = { |
1480 | .owner = THIS_MODULE, | ||
1481 | .name = "stv680", | 1480 | .name = "stv680", |
1482 | .probe = stv680_probe, | 1481 | .probe = stv680_probe, |
1483 | .disconnect = stv680_disconnect, | 1482 | .disconnect = stv680_disconnect, |
diff --git a/drivers/usb/media/stv680.h b/drivers/usb/media/stv680.h index 445940612603..b0551cdb280b 100644 --- a/drivers/usb/media/stv680.h +++ b/drivers/usb/media/stv680.h | |||
@@ -151,7 +151,7 @@ struct usb_stv { | |||
151 | }; | 151 | }; |
152 | 152 | ||
153 | 153 | ||
154 | static unsigned char red[256] = { | 154 | static const unsigned char red[256] = { |
155 | 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, | 155 | 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, |
156 | 18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42, | 156 | 18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42, |
157 | 44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69, | 157 | 44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69, |
@@ -176,7 +176,7 @@ static unsigned char red[256] = { | |||
176 | 220, 220, 221, 221 | 176 | 220, 220, 221, 221 |
177 | }; | 177 | }; |
178 | 178 | ||
179 | static unsigned char green[256] = { | 179 | static const unsigned char green[256] = { |
180 | 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, | 180 | 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, |
181 | 21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47, | 181 | 21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47, |
182 | 50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77, | 182 | 50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77, |
@@ -201,7 +201,7 @@ static unsigned char green[256] = { | |||
201 | 245, 245, 246, 246 | 201 | 245, 245, 246, 246 |
202 | }; | 202 | }; |
203 | 203 | ||
204 | static unsigned char blue[256] = { | 204 | static const unsigned char blue[256] = { |
205 | 0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, | 205 | 0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, |
206 | 23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51, | 206 | 23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51, |
207 | 55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84, | 207 | 55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84, |
diff --git a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c index 24efb21969c6..4bd113325ef9 100644 --- a/drivers/usb/media/usbvideo.c +++ b/drivers/usb/media/usbvideo.c | |||
@@ -725,7 +725,7 @@ int usbvideo_register( | |||
725 | /* Allocate user_data separately because of kmalloc's limits */ | 725 | /* Allocate user_data separately because of kmalloc's limits */ |
726 | if (num_extra > 0) { | 726 | if (num_extra > 0) { |
727 | up->user_size = num_cams * num_extra; | 727 | up->user_size = num_cams * num_extra; |
728 | up->user_data = (char *) kmalloc(up->user_size, GFP_KERNEL); | 728 | up->user_data = kmalloc(up->user_size, GFP_KERNEL); |
729 | if (up->user_data == NULL) { | 729 | if (up->user_data == NULL) { |
730 | err("%s: Failed to allocate user_data (%d. bytes)", | 730 | err("%s: Failed to allocate user_data (%d. bytes)", |
731 | __FUNCTION__, up->user_size); | 731 | __FUNCTION__, up->user_size); |
@@ -955,7 +955,7 @@ static struct file_operations usbvideo_fops = { | |||
955 | .ioctl = usbvideo_v4l_ioctl, | 955 | .ioctl = usbvideo_v4l_ioctl, |
956 | .llseek = no_llseek, | 956 | .llseek = no_llseek, |
957 | }; | 957 | }; |
958 | static struct video_device usbvideo_template = { | 958 | static const struct video_device usbvideo_template = { |
959 | .owner = THIS_MODULE, | 959 | .owner = THIS_MODULE, |
960 | .type = VID_TYPE_CAPTURE, | 960 | .type = VID_TYPE_CAPTURE, |
961 | .hardware = VID_HARDWARE_CPIA, | 961 | .hardware = VID_HARDWARE_CPIA, |
diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c index 0bc0b1247a6b..1c73155c8d77 100644 --- a/drivers/usb/media/vicam.c +++ b/drivers/usb/media/vicam.c | |||
@@ -1257,7 +1257,6 @@ static struct usb_device_id vicam_table[] = { | |||
1257 | MODULE_DEVICE_TABLE(usb, vicam_table); | 1257 | MODULE_DEVICE_TABLE(usb, vicam_table); |
1258 | 1258 | ||
1259 | static struct usb_driver vicam_driver = { | 1259 | static struct usb_driver vicam_driver = { |
1260 | .owner = THIS_MODULE, | ||
1261 | .name = "vicam", | 1260 | .name = "vicam", |
1262 | .probe = vicam_probe, | 1261 | .probe = vicam_probe, |
1263 | .disconnect = vicam_disconnect, | 1262 | .disconnect = vicam_disconnect, |
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c index 67612c81cb9f..04d69339c054 100644 --- a/drivers/usb/media/w9968cf.c +++ b/drivers/usb/media/w9968cf.c | |||
@@ -2958,7 +2958,7 @@ static int w9968cf_v4l_ioctl(struct inode* inode, struct file* filp, | |||
2958 | }; | 2958 | }; |
2959 | 2959 | ||
2960 | #define V4L1_IOCTL(cmd) \ | 2960 | #define V4L1_IOCTL(cmd) \ |
2961 | ((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \ | 2961 | ((_IOC_NR((cmd)) < ARRAY_SIZE(v4l1_ioctls)) ? \ |
2962 | v4l1_ioctls[_IOC_NR((cmd))] : "?") | 2962 | v4l1_ioctls[_IOC_NR((cmd))] : "?") |
2963 | 2963 | ||
2964 | cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); | 2964 | cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp)); |
@@ -3554,7 +3554,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3554 | 3554 | ||
3555 | 3555 | ||
3556 | /* Allocate 2 bytes of memory for camera control USB transfers */ | 3556 | /* Allocate 2 bytes of memory for camera control USB transfers */ |
3557 | if (!(cam->control_buffer = (u16*)kmalloc(2, GFP_KERNEL))) { | 3557 | if (!(cam->control_buffer = kmalloc(2, GFP_KERNEL))) { |
3558 | DBG(1,"Couldn't allocate memory for camera control transfers") | 3558 | DBG(1,"Couldn't allocate memory for camera control transfers") |
3559 | err = -ENOMEM; | 3559 | err = -ENOMEM; |
3560 | goto fail; | 3560 | goto fail; |
@@ -3562,7 +3562,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3562 | memset(cam->control_buffer, 0, 2); | 3562 | memset(cam->control_buffer, 0, 2); |
3563 | 3563 | ||
3564 | /* Allocate 8 bytes of memory for USB data transfers to the FSB */ | 3564 | /* Allocate 8 bytes of memory for USB data transfers to the FSB */ |
3565 | if (!(cam->data_buffer = (u16*)kmalloc(8, GFP_KERNEL))) { | 3565 | if (!(cam->data_buffer = kmalloc(8, GFP_KERNEL))) { |
3566 | DBG(1, "Couldn't allocate memory for data " | 3566 | DBG(1, "Couldn't allocate memory for data " |
3567 | "transfers to the FSB") | 3567 | "transfers to the FSB") |
3568 | err = -ENOMEM; | 3568 | err = -ENOMEM; |
@@ -3668,7 +3668,6 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf) | |||
3668 | 3668 | ||
3669 | 3669 | ||
3670 | static struct usb_driver w9968cf_usb_driver = { | 3670 | static struct usb_driver w9968cf_usb_driver = { |
3671 | .owner = THIS_MODULE, | ||
3672 | .name = "w9968cf", | 3671 | .name = "w9968cf", |
3673 | .id_table = winbond_id_table, | 3672 | .id_table = winbond_id_table, |
3674 | .probe = w9968cf_usb_probe, | 3673 | .probe = w9968cf_usb_probe, |
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index b293db3c28c3..449b2501acf3 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c | |||
@@ -767,7 +767,7 @@ static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned | |||
767 | memset (bep, 0, sizeof (auerbuf_t)); | 767 | memset (bep, 0, sizeof (auerbuf_t)); |
768 | bep->list = bcp; | 768 | bep->list = bcp; |
769 | INIT_LIST_HEAD (&bep->buff_list); | 769 | INIT_LIST_HEAD (&bep->buff_list); |
770 | bep->bufp = (char *) kmalloc (bufsize, GFP_KERNEL); | 770 | bep->bufp = kmalloc (bufsize, GFP_KERNEL); |
771 | if (!bep->bufp) | 771 | if (!bep->bufp) |
772 | goto bl_fail; | 772 | goto bl_fail; |
773 | bep->dr = (struct usb_ctrlrequest *) kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL); | 773 | bep->dr = (struct usb_ctrlrequest *) kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL); |
@@ -1123,7 +1123,7 @@ static int auerswald_int_open (pauerswald_t cp) | |||
1123 | } | 1123 | } |
1124 | } | 1124 | } |
1125 | if (!cp->intbufp) { | 1125 | if (!cp->intbufp) { |
1126 | cp->intbufp = (char *) kmalloc (irqsize, GFP_KERNEL); | 1126 | cp->intbufp = kmalloc (irqsize, GFP_KERNEL); |
1127 | if (!cp->intbufp) { | 1127 | if (!cp->intbufp) { |
1128 | ret = -ENOMEM; | 1128 | ret = -ENOMEM; |
1129 | goto intoend; | 1129 | goto intoend; |
@@ -2103,7 +2103,6 @@ MODULE_DEVICE_TABLE (usb, auerswald_ids); | |||
2103 | 2103 | ||
2104 | /* Standard usb driver struct */ | 2104 | /* Standard usb driver struct */ |
2105 | static struct usb_driver auerswald_driver = { | 2105 | static struct usb_driver auerswald_driver = { |
2106 | .owner = THIS_MODULE, | ||
2107 | .name = "auerswald", | 2106 | .name = "auerswald", |
2108 | .probe = auerswald_probe, | 2107 | .probe = auerswald_probe, |
2109 | .disconnect = auerswald_disconnect, | 2108 | .disconnect = auerswald_disconnect, |
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c index b33044d56a1e..6671317b495f 100644 --- a/drivers/usb/misc/cytherm.c +++ b/drivers/usb/misc/cytherm.c | |||
@@ -50,7 +50,6 @@ static void cytherm_disconnect(struct usb_interface *interface); | |||
50 | 50 | ||
51 | /* usb specific object needed to register this driver with the usb subsystem */ | 51 | /* usb specific object needed to register this driver with the usb subsystem */ |
52 | static struct usb_driver cytherm_driver = { | 52 | static struct usb_driver cytherm_driver = { |
53 | .owner = THIS_MODULE, | ||
54 | .name = "cytherm", | 53 | .name = "cytherm", |
55 | .probe = cytherm_probe, | 54 | .probe = cytherm_probe, |
56 | .disconnect = cytherm_disconnect, | 55 | .disconnect = cytherm_disconnect, |
diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c index c8155209bf4b..3824df33094e 100644 --- a/drivers/usb/misc/emi26.c +++ b/drivers/usb/misc/emi26.c | |||
@@ -227,7 +227,6 @@ static void emi26_disconnect(struct usb_interface *intf) | |||
227 | } | 227 | } |
228 | 228 | ||
229 | static struct usb_driver emi26_driver = { | 229 | static struct usb_driver emi26_driver = { |
230 | .owner = THIS_MODULE, | ||
231 | .name = "emi26 - firmware loader", | 230 | .name = "emi26 - firmware loader", |
232 | .probe = emi26_probe, | 231 | .probe = emi26_probe, |
233 | .disconnect = emi26_disconnect, | 232 | .disconnect = emi26_disconnect, |
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index 189986af2ac7..52fea2e08db8 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c | |||
@@ -266,7 +266,6 @@ static void emi62_disconnect(struct usb_interface *intf) | |||
266 | } | 266 | } |
267 | 267 | ||
268 | static struct usb_driver emi62_driver = { | 268 | static struct usb_driver emi62_driver = { |
269 | .owner = THIS_MODULE, | ||
270 | .name = "emi62 - firmware loader", | 269 | .name = "emi62 - firmware loader", |
271 | .probe = emi62_probe, | 270 | .probe = emi62_probe, |
272 | .disconnect = emi62_disconnect, | 271 | .disconnect = emi62_disconnect, |
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index 1dc3e0f73014..d8cde1017985 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c | |||
@@ -114,7 +114,6 @@ static struct usb_class_driver idmouse_class = { | |||
114 | 114 | ||
115 | /* usb specific object needed to register this driver with the usb subsystem */ | 115 | /* usb specific object needed to register this driver with the usb subsystem */ |
116 | static struct usb_driver idmouse_driver = { | 116 | static struct usb_driver idmouse_driver = { |
117 | .owner = THIS_MODULE, | ||
118 | .name = DRIVER_SHORT, | 117 | .name = DRIVER_SHORT, |
119 | .probe = idmouse_probe, | 118 | .probe = idmouse_probe, |
120 | .disconnect = idmouse_disconnect, | 119 | .disconnect = idmouse_disconnect, |
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 7e93ac96490f..981d8a5fbfd9 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c | |||
@@ -763,7 +763,6 @@ static void ld_usb_disconnect(struct usb_interface *intf) | |||
763 | 763 | ||
764 | /* usb specific object needed to register this driver with the usb subsystem */ | 764 | /* usb specific object needed to register this driver with the usb subsystem */ |
765 | static struct usb_driver ld_usb_driver = { | 765 | static struct usb_driver ld_usb_driver = { |
766 | .owner = THIS_MODULE, | ||
767 | .name = "ldusb", | 766 | .name = "ldusb", |
768 | .probe = ld_usb_probe, | 767 | .probe = ld_usb_probe, |
769 | .disconnect = ld_usb_disconnect, | 768 | .disconnect = ld_usb_disconnect, |
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 2703e205bc8f..1336745b8f55 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c | |||
@@ -282,7 +282,6 @@ static struct usb_class_driver tower_class = { | |||
282 | 282 | ||
283 | /* usb specific object needed to register this driver with the usb subsystem */ | 283 | /* usb specific object needed to register this driver with the usb subsystem */ |
284 | static struct usb_driver tower_driver = { | 284 | static struct usb_driver tower_driver = { |
285 | .owner = THIS_MODULE, | ||
286 | .name = "legousbtower", | 285 | .name = "legousbtower", |
287 | .probe = tower_probe, | 286 | .probe = tower_probe, |
288 | .disconnect = tower_disconnect, | 287 | .disconnect = tower_disconnect, |
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c index 067a81486921..605a3c87e05c 100644 --- a/drivers/usb/misc/phidgetkit.c +++ b/drivers/usb/misc/phidgetkit.c | |||
@@ -555,7 +555,6 @@ static void interfacekit_disconnect(struct usb_interface *interface) | |||
555 | } | 555 | } |
556 | 556 | ||
557 | static struct usb_driver interfacekit_driver = { | 557 | static struct usb_driver interfacekit_driver = { |
558 | .owner = THIS_MODULE, | ||
559 | .name = "phidgetkit", | 558 | .name = "phidgetkit", |
560 | .probe = interfacekit_probe, | 559 | .probe = interfacekit_probe, |
561 | .disconnect = interfacekit_disconnect, | 560 | .disconnect = interfacekit_disconnect, |
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c index a30d4a6ee824..b3418d2bcc69 100644 --- a/drivers/usb/misc/phidgetservo.c +++ b/drivers/usb/misc/phidgetservo.c | |||
@@ -306,7 +306,6 @@ servo_disconnect(struct usb_interface *interface) | |||
306 | } | 306 | } |
307 | 307 | ||
308 | static struct usb_driver servo_driver = { | 308 | static struct usb_driver servo_driver = { |
309 | .owner = THIS_MODULE, | ||
310 | .name = "phidgetservo", | 309 | .name = "phidgetservo", |
311 | .probe = servo_probe, | 310 | .probe = servo_probe, |
312 | .disconnect = servo_disconnect, | 311 | .disconnect = servo_disconnect, |
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 9590dbac5d9a..384fa3769805 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c | |||
@@ -465,14 +465,14 @@ static int probe_rio(struct usb_interface *intf, | |||
465 | 465 | ||
466 | rio->rio_dev = dev; | 466 | rio->rio_dev = dev; |
467 | 467 | ||
468 | if (!(rio->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) { | 468 | if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) { |
469 | err("probe_rio: Not enough memory for the output buffer"); | 469 | err("probe_rio: Not enough memory for the output buffer"); |
470 | usb_deregister_dev(intf, &usb_rio_class); | 470 | usb_deregister_dev(intf, &usb_rio_class); |
471 | return -ENOMEM; | 471 | return -ENOMEM; |
472 | } | 472 | } |
473 | dbg("probe_rio: obuf address:%p", rio->obuf); | 473 | dbg("probe_rio: obuf address:%p", rio->obuf); |
474 | 474 | ||
475 | if (!(rio->ibuf = (char *) kmalloc(IBUF_SIZE, GFP_KERNEL))) { | 475 | if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) { |
476 | err("probe_rio: Not enough memory for the input buffer"); | 476 | err("probe_rio: Not enough memory for the input buffer"); |
477 | usb_deregister_dev(intf, &usb_rio_class); | 477 | usb_deregister_dev(intf, &usb_rio_class); |
478 | kfree(rio->obuf); | 478 | kfree(rio->obuf); |
@@ -522,7 +522,6 @@ static struct usb_device_id rio_table [] = { | |||
522 | MODULE_DEVICE_TABLE (usb, rio_table); | 522 | MODULE_DEVICE_TABLE (usb, rio_table); |
523 | 523 | ||
524 | static struct usb_driver rio_driver = { | 524 | static struct usb_driver rio_driver = { |
525 | .owner = THIS_MODULE, | ||
526 | .name = "rio500", | 525 | .name = "rio500", |
527 | .probe = probe_rio, | 526 | .probe = probe_rio, |
528 | .disconnect = disconnect_rio, | 527 | .disconnect = disconnect_rio, |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 41ef2b606751..3260d595441f 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
@@ -863,9 +863,6 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, | |||
863 | 863 | ||
864 | switch (length) { | 864 | switch (length) { |
865 | 865 | ||
866 | case 0: | ||
867 | return ret; | ||
868 | |||
869 | case 1: | 866 | case 1: |
870 | if (userbuffer) { | 867 | if (userbuffer) { |
871 | if (get_user(swap8, (u8 __user *)userbuffer)) | 868 | if (get_user(swap8, (u8 __user *)userbuffer)) |
@@ -1221,9 +1218,6 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, | |||
1221 | 1218 | ||
1222 | switch (length) { | 1219 | switch (length) { |
1223 | 1220 | ||
1224 | case 0: | ||
1225 | return ret; | ||
1226 | |||
1227 | case 1: | 1221 | case 1: |
1228 | 1222 | ||
1229 | ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, | 1223 | ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, |
@@ -2443,8 +2437,8 @@ sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init) | |||
2443 | u8 *tempbuf; | 2437 | u8 *tempbuf; |
2444 | u16 *tempbufb; | 2438 | u16 *tempbufb; |
2445 | size_t written; | 2439 | size_t written; |
2446 | static char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer."; | 2440 | static const char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer."; |
2447 | static char bootlogo[] = "(o_ //\\ V_/_"; | 2441 | static const char bootlogo[] = "(o_ //\\ V_/_"; |
2448 | 2442 | ||
2449 | /* sisusb->lock is down */ | 2443 | /* sisusb->lock is down */ |
2450 | 2444 | ||
@@ -3489,7 +3483,6 @@ static struct usb_device_id sisusb_table [] = { | |||
3489 | MODULE_DEVICE_TABLE (usb, sisusb_table); | 3483 | MODULE_DEVICE_TABLE (usb, sisusb_table); |
3490 | 3484 | ||
3491 | static struct usb_driver sisusb_driver = { | 3485 | static struct usb_driver sisusb_driver = { |
3492 | .owner = THIS_MODULE, | ||
3493 | .name = "sisusb", | 3486 | .name = "sisusb", |
3494 | .probe = sisusb_probe, | 3487 | .probe = sisusb_probe, |
3495 | .disconnect = sisusb_disconnect, | 3488 | .disconnect = sisusb_disconnect, |
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 85f3725334b0..cc3dae3f34e0 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c | |||
@@ -371,7 +371,6 @@ static void lcd_disconnect(struct usb_interface *interface) | |||
371 | } | 371 | } |
372 | 372 | ||
373 | static struct usb_driver lcd_driver = { | 373 | static struct usb_driver lcd_driver = { |
374 | .owner = THIS_MODULE, | ||
375 | .name = "usblcd", | 374 | .name = "usblcd", |
376 | .probe = lcd_probe, | 375 | .probe = lcd_probe, |
377 | .disconnect = lcd_disconnect, | 376 | .disconnect = lcd_disconnect, |
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c index 3c93921cb6b3..877b081a3a6e 100644 --- a/drivers/usb/misc/usbled.c +++ b/drivers/usb/misc/usbled.c | |||
@@ -148,7 +148,6 @@ static void led_disconnect(struct usb_interface *interface) | |||
148 | } | 148 | } |
149 | 149 | ||
150 | static struct usb_driver led_driver = { | 150 | static struct usb_driver led_driver = { |
151 | .owner = THIS_MODULE, | ||
152 | .name = "usbled", | 151 | .name = "usbled", |
153 | .probe = led_probe, | 152 | .probe = led_probe, |
154 | .disconnect = led_disconnect, | 153 | .disconnect = led_disconnect, |
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 605a2afe34ed..84fa1728f052 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c | |||
@@ -2134,7 +2134,6 @@ static struct usb_device_id id_table [] = { | |||
2134 | MODULE_DEVICE_TABLE (usb, id_table); | 2134 | MODULE_DEVICE_TABLE (usb, id_table); |
2135 | 2135 | ||
2136 | static struct usb_driver usbtest_driver = { | 2136 | static struct usb_driver usbtest_driver = { |
2137 | .owner = THIS_MODULE, | ||
2138 | .name = "usbtest", | 2137 | .name = "usbtest", |
2139 | .id_table = id_table, | 2138 | .id_table = id_table, |
2140 | .probe = usbtest_probe, | 2139 | .probe = usbtest_probe, |
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 1cabe7ed91f5..4081990b7d1a 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c | |||
@@ -780,7 +780,6 @@ MODULE_DEVICE_TABLE (usb, uss720_table); | |||
780 | 780 | ||
781 | 781 | ||
782 | static struct usb_driver uss720_driver = { | 782 | static struct usb_driver uss720_driver = { |
783 | .owner = THIS_MODULE, | ||
784 | .name = "uss720", | 783 | .name = "uss720", |
785 | .probe = uss720_probe, | 784 | .probe = uss720_probe, |
786 | .disconnect = uss720_disconnect, | 785 | .disconnect = uss720_disconnect, |
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 17d0190ef64e..611612146ae9 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c | |||
@@ -97,19 +97,12 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, | |||
97 | if (len >= DATA_MAX) | 97 | if (len >= DATA_MAX) |
98 | len = DATA_MAX; | 98 | len = DATA_MAX; |
99 | 99 | ||
100 | /* | 100 | if (usb_pipein(pipe)) { |
101 | * Bulk is easy to shortcut reliably. | 101 | if (ev_type == 'S') |
102 | * XXX Other pipe types need consideration. Currently, we overdo it | 102 | return '<'; |
103 | * and collect garbage for them: better more than less. | 103 | } else { |
104 | */ | 104 | if (ev_type == 'C') |
105 | if (usb_pipebulk(pipe) || usb_pipecontrol(pipe)) { | 105 | return '>'; |
106 | if (usb_pipein(pipe)) { | ||
107 | if (ev_type == 'S') | ||
108 | return '<'; | ||
109 | } else { | ||
110 | if (ev_type == 'C') | ||
111 | return '>'; | ||
112 | } | ||
113 | } | 106 | } |
114 | 107 | ||
115 | /* | 108 | /* |
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c index 542120ef1fd2..541181695040 100644 --- a/drivers/usb/net/asix.c +++ b/drivers/usb/net/asix.c | |||
@@ -912,13 +912,16 @@ static const struct usb_device_id products [] = { | |||
912 | // ASIX AX88772 10/100 | 912 | // ASIX AX88772 10/100 |
913 | USB_DEVICE (0x0b95, 0x7720), | 913 | USB_DEVICE (0x0b95, 0x7720), |
914 | .driver_info = (unsigned long) &ax88772_info, | 914 | .driver_info = (unsigned long) &ax88772_info, |
915 | }, { | ||
916 | // Linksys USB200M Rev 2 | ||
917 | USB_DEVICE (0x13b1, 0x0018), | ||
918 | .driver_info = (unsigned long) &ax88772_info, | ||
915 | }, | 919 | }, |
916 | { }, // END | 920 | { }, // END |
917 | }; | 921 | }; |
918 | MODULE_DEVICE_TABLE(usb, products); | 922 | MODULE_DEVICE_TABLE(usb, products); |
919 | 923 | ||
920 | static struct usb_driver asix_driver = { | 924 | static struct usb_driver asix_driver = { |
921 | .owner = THIS_MODULE, | ||
922 | .name = "asix", | 925 | .name = "asix", |
923 | .id_table = products, | 926 | .id_table = products, |
924 | .probe = usbnet_probe, | 927 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c index 37ef365a2472..be5f5e142dd0 100644 --- a/drivers/usb/net/catc.c +++ b/drivers/usb/net/catc.c | |||
@@ -934,7 +934,6 @@ static struct usb_device_id catc_id_table [] = { | |||
934 | MODULE_DEVICE_TABLE(usb, catc_id_table); | 934 | MODULE_DEVICE_TABLE(usb, catc_id_table); |
935 | 935 | ||
936 | static struct usb_driver catc_driver = { | 936 | static struct usb_driver catc_driver = { |
937 | .owner = THIS_MODULE, | ||
938 | .name = driver_name, | 937 | .name = driver_name, |
939 | .probe = catc_probe, | 938 | .probe = catc_probe, |
940 | .disconnect = catc_disconnect, | 939 | .disconnect = catc_disconnect, |
diff --git a/drivers/usb/net/cdc_ether.c b/drivers/usb/net/cdc_ether.c index c008c981862b..63f1f3ba8e0b 100644 --- a/drivers/usb/net/cdc_ether.c +++ b/drivers/usb/net/cdc_ether.c | |||
@@ -476,7 +476,6 @@ static const struct usb_device_id products [] = { | |||
476 | MODULE_DEVICE_TABLE(usb, products); | 476 | MODULE_DEVICE_TABLE(usb, products); |
477 | 477 | ||
478 | static struct usb_driver cdc_driver = { | 478 | static struct usb_driver cdc_driver = { |
479 | .owner = THIS_MODULE, | ||
480 | .name = "cdc_ether", | 479 | .name = "cdc_ether", |
481 | .id_table = products, | 480 | .id_table = products, |
482 | .probe = usbnet_probe, | 481 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/cdc_subset.c b/drivers/usb/net/cdc_subset.c index f05cfb83c82d..ec801e8bb1bb 100644 --- a/drivers/usb/net/cdc_subset.c +++ b/drivers/usb/net/cdc_subset.c | |||
@@ -306,7 +306,6 @@ MODULE_DEVICE_TABLE(usb, products); | |||
306 | /*-------------------------------------------------------------------------*/ | 306 | /*-------------------------------------------------------------------------*/ |
307 | 307 | ||
308 | static struct usb_driver cdc_subset_driver = { | 308 | static struct usb_driver cdc_subset_driver = { |
309 | .owner = THIS_MODULE, | ||
310 | .name = "cdc_subset", | 309 | .name = "cdc_subset", |
311 | .probe = usbnet_probe, | 310 | .probe = usbnet_probe, |
312 | .suspend = usbnet_suspend, | 311 | .suspend = usbnet_suspend, |
diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c index 2455e9a85674..faf1e86be687 100644 --- a/drivers/usb/net/gl620a.c +++ b/drivers/usb/net/gl620a.c | |||
@@ -377,7 +377,6 @@ static const struct usb_device_id products [] = { | |||
377 | MODULE_DEVICE_TABLE(usb, products); | 377 | MODULE_DEVICE_TABLE(usb, products); |
378 | 378 | ||
379 | static struct usb_driver gl620a_driver = { | 379 | static struct usb_driver gl620a_driver = { |
380 | .owner = THIS_MODULE, | ||
381 | .name = "gl620a", | 380 | .name = "gl620a", |
382 | .id_table = products, | 381 | .id_table = products, |
383 | .probe = usbnet_probe, | 382 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index b5776518020f..def3bb8e2290 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c | |||
@@ -175,7 +175,6 @@ MODULE_DEVICE_TABLE (usb, usb_klsi_table); | |||
175 | * kaweth_driver | 175 | * kaweth_driver |
176 | ****************************************************************/ | 176 | ****************************************************************/ |
177 | static struct usb_driver kaweth_driver = { | 177 | static struct usb_driver kaweth_driver = { |
178 | .owner = THIS_MODULE, | ||
179 | .name = driver_name, | 178 | .name = driver_name, |
180 | .probe = kaweth_probe, | 179 | .probe = kaweth_probe, |
181 | .disconnect = kaweth_disconnect, | 180 | .disconnect = kaweth_disconnect, |
diff --git a/drivers/usb/net/net1080.c b/drivers/usb/net/net1080.c index b3799b1a2b0d..78e6a43b1087 100644 --- a/drivers/usb/net/net1080.c +++ b/drivers/usb/net/net1080.c | |||
@@ -593,7 +593,6 @@ static const struct usb_device_id products [] = { | |||
593 | MODULE_DEVICE_TABLE(usb, products); | 593 | MODULE_DEVICE_TABLE(usb, products); |
594 | 594 | ||
595 | static struct usb_driver net1080_driver = { | 595 | static struct usb_driver net1080_driver = { |
596 | .owner = THIS_MODULE, | ||
597 | .name = "net1080", | 596 | .name = "net1080", |
598 | .id_table = products, | 597 | .id_table = products, |
599 | .probe = usbnet_probe, | 598 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 683e3df5d607..156a2f1cb39a 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c | |||
@@ -45,7 +45,7 @@ | |||
45 | /* | 45 | /* |
46 | * Version Information | 46 | * Version Information |
47 | */ | 47 | */ |
48 | #define DRIVER_VERSION "v0.6.12 (2005/01/13)" | 48 | #define DRIVER_VERSION "v0.6.13 (2005/11/13)" |
49 | #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>" | 49 | #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>" |
50 | #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver" | 50 | #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver" |
51 | 51 | ||
@@ -57,12 +57,14 @@ static const char driver_name[] = "pegasus"; | |||
57 | 57 | ||
58 | static int loopback = 0; | 58 | static int loopback = 0; |
59 | static int mii_mode = 0; | 59 | static int mii_mode = 0; |
60 | static char *devid=NULL; | ||
60 | 61 | ||
61 | static struct usb_eth_dev usb_dev_id[] = { | 62 | static struct usb_eth_dev usb_dev_id[] = { |
62 | #define PEGASUS_DEV(pn, vid, pid, flags) \ | 63 | #define PEGASUS_DEV(pn, vid, pid, flags) \ |
63 | {.name = pn, .vendor = vid, .device = pid, .private = flags}, | 64 | {.name = pn, .vendor = vid, .device = pid, .private = flags}, |
64 | #include "pegasus.h" | 65 | #include "pegasus.h" |
65 | #undef PEGASUS_DEV | 66 | #undef PEGASUS_DEV |
67 | {NULL, 0, 0, 0}, | ||
66 | {NULL, 0, 0, 0} | 68 | {NULL, 0, 0, 0} |
67 | }; | 69 | }; |
68 | 70 | ||
@@ -71,6 +73,7 @@ static struct usb_device_id pegasus_ids[] = { | |||
71 | {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid}, | 73 | {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid}, |
72 | #include "pegasus.h" | 74 | #include "pegasus.h" |
73 | #undef PEGASUS_DEV | 75 | #undef PEGASUS_DEV |
76 | {}, | ||
74 | {} | 77 | {} |
75 | }; | 78 | }; |
76 | 79 | ||
@@ -79,8 +82,10 @@ MODULE_DESCRIPTION(DRIVER_DESC); | |||
79 | MODULE_LICENSE("GPL"); | 82 | MODULE_LICENSE("GPL"); |
80 | module_param(loopback, bool, 0); | 83 | module_param(loopback, bool, 0); |
81 | module_param(mii_mode, bool, 0); | 84 | module_param(mii_mode, bool, 0); |
85 | module_param(devid, charp, 0); | ||
82 | MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)"); | 86 | MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)"); |
83 | MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0"); | 87 | MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0"); |
88 | MODULE_PARM_DESC(devid, "The format is: 'DEV_name:VendorID:DeviceID:Flags'"); | ||
84 | 89 | ||
85 | /* use ethtool to change the level for any given device */ | 90 | /* use ethtool to change the level for any given device */ |
86 | static int msg_level = -1; | 91 | static int msg_level = -1; |
@@ -113,7 +118,7 @@ static void ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
113 | break; | 118 | break; |
114 | default: | 119 | default: |
115 | if (netif_msg_drv(pegasus)) | 120 | if (netif_msg_drv(pegasus)) |
116 | dev_err(&pegasus->intf->dev, "%s, status %d\n", | 121 | dev_dbg(&pegasus->intf->dev, "%s, status %d\n", |
117 | __FUNCTION__, urb->status); | 122 | __FUNCTION__, urb->status); |
118 | } | 123 | } |
119 | pegasus->flags &= ~ETH_REGS_CHANGED; | 124 | pegasus->flags &= ~ETH_REGS_CHANGED; |
@@ -308,9 +313,9 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) | |||
308 | __le16 regdi; | 313 | __le16 regdi; |
309 | int ret; | 314 | int ret; |
310 | 315 | ||
311 | ret = set_register(pegasus, PhyCtrl, 0); | 316 | set_register(pegasus, PhyCtrl, 0); |
312 | ret = set_registers(pegasus, PhyAddr, sizeof (data), data); | 317 | set_registers(pegasus, PhyAddr, sizeof (data), data); |
313 | ret = set_register(pegasus, PhyCtrl, (indx | PHY_READ)); | 318 | set_register(pegasus, PhyCtrl, (indx | PHY_READ)); |
314 | for (i = 0; i < REG_TIMEOUT; i++) { | 319 | for (i = 0; i < REG_TIMEOUT; i++) { |
315 | ret = get_registers(pegasus, PhyCtrl, 1, data); | 320 | ret = get_registers(pegasus, PhyCtrl, 1, data); |
316 | if (data[0] & PHY_DONE) | 321 | if (data[0] & PHY_DONE) |
@@ -319,12 +324,12 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) | |||
319 | if (i < REG_TIMEOUT) { | 324 | if (i < REG_TIMEOUT) { |
320 | ret = get_registers(pegasus, PhyData, 2, ®di); | 325 | ret = get_registers(pegasus, PhyData, 2, ®di); |
321 | *regd = le16_to_cpu(regdi); | 326 | *regd = le16_to_cpu(regdi); |
322 | return 1; | 327 | return ret; |
323 | } | 328 | } |
324 | if (netif_msg_drv(pegasus)) | 329 | if (netif_msg_drv(pegasus)) |
325 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 330 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
326 | 331 | ||
327 | return 0; | 332 | return ret; |
328 | } | 333 | } |
329 | 334 | ||
330 | static int mdio_read(struct net_device *dev, int phy_id, int loc) | 335 | static int mdio_read(struct net_device *dev, int phy_id, int loc) |
@@ -344,20 +349,20 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd) | |||
344 | 349 | ||
345 | data[1] = (u8) regd; | 350 | data[1] = (u8) regd; |
346 | data[2] = (u8) (regd >> 8); | 351 | data[2] = (u8) (regd >> 8); |
347 | ret = set_register(pegasus, PhyCtrl, 0); | 352 | set_register(pegasus, PhyCtrl, 0); |
348 | ret = set_registers(pegasus, PhyAddr, sizeof(data), data); | 353 | set_registers(pegasus, PhyAddr, sizeof(data), data); |
349 | ret = set_register(pegasus, PhyCtrl, (indx | PHY_WRITE)); | 354 | set_register(pegasus, PhyCtrl, (indx | PHY_WRITE)); |
350 | for (i = 0; i < REG_TIMEOUT; i++) { | 355 | for (i = 0; i < REG_TIMEOUT; i++) { |
351 | ret = get_registers(pegasus, PhyCtrl, 1, data); | 356 | ret = get_registers(pegasus, PhyCtrl, 1, data); |
352 | if (data[0] & PHY_DONE) | 357 | if (data[0] & PHY_DONE) |
353 | break; | 358 | break; |
354 | } | 359 | } |
355 | if (i < REG_TIMEOUT) | 360 | if (i < REG_TIMEOUT) |
356 | return 0; | 361 | return ret; |
357 | 362 | ||
358 | if (netif_msg_drv(pegasus)) | 363 | if (netif_msg_drv(pegasus)) |
359 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 364 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
360 | return 1; | 365 | return -ETIMEDOUT; |
361 | } | 366 | } |
362 | 367 | ||
363 | static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) | 368 | static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) |
@@ -374,9 +379,9 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) | |||
374 | __le16 retdatai; | 379 | __le16 retdatai; |
375 | int ret; | 380 | int ret; |
376 | 381 | ||
377 | ret = set_register(pegasus, EpromCtrl, 0); | 382 | set_register(pegasus, EpromCtrl, 0); |
378 | ret = set_register(pegasus, EpromOffset, index); | 383 | set_register(pegasus, EpromOffset, index); |
379 | ret = set_register(pegasus, EpromCtrl, EPROM_READ); | 384 | set_register(pegasus, EpromCtrl, EPROM_READ); |
380 | 385 | ||
381 | for (i = 0; i < REG_TIMEOUT; i++) { | 386 | for (i = 0; i < REG_TIMEOUT; i++) { |
382 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); | 387 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); |
@@ -386,12 +391,12 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) | |||
386 | if (i < REG_TIMEOUT) { | 391 | if (i < REG_TIMEOUT) { |
387 | ret = get_registers(pegasus, EpromData, 2, &retdatai); | 392 | ret = get_registers(pegasus, EpromData, 2, &retdatai); |
388 | *retdata = le16_to_cpu(retdatai); | 393 | *retdata = le16_to_cpu(retdatai); |
389 | return 0; | 394 | return ret; |
390 | } | 395 | } |
391 | 396 | ||
392 | if (netif_msg_drv(pegasus)) | 397 | if (netif_msg_drv(pegasus)) |
393 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 398 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
394 | return -1; | 399 | return -ETIMEDOUT; |
395 | } | 400 | } |
396 | 401 | ||
397 | #ifdef PEGASUS_WRITE_EEPROM | 402 | #ifdef PEGASUS_WRITE_EEPROM |
@@ -400,8 +405,8 @@ static inline void enable_eprom_write(pegasus_t * pegasus) | |||
400 | __u8 tmp; | 405 | __u8 tmp; |
401 | int ret; | 406 | int ret; |
402 | 407 | ||
403 | ret = get_registers(pegasus, EthCtrl2, 1, &tmp); | 408 | get_registers(pegasus, EthCtrl2, 1, &tmp); |
404 | ret = set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE); | 409 | set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE); |
405 | } | 410 | } |
406 | 411 | ||
407 | static inline void disable_eprom_write(pegasus_t * pegasus) | 412 | static inline void disable_eprom_write(pegasus_t * pegasus) |
@@ -409,9 +414,9 @@ static inline void disable_eprom_write(pegasus_t * pegasus) | |||
409 | __u8 tmp; | 414 | __u8 tmp; |
410 | int ret; | 415 | int ret; |
411 | 416 | ||
412 | ret = get_registers(pegasus, EthCtrl2, 1, &tmp); | 417 | get_registers(pegasus, EthCtrl2, 1, &tmp); |
413 | ret = set_register(pegasus, EpromCtrl, 0); | 418 | set_register(pegasus, EpromCtrl, 0); |
414 | ret = set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE); | 419 | set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE); |
415 | } | 420 | } |
416 | 421 | ||
417 | static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) | 422 | static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) |
@@ -420,11 +425,11 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) | |||
420 | __u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE }; | 425 | __u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE }; |
421 | int ret; | 426 | int ret; |
422 | 427 | ||
423 | ret = set_registers(pegasus, EpromOffset, 4, d); | 428 | set_registers(pegasus, EpromOffset, 4, d); |
424 | enable_eprom_write(pegasus); | 429 | enable_eprom_write(pegasus); |
425 | ret = set_register(pegasus, EpromOffset, index); | 430 | set_register(pegasus, EpromOffset, index); |
426 | ret = set_registers(pegasus, EpromData, 2, &data); | 431 | set_registers(pegasus, EpromData, 2, &data); |
427 | ret = set_register(pegasus, EpromCtrl, EPROM_WRITE); | 432 | set_register(pegasus, EpromCtrl, EPROM_WRITE); |
428 | 433 | ||
429 | for (i = 0; i < REG_TIMEOUT; i++) { | 434 | for (i = 0; i < REG_TIMEOUT; i++) { |
430 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); | 435 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); |
@@ -433,10 +438,10 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) | |||
433 | } | 438 | } |
434 | disable_eprom_write(pegasus); | 439 | disable_eprom_write(pegasus); |
435 | if (i < REG_TIMEOUT) | 440 | if (i < REG_TIMEOUT) |
436 | return 0; | 441 | return ret; |
437 | if (netif_msg_drv(pegasus)) | 442 | if (netif_msg_drv(pegasus)) |
438 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); | 443 | dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); |
439 | return -1; | 444 | return -ETIMEDOUT; |
440 | } | 445 | } |
441 | #endif /* PEGASUS_WRITE_EEPROM */ | 446 | #endif /* PEGASUS_WRITE_EEPROM */ |
442 | 447 | ||
@@ -454,10 +459,9 @@ static inline void get_node_id(pegasus_t * pegasus, __u8 * id) | |||
454 | static void set_ethernet_addr(pegasus_t * pegasus) | 459 | static void set_ethernet_addr(pegasus_t * pegasus) |
455 | { | 460 | { |
456 | __u8 node_id[6]; | 461 | __u8 node_id[6]; |
457 | int ret; | ||
458 | 462 | ||
459 | get_node_id(pegasus, node_id); | 463 | get_node_id(pegasus, node_id); |
460 | ret = set_registers(pegasus, EthID, sizeof (node_id), node_id); | 464 | set_registers(pegasus, EthID, sizeof (node_id), node_id); |
461 | memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id)); | 465 | memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id)); |
462 | } | 466 | } |
463 | 467 | ||
@@ -465,30 +469,29 @@ static inline int reset_mac(pegasus_t * pegasus) | |||
465 | { | 469 | { |
466 | __u8 data = 0x8; | 470 | __u8 data = 0x8; |
467 | int i; | 471 | int i; |
468 | int ret; | ||
469 | 472 | ||
470 | ret = set_register(pegasus, EthCtrl1, data); | 473 | set_register(pegasus, EthCtrl1, data); |
471 | for (i = 0; i < REG_TIMEOUT; i++) { | 474 | for (i = 0; i < REG_TIMEOUT; i++) { |
472 | ret = get_registers(pegasus, EthCtrl1, 1, &data); | 475 | get_registers(pegasus, EthCtrl1, 1, &data); |
473 | if (~data & 0x08) { | 476 | if (~data & 0x08) { |
474 | if (loopback & 1) | 477 | if (loopback & 1) |
475 | break; | 478 | break; |
476 | if (mii_mode && (pegasus->features & HAS_HOME_PNA)) | 479 | if (mii_mode && (pegasus->features & HAS_HOME_PNA)) |
477 | ret = set_register(pegasus, Gpio1, 0x34); | 480 | set_register(pegasus, Gpio1, 0x34); |
478 | else | 481 | else |
479 | ret = set_register(pegasus, Gpio1, 0x26); | 482 | set_register(pegasus, Gpio1, 0x26); |
480 | ret = set_register(pegasus, Gpio0, pegasus->features); | 483 | set_register(pegasus, Gpio0, pegasus->features); |
481 | ret = set_register(pegasus, Gpio0, DEFAULT_GPIO_SET); | 484 | set_register(pegasus, Gpio0, DEFAULT_GPIO_SET); |
482 | break; | 485 | break; |
483 | } | 486 | } |
484 | } | 487 | } |
485 | if (i == REG_TIMEOUT) | 488 | if (i == REG_TIMEOUT) |
486 | return 1; | 489 | return -ETIMEDOUT; |
487 | 490 | ||
488 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS || | 491 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS || |
489 | usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) { | 492 | usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) { |
490 | ret = set_register(pegasus, Gpio0, 0x24); | 493 | set_register(pegasus, Gpio0, 0x24); |
491 | ret = set_register(pegasus, Gpio0, 0x26); | 494 | set_register(pegasus, Gpio0, 0x26); |
492 | } | 495 | } |
493 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) { | 496 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) { |
494 | __u16 auxmode; | 497 | __u16 auxmode; |
@@ -527,7 +530,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) | |||
527 | write_mii_word(pegasus, 0, 0x1b, auxmode | 4); | 530 | write_mii_word(pegasus, 0, 0x1b, auxmode | 4); |
528 | } | 531 | } |
529 | 532 | ||
530 | return 0; | 533 | return ret; |
531 | } | 534 | } |
532 | 535 | ||
533 | static void fill_skb_pool(pegasus_t * pegasus) | 536 | static void fill_skb_pool(pegasus_t * pegasus) |
@@ -881,9 +884,8 @@ static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev) | |||
881 | static inline void disable_net_traffic(pegasus_t * pegasus) | 884 | static inline void disable_net_traffic(pegasus_t * pegasus) |
882 | { | 885 | { |
883 | int tmp = 0; | 886 | int tmp = 0; |
884 | int ret; | ||
885 | 887 | ||
886 | ret = set_registers(pegasus, EthCtrl0, 2, &tmp); | 888 | set_registers(pegasus, EthCtrl0, 2, &tmp); |
887 | } | 889 | } |
888 | 890 | ||
889 | static inline void get_interrupt_interval(pegasus_t * pegasus) | 891 | static inline void get_interrupt_interval(pegasus_t * pegasus) |
@@ -1206,18 +1208,17 @@ static __u8 mii_phy_probe(pegasus_t * pegasus) | |||
1206 | static inline void setup_pegasus_II(pegasus_t * pegasus) | 1208 | static inline void setup_pegasus_II(pegasus_t * pegasus) |
1207 | { | 1209 | { |
1208 | __u8 data = 0xa5; | 1210 | __u8 data = 0xa5; |
1209 | int ret; | ||
1210 | 1211 | ||
1211 | ret = set_register(pegasus, Reg1d, 0); | 1212 | set_register(pegasus, Reg1d, 0); |
1212 | ret = set_register(pegasus, Reg7b, 1); | 1213 | set_register(pegasus, Reg7b, 1); |
1213 | mdelay(100); | 1214 | mdelay(100); |
1214 | if ((pegasus->features & HAS_HOME_PNA) && mii_mode) | 1215 | if ((pegasus->features & HAS_HOME_PNA) && mii_mode) |
1215 | ret = set_register(pegasus, Reg7b, 0); | 1216 | set_register(pegasus, Reg7b, 0); |
1216 | else | 1217 | else |
1217 | ret = set_register(pegasus, Reg7b, 2); | 1218 | set_register(pegasus, Reg7b, 2); |
1218 | 1219 | ||
1219 | ret = set_register(pegasus, 0x83, data); | 1220 | set_register(pegasus, 0x83, data); |
1220 | ret = get_registers(pegasus, 0x83, 1, &data); | 1221 | get_registers(pegasus, 0x83, 1, &data); |
1221 | 1222 | ||
1222 | if (data == 0xa5) { | 1223 | if (data == 0xa5) { |
1223 | pegasus->chip = 0x8513; | 1224 | pegasus->chip = 0x8513; |
@@ -1225,14 +1226,14 @@ static inline void setup_pegasus_II(pegasus_t * pegasus) | |||
1225 | pegasus->chip = 0; | 1226 | pegasus->chip = 0; |
1226 | } | 1227 | } |
1227 | 1228 | ||
1228 | ret = set_register(pegasus, 0x80, 0xc0); | 1229 | set_register(pegasus, 0x80, 0xc0); |
1229 | ret = set_register(pegasus, 0x83, 0xff); | 1230 | set_register(pegasus, 0x83, 0xff); |
1230 | ret = set_register(pegasus, 0x84, 0x01); | 1231 | set_register(pegasus, 0x84, 0x01); |
1231 | 1232 | ||
1232 | if (pegasus->features & HAS_HOME_PNA && mii_mode) | 1233 | if (pegasus->features & HAS_HOME_PNA && mii_mode) |
1233 | ret = set_register(pegasus, Reg81, 6); | 1234 | set_register(pegasus, Reg81, 6); |
1234 | else | 1235 | else |
1235 | ret = set_register(pegasus, Reg81, 2); | 1236 | set_register(pegasus, Reg81, 2); |
1236 | } | 1237 | } |
1237 | 1238 | ||
1238 | 1239 | ||
@@ -1414,9 +1415,42 @@ static struct usb_driver pegasus_driver = { | |||
1414 | .resume = pegasus_resume, | 1415 | .resume = pegasus_resume, |
1415 | }; | 1416 | }; |
1416 | 1417 | ||
1418 | static void parse_id(char *id) | ||
1419 | { | ||
1420 | unsigned int vendor_id=0, device_id=0, flags=0, i=0; | ||
1421 | char *token, *name=NULL; | ||
1422 | |||
1423 | if ((token = strsep(&id, ":")) != NULL) | ||
1424 | name = token; | ||
1425 | /* name now points to a null terminated string*/ | ||
1426 | if ((token = strsep(&id, ":")) != NULL) | ||
1427 | vendor_id = simple_strtoul(token, NULL, 16); | ||
1428 | if ((token = strsep(&id, ":")) != NULL) | ||
1429 | device_id = simple_strtoul(token, NULL, 16); | ||
1430 | flags = simple_strtoul(id, NULL, 16); | ||
1431 | pr_info("%s: new device %s, vendor ID 0x%04x, device ID 0x%04x, flags: 0x%x\n", | ||
1432 | driver_name, name, vendor_id, device_id, flags); | ||
1433 | |||
1434 | if (vendor_id > 0x10000 || vendor_id == 0) | ||
1435 | return; | ||
1436 | if (device_id > 0x10000 || device_id == 0) | ||
1437 | return; | ||
1438 | |||
1439 | for (i=0; usb_dev_id[i].name; i++); | ||
1440 | usb_dev_id[i].name = name; | ||
1441 | usb_dev_id[i].vendor = vendor_id; | ||
1442 | usb_dev_id[i].device = device_id; | ||
1443 | usb_dev_id[i].private = flags; | ||
1444 | pegasus_ids[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE; | ||
1445 | pegasus_ids[i].idVendor = vendor_id; | ||
1446 | pegasus_ids[i].idProduct = device_id; | ||
1447 | } | ||
1448 | |||
1417 | static int __init pegasus_init(void) | 1449 | static int __init pegasus_init(void) |
1418 | { | 1450 | { |
1419 | pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION); | 1451 | pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION); |
1452 | if (devid) | ||
1453 | parse_id(devid); | ||
1420 | pegasus_workqueue = create_singlethread_workqueue("pegasus"); | 1454 | pegasus_workqueue = create_singlethread_workqueue("pegasus"); |
1421 | if (!pegasus_workqueue) | 1455 | if (!pegasus_workqueue) |
1422 | return -ENOMEM; | 1456 | return -ENOMEM; |
diff --git a/drivers/usb/net/plusb.c b/drivers/usb/net/plusb.c index 89856aa0e3b8..4fe863389cb7 100644 --- a/drivers/usb/net/plusb.c +++ b/drivers/usb/net/plusb.c | |||
@@ -127,7 +127,6 @@ static const struct usb_device_id products [] = { | |||
127 | MODULE_DEVICE_TABLE(usb, products); | 127 | MODULE_DEVICE_TABLE(usb, products); |
128 | 128 | ||
129 | static struct usb_driver plusb_driver = { | 129 | static struct usb_driver plusb_driver = { |
130 | .owner = THIS_MODULE, | ||
131 | .name = "plusb", | 130 | .name = "plusb", |
132 | .id_table = products, | 131 | .id_table = products, |
133 | .probe = usbnet_probe, | 132 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c index c0ecbab6f6ba..49991ac1bf3b 100644 --- a/drivers/usb/net/rndis_host.c +++ b/drivers/usb/net/rndis_host.c | |||
@@ -586,7 +586,6 @@ static const struct usb_device_id products [] = { | |||
586 | MODULE_DEVICE_TABLE(usb, products); | 586 | MODULE_DEVICE_TABLE(usb, products); |
587 | 587 | ||
588 | static struct usb_driver rndis_driver = { | 588 | static struct usb_driver rndis_driver = { |
589 | .owner = THIS_MODULE, | ||
590 | .name = "rndis_host", | 589 | .name = "rndis_host", |
591 | .id_table = products, | 590 | .id_table = products, |
592 | .probe = usbnet_probe, | 591 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index 787dd3591d6a..8ca52be23976 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c | |||
@@ -177,7 +177,6 @@ static int rtl8150_probe(struct usb_interface *intf, | |||
177 | static const char driver_name [] = "rtl8150"; | 177 | static const char driver_name [] = "rtl8150"; |
178 | 178 | ||
179 | static struct usb_driver rtl8150_driver = { | 179 | static struct usb_driver rtl8150_driver = { |
180 | .owner = THIS_MODULE, | ||
181 | .name = driver_name, | 180 | .name = driver_name, |
182 | .probe = rtl8150_probe, | 181 | .probe = rtl8150_probe, |
183 | .disconnect = rtl8150_disconnect, | 182 | .disconnect = rtl8150_disconnect, |
diff --git a/drivers/usb/net/zaurus.c b/drivers/usb/net/zaurus.c index 680d13957af4..9c5ab251370c 100644 --- a/drivers/usb/net/zaurus.c +++ b/drivers/usb/net/zaurus.c | |||
@@ -357,7 +357,6 @@ static const struct usb_device_id products [] = { | |||
357 | MODULE_DEVICE_TABLE(usb, products); | 357 | MODULE_DEVICE_TABLE(usb, products); |
358 | 358 | ||
359 | static struct usb_driver zaurus_driver = { | 359 | static struct usb_driver zaurus_driver = { |
360 | .owner = THIS_MODULE, | ||
361 | .name = "zaurus", | 360 | .name = "zaurus", |
362 | .id_table = products, | 361 | .id_table = products, |
363 | .probe = usbnet_probe, | 362 | .probe = usbnet_probe, |
diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c index 2f52261c7cc1..f3a8e2807c3b 100644 --- a/drivers/usb/net/zd1201.c +++ b/drivers/usb/net/zd1201.c | |||
@@ -1722,7 +1722,7 @@ static const struct iw_priv_args zd1201_private_args[] = { | |||
1722 | IW_PRIV_TYPE_NONE, "sethostauth" }, | 1722 | IW_PRIV_TYPE_NONE, "sethostauth" }, |
1723 | { ZD1201GIWHOSTAUTH, IW_PRIV_TYPE_NONE, | 1723 | { ZD1201GIWHOSTAUTH, IW_PRIV_TYPE_NONE, |
1724 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostauth" }, | 1724 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostauth" }, |
1725 | { ZD1201SIWAUTHSTA, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, | 1725 | { ZD1201SIWAUTHSTA, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, |
1726 | IW_PRIV_TYPE_NONE, "authstation" }, | 1726 | IW_PRIV_TYPE_NONE, "authstation" }, |
1727 | { ZD1201SIWMAXASSOC, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | 1727 | { ZD1201SIWMAXASSOC, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, |
1728 | IW_PRIV_TYPE_NONE, "setmaxassoc" }, | 1728 | IW_PRIV_TYPE_NONE, "setmaxassoc" }, |
@@ -1731,9 +1731,9 @@ static const struct iw_priv_args zd1201_private_args[] = { | |||
1731 | }; | 1731 | }; |
1732 | 1732 | ||
1733 | static const struct iw_handler_def zd1201_iw_handlers = { | 1733 | static const struct iw_handler_def zd1201_iw_handlers = { |
1734 | .num_standard = sizeof(zd1201_iw_handler)/sizeof(iw_handler), | 1734 | .num_standard = ARRAY_SIZE(zd1201_iw_handler), |
1735 | .num_private = sizeof(zd1201_private_handler)/sizeof(iw_handler), | 1735 | .num_private = ARRAY_SIZE(zd1201_private_handler), |
1736 | .num_private_args = sizeof(zd1201_private_args)/sizeof(struct iw_priv_args), | 1736 | .num_private_args = ARRAY_SIZE(zd1201_private_args), |
1737 | .standard = (iw_handler *)zd1201_iw_handler, | 1737 | .standard = (iw_handler *)zd1201_iw_handler, |
1738 | .private = (iw_handler *)zd1201_private_handler, | 1738 | .private = (iw_handler *)zd1201_private_handler, |
1739 | .private_args = (struct iw_priv_args *) zd1201_private_args, | 1739 | .private_args = (struct iw_priv_args *) zd1201_private_args, |
@@ -1829,6 +1829,8 @@ static int zd1201_probe(struct usb_interface *interface, | |||
1829 | if (err) | 1829 | if (err) |
1830 | goto err_net; | 1830 | goto err_net; |
1831 | 1831 | ||
1832 | SET_NETDEV_DEV(zd->dev, &usb->dev); | ||
1833 | |||
1832 | err = register_netdev(zd->dev); | 1834 | err = register_netdev(zd->dev); |
1833 | if (err) | 1835 | if (err) |
1834 | goto err_net; | 1836 | goto err_net; |
@@ -1923,7 +1925,6 @@ static int zd1201_resume(struct usb_interface *interface) | |||
1923 | #endif | 1925 | #endif |
1924 | 1926 | ||
1925 | static struct usb_driver zd1201_usb = { | 1927 | static struct usb_driver zd1201_usb = { |
1926 | .owner = THIS_MODULE, | ||
1927 | .name = "zd1201", | 1928 | .name = "zd1201", |
1928 | .probe = zd1201_probe, | 1929 | .probe = zd1201_probe, |
1929 | .disconnect = zd1201_disconnect, | 1930 | .disconnect = zd1201_disconnect, |
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 1f29d8837327..dbf1f063098c 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c | |||
@@ -23,11 +23,11 @@ static struct usb_device_id id_table [] = { | |||
23 | MODULE_DEVICE_TABLE(usb, id_table); | 23 | MODULE_DEVICE_TABLE(usb, id_table); |
24 | 24 | ||
25 | static struct usb_driver airprime_driver = { | 25 | static struct usb_driver airprime_driver = { |
26 | .owner = THIS_MODULE, | ||
27 | .name = "airprime", | 26 | .name = "airprime", |
28 | .probe = usb_serial_probe, | 27 | .probe = usb_serial_probe, |
29 | .disconnect = usb_serial_disconnect, | 28 | .disconnect = usb_serial_disconnect, |
30 | .id_table = id_table, | 29 | .id_table = id_table, |
30 | .no_dynamic_id = 1, | ||
31 | }; | 31 | }; |
32 | 32 | ||
33 | static struct usb_serial_driver airprime_device = { | 33 | static struct usb_serial_driver airprime_device = { |
diff --git a/drivers/usb/serial/anydata.c b/drivers/usb/serial/anydata.c index 18022a74a3dc..343f6f228220 100644 --- a/drivers/usb/serial/anydata.c +++ b/drivers/usb/serial/anydata.c | |||
@@ -27,11 +27,11 @@ static int buffer_size; | |||
27 | static int debug; | 27 | static int debug; |
28 | 28 | ||
29 | static struct usb_driver anydata_driver = { | 29 | static struct usb_driver anydata_driver = { |
30 | .owner = THIS_MODULE, | ||
31 | .name = "anydata", | 30 | .name = "anydata", |
32 | .probe = usb_serial_probe, | 31 | .probe = usb_serial_probe, |
33 | .disconnect = usb_serial_disconnect, | 32 | .disconnect = usb_serial_disconnect, |
34 | .id_table = id_table, | 33 | .id_table = id_table, |
34 | .no_dynamic_id = 1, | ||
35 | }; | 35 | }; |
36 | 36 | ||
37 | static int anydata_open(struct usb_serial_port *port, struct file *filp) | 37 | static int anydata_open(struct usb_serial_port *port, struct file *filp) |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 84bc0ee4f061..4144777ea18b 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -113,11 +113,11 @@ static struct usb_device_id id_table_combined [] = { | |||
113 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 113 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
114 | 114 | ||
115 | static struct usb_driver belkin_driver = { | 115 | static struct usb_driver belkin_driver = { |
116 | .owner = THIS_MODULE, | ||
117 | .name = "belkin", | 116 | .name = "belkin", |
118 | .probe = usb_serial_probe, | 117 | .probe = usb_serial_probe, |
119 | .disconnect = usb_serial_disconnect, | 118 | .disconnect = usb_serial_disconnect, |
120 | .id_table = id_table_combined, | 119 | .id_table = id_table_combined, |
120 | .no_dynamic_id = 1, | ||
121 | }; | 121 | }; |
122 | 122 | ||
123 | /* All of the device info needed for the serial converters */ | 123 | /* All of the device info needed for the serial converters */ |
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index c9787001cf2a..da46b351e188 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
@@ -67,11 +67,11 @@ static struct usb_device_id id_table [] = { | |||
67 | MODULE_DEVICE_TABLE (usb, id_table); | 67 | MODULE_DEVICE_TABLE (usb, id_table); |
68 | 68 | ||
69 | static struct usb_driver cp2101_driver = { | 69 | static struct usb_driver cp2101_driver = { |
70 | .owner = THIS_MODULE, | ||
71 | .name = "cp2101", | 70 | .name = "cp2101", |
72 | .probe = usb_serial_probe, | 71 | .probe = usb_serial_probe, |
73 | .disconnect = usb_serial_disconnect, | 72 | .disconnect = usb_serial_disconnect, |
74 | .id_table = id_table, | 73 | .id_table = id_table, |
74 | .no_dynamic_id = 1, | ||
75 | }; | 75 | }; |
76 | 76 | ||
77 | static struct usb_serial_driver cp2101_device = { | 77 | static struct usb_serial_driver cp2101_device = { |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index e581e4ae8483..6d18d4eaba35 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
@@ -76,11 +76,11 @@ static struct usb_device_id id_table [] = { | |||
76 | MODULE_DEVICE_TABLE (usb, id_table); | 76 | MODULE_DEVICE_TABLE (usb, id_table); |
77 | 77 | ||
78 | static struct usb_driver cyberjack_driver = { | 78 | static struct usb_driver cyberjack_driver = { |
79 | .owner = THIS_MODULE, | ||
80 | .name = "cyberjack", | 79 | .name = "cyberjack", |
81 | .probe = usb_serial_probe, | 80 | .probe = usb_serial_probe, |
82 | .disconnect = usb_serial_disconnect, | 81 | .disconnect = usb_serial_disconnect, |
83 | .id_table = id_table, | 82 | .id_table = id_table, |
83 | .no_dynamic_id = 1, | ||
84 | }; | 84 | }; |
85 | 85 | ||
86 | static struct usb_serial_driver cyberjack_device = { | 86 | static struct usb_serial_driver cyberjack_device = { |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index af9290ed257b..af18355e94cc 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -112,6 +112,7 @@ static struct usb_driver cypress_driver = { | |||
112 | .probe = usb_serial_probe, | 112 | .probe = usb_serial_probe, |
113 | .disconnect = usb_serial_disconnect, | 113 | .disconnect = usb_serial_disconnect, |
114 | .id_table = id_table_combined, | 114 | .id_table = id_table_combined, |
115 | .no_dynamic_id = 1, | ||
115 | }; | 116 | }; |
116 | 117 | ||
117 | struct cypress_private { | 118 | struct cypress_private { |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index dc74644a603d..8fc414bd5b24 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -493,11 +493,11 @@ static struct usb_device_id id_table_4 [] = { | |||
493 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 493 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
494 | 494 | ||
495 | static struct usb_driver digi_driver = { | 495 | static struct usb_driver digi_driver = { |
496 | .owner = THIS_MODULE, | ||
497 | .name = "digi_acceleport", | 496 | .name = "digi_acceleport", |
498 | .probe = usb_serial_probe, | 497 | .probe = usb_serial_probe, |
499 | .disconnect = usb_serial_disconnect, | 498 | .disconnect = usb_serial_disconnect, |
500 | .id_table = id_table_combined, | 499 | .id_table = id_table_combined, |
500 | .no_dynamic_id = 1, | ||
501 | }; | 501 | }; |
502 | 502 | ||
503 | 503 | ||
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 0b0546dcc7b9..79a766e9ca23 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
@@ -105,11 +105,11 @@ static struct usb_device_id id_table [] = { | |||
105 | MODULE_DEVICE_TABLE (usb, id_table); | 105 | MODULE_DEVICE_TABLE (usb, id_table); |
106 | 106 | ||
107 | static struct usb_driver empeg_driver = { | 107 | static struct usb_driver empeg_driver = { |
108 | .owner = THIS_MODULE, | ||
109 | .name = "empeg", | 108 | .name = "empeg", |
110 | .probe = usb_serial_probe, | 109 | .probe = usb_serial_probe, |
111 | .disconnect = usb_serial_disconnect, | 110 | .disconnect = usb_serial_disconnect, |
112 | .id_table = id_table, | 111 | .id_table = id_table, |
112 | .no_dynamic_id = 1, | ||
113 | }; | 113 | }; |
114 | 114 | ||
115 | static struct usb_serial_driver empeg_device = { | 115 | static struct usb_serial_driver empeg_device = { |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 06e04b442ff1..eb863b3f2d79 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -471,12 +471,15 @@ static struct usb_device_id id_table_combined [] = { | |||
471 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, | 471 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, |
472 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) }, | 472 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) }, |
473 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) }, | 473 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) }, |
474 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) }, | ||
475 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) }, | ||
474 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, | 476 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, |
475 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, | 477 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, |
476 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, | 478 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, |
477 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) }, | 479 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) }, |
478 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) }, | 480 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) }, |
479 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, | 481 | { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, |
482 | { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) }, | ||
480 | { }, /* Optional parameter entry */ | 483 | { }, /* Optional parameter entry */ |
481 | { } /* Terminating entry */ | 484 | { } /* Terminating entry */ |
482 | }; | 485 | }; |
@@ -488,9 +491,10 @@ static struct usb_driver ftdi_driver = { | |||
488 | .probe = usb_serial_probe, | 491 | .probe = usb_serial_probe, |
489 | .disconnect = usb_serial_disconnect, | 492 | .disconnect = usb_serial_disconnect, |
490 | .id_table = id_table_combined, | 493 | .id_table = id_table_combined, |
494 | .no_dynamic_id = 1, | ||
491 | }; | 495 | }; |
492 | 496 | ||
493 | static char *ftdi_chip_name[] = { | 497 | static const char *ftdi_chip_name[] = { |
494 | [SIO] = "SIO", /* the serial part of FT8U100AX */ | 498 | [SIO] = "SIO", /* the serial part of FT8U100AX */ |
495 | [FT8U232AM] = "FT8U232AM", | 499 | [FT8U232AM] = "FT8U232AM", |
496 | [FT232BM] = "FT232BM", | 500 | [FT232BM] = "FT232BM", |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 773ea3eca086..f380f9eaff71 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -343,6 +343,13 @@ | |||
343 | #define XSENS_CONVERTER_7_PID 0xD38F | 343 | #define XSENS_CONVERTER_7_PID 0xD38F |
344 | 344 | ||
345 | /* | 345 | /* |
346 | * Teratronik product ids. | ||
347 | * Submitted by O. Wölfelschneider. | ||
348 | */ | ||
349 | #define FTDI_TERATRONIK_VCP_PID 0xEC88 /* Teratronik device (preferring VCP driver on windows) */ | ||
350 | #define FTDI_TERATRONIK_D2XX_PID 0xEC89 /* Teratronik device (preferring D2XX driver on windows) */ | ||
351 | |||
352 | /* | ||
346 | * Evolution Robotics products (http://www.evolution.com/). | 353 | * Evolution Robotics products (http://www.evolution.com/). |
347 | * Submitted by Shawn M. Lavelle. | 354 | * Submitted by Shawn M. Lavelle. |
348 | */ | 355 | */ |
@@ -352,6 +359,12 @@ | |||
352 | /* Pyramid Computer GmbH */ | 359 | /* Pyramid Computer GmbH */ |
353 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ | 360 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ |
354 | 361 | ||
362 | /* | ||
363 | * Posiflex inc retail equipment (http://www.posiflex.com.tw) | ||
364 | */ | ||
365 | #define POSIFLEX_VID 0x0d3a /* Vendor ID */ | ||
366 | #define POSIFLEX_PP7000_PID 0x0300 /* PP-7000II thermal printer */ | ||
367 | |||
355 | /* Commands */ | 368 | /* Commands */ |
356 | #define FTDI_SIO_RESET 0 /* Reset the port */ | 369 | #define FTDI_SIO_RESET 0 /* Reset the port */ |
357 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ | 370 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 35820bda7ae1..452efce72714 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -222,11 +222,11 @@ static struct usb_device_id id_table [] = { | |||
222 | MODULE_DEVICE_TABLE (usb, id_table); | 222 | MODULE_DEVICE_TABLE (usb, id_table); |
223 | 223 | ||
224 | static struct usb_driver garmin_driver = { | 224 | static struct usb_driver garmin_driver = { |
225 | .owner = THIS_MODULE, | ||
226 | .name = "garmin_gps", | 225 | .name = "garmin_gps", |
227 | .probe = usb_serial_probe, | 226 | .probe = usb_serial_probe, |
228 | .disconnect = usb_serial_disconnect, | 227 | .disconnect = usb_serial_disconnect, |
229 | .id_table = id_table, | 228 | .id_table = id_table, |
229 | .no_dynamic_id = 1, | ||
230 | }; | 230 | }; |
231 | 231 | ||
232 | 232 | ||
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 53a47c31cd0e..4ddac620fc0c 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -68,11 +68,11 @@ static int generic_probe(struct usb_interface *interface, | |||
68 | } | 68 | } |
69 | 69 | ||
70 | static struct usb_driver generic_driver = { | 70 | static struct usb_driver generic_driver = { |
71 | .owner = THIS_MODULE, | ||
72 | .name = "usbserial_generic", | 71 | .name = "usbserial_generic", |
73 | .probe = generic_probe, | 72 | .probe = generic_probe, |
74 | .disconnect = usb_serial_disconnect, | 73 | .disconnect = usb_serial_disconnect, |
75 | .id_table = generic_serial_ids, | 74 | .id_table = generic_serial_ids, |
75 | .no_dynamic_id = 1, | ||
76 | }; | 76 | }; |
77 | #endif | 77 | #endif |
78 | 78 | ||
diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c index 8eadfb705601..e9719da2aca1 100644 --- a/drivers/usb/serial/hp4x.c +++ b/drivers/usb/serial/hp4x.c | |||
@@ -37,11 +37,11 @@ static struct usb_device_id id_table [] = { | |||
37 | MODULE_DEVICE_TABLE(usb, id_table); | 37 | MODULE_DEVICE_TABLE(usb, id_table); |
38 | 38 | ||
39 | static struct usb_driver hp49gp_driver = { | 39 | static struct usb_driver hp49gp_driver = { |
40 | .owner = THIS_MODULE, | ||
41 | .name = "hp4X", | 40 | .name = "hp4X", |
42 | .probe = usb_serial_probe, | 41 | .probe = usb_serial_probe, |
43 | .disconnect = usb_serial_disconnect, | 42 | .disconnect = usb_serial_disconnect, |
44 | .id_table = id_table, | 43 | .id_table = id_table, |
44 | .no_dynamic_id = 1, | ||
45 | }; | 45 | }; |
46 | 46 | ||
47 | static struct usb_serial_driver hp49gp_device = { | 47 | static struct usb_serial_driver hp49gp_device = { |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index dc4c498bd1ed..faedbeb6ba49 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -184,7 +184,7 @@ struct divisor_table_entry { | |||
184 | // These assume a 3.6864MHz crystal, the standard /16, and | 184 | // These assume a 3.6864MHz crystal, the standard /16, and |
185 | // MCR.7 = 0. | 185 | // MCR.7 = 0. |
186 | // | 186 | // |
187 | static struct divisor_table_entry divisor_table[] = { | 187 | static const struct divisor_table_entry divisor_table[] = { |
188 | { 50, 4608}, | 188 | { 50, 4608}, |
189 | { 75, 3072}, | 189 | { 75, 3072}, |
190 | { 110, 2095}, /* 2094.545455 => 230450 => .0217 % over */ | 190 | { 110, 2095}, /* 2094.545455 => 230450 => .0217 % over */ |
@@ -242,11 +242,11 @@ static void edge_shutdown (struct usb_serial *serial); | |||
242 | #include "io_tables.h" /* all of the devices that this driver supports */ | 242 | #include "io_tables.h" /* all of the devices that this driver supports */ |
243 | 243 | ||
244 | static struct usb_driver io_driver = { | 244 | static struct usb_driver io_driver = { |
245 | .owner = THIS_MODULE, | ||
246 | .name = "io_edgeport", | 245 | .name = "io_edgeport", |
247 | .probe = usb_serial_probe, | 246 | .probe = usb_serial_probe, |
248 | .disconnect = usb_serial_disconnect, | 247 | .disconnect = usb_serial_disconnect, |
249 | .id_table = id_table_combined, | 248 | .id_table = id_table_combined, |
249 | .no_dynamic_id = 1, | ||
250 | }; | 250 | }; |
251 | 251 | ||
252 | /* function prototypes for all of our local functions */ | 252 | /* function prototypes for all of our local functions */ |
@@ -2353,7 +2353,7 @@ static int calc_baud_rate_divisor (int baudrate, int *divisor) | |||
2353 | 2353 | ||
2354 | dbg("%s - %d", __FUNCTION__, baudrate); | 2354 | dbg("%s - %d", __FUNCTION__, baudrate); |
2355 | 2355 | ||
2356 | for (i = 0; i < NUM_ENTRIES(divisor_table); i++) { | 2356 | for (i = 0; i < ARRAY_SIZE(divisor_table); i++) { |
2357 | if ( divisor_table[i].BaudRate == baudrate ) { | 2357 | if ( divisor_table[i].BaudRate == baudrate ) { |
2358 | *divisor = divisor_table[i].Divisor; | 2358 | *divisor = divisor_table[i].Divisor; |
2359 | return 0; | 2359 | return 0; |
diff --git a/drivers/usb/serial/io_edgeport.h b/drivers/usb/serial/io_edgeport.h index 5112d7aac055..123fa8a904e6 100644 --- a/drivers/usb/serial/io_edgeport.h +++ b/drivers/usb/serial/io_edgeport.h | |||
@@ -31,9 +31,6 @@ | |||
31 | #ifndef HIGH8 | 31 | #ifndef HIGH8 |
32 | #define HIGH8(a) ((unsigned char)((a & 0xff00) >> 8)) | 32 | #define HIGH8(a) ((unsigned char)((a & 0xff00) >> 8)) |
33 | #endif | 33 | #endif |
34 | #ifndef NUM_ENTRIES | ||
35 | #define NUM_ENTRIES(x) (sizeof(x)/sizeof((x)[0])) | ||
36 | #endif | ||
37 | 34 | ||
38 | #ifndef __KERNEL__ | 35 | #ifndef __KERNEL__ |
39 | #define __KERNEL__ | 36 | #define __KERNEL__ |
diff --git a/drivers/usb/serial/io_fw_boot2.h b/drivers/usb/serial/io_fw_boot2.h index c7c3a3c305fe..e3463de99de4 100644 --- a/drivers/usb/serial/io_fw_boot2.h +++ b/drivers/usb/serial/io_fw_boot2.h | |||
@@ -537,7 +537,7 @@ static unsigned char IMAGE_ARRAY_NAME[] = { | |||
537 | 537 | ||
538 | }; | 538 | }; |
539 | 539 | ||
540 | static struct edge_firmware_version_info IMAGE_VERSION_NAME = { | 540 | static const struct edge_firmware_version_info IMAGE_VERSION_NAME = { |
541 | 2, 0, 3 }; // Major, Minor, Build | 541 | 2, 0, 3 }; // Major, Minor, Build |
542 | 542 | ||
543 | #undef IMAGE_VERSION_NAME | 543 | #undef IMAGE_VERSION_NAME |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 832b6d6734c0..2edf9cabad20 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -216,11 +216,11 @@ static struct usb_device_id id_table_combined [] = { | |||
216 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 216 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
217 | 217 | ||
218 | static struct usb_driver io_driver = { | 218 | static struct usb_driver io_driver = { |
219 | .owner = THIS_MODULE, | ||
220 | .name = "io_ti", | 219 | .name = "io_ti", |
221 | .probe = usb_serial_probe, | 220 | .probe = usb_serial_probe, |
222 | .disconnect = usb_serial_disconnect, | 221 | .disconnect = usb_serial_disconnect, |
223 | .id_table = id_table_combined, | 222 | .id_table = id_table_combined, |
223 | .no_dynamic_id = 1, | ||
224 | }; | 224 | }; |
225 | 225 | ||
226 | 226 | ||
@@ -2843,7 +2843,7 @@ static struct edge_buf *edge_buf_alloc(unsigned int size) | |||
2843 | * Free the buffer and all associated memory. | 2843 | * Free the buffer and all associated memory. |
2844 | */ | 2844 | */ |
2845 | 2845 | ||
2846 | void edge_buf_free(struct edge_buf *eb) | 2846 | static void edge_buf_free(struct edge_buf *eb) |
2847 | { | 2847 | { |
2848 | if (eb) { | 2848 | if (eb) { |
2849 | kfree(eb->buf_buf); | 2849 | kfree(eb->buf_buf); |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index d5d066488100..06d07cea0b70 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -542,11 +542,11 @@ static struct usb_device_id ipaq_id_table [] = { | |||
542 | MODULE_DEVICE_TABLE (usb, ipaq_id_table); | 542 | MODULE_DEVICE_TABLE (usb, ipaq_id_table); |
543 | 543 | ||
544 | static struct usb_driver ipaq_driver = { | 544 | static struct usb_driver ipaq_driver = { |
545 | .owner = THIS_MODULE, | ||
546 | .name = "ipaq", | 545 | .name = "ipaq", |
547 | .probe = usb_serial_probe, | 546 | .probe = usb_serial_probe, |
548 | .disconnect = usb_serial_disconnect, | 547 | .disconnect = usb_serial_disconnect, |
549 | .id_table = ipaq_id_table, | 548 | .id_table = ipaq_id_table, |
549 | .no_dynamic_id = 1, | ||
550 | }; | 550 | }; |
551 | 551 | ||
552 | 552 | ||
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 7744b8148bc5..2dd191f5fe76 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
@@ -152,11 +152,11 @@ static struct usb_device_id usb_ipw_ids[] = { | |||
152 | MODULE_DEVICE_TABLE(usb, usb_ipw_ids); | 152 | MODULE_DEVICE_TABLE(usb, usb_ipw_ids); |
153 | 153 | ||
154 | static struct usb_driver usb_ipw_driver = { | 154 | static struct usb_driver usb_ipw_driver = { |
155 | .owner = THIS_MODULE, | ||
156 | .name = "ipwtty", | 155 | .name = "ipwtty", |
157 | .probe = usb_serial_probe, | 156 | .probe = usb_serial_probe, |
158 | .disconnect = usb_serial_disconnect, | 157 | .disconnect = usb_serial_disconnect, |
159 | .id_table = usb_ipw_ids, | 158 | .id_table = usb_ipw_ids, |
159 | .no_dynamic_id = 1, | ||
160 | }; | 160 | }; |
161 | 161 | ||
162 | static int debug; | 162 | static int debug; |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 19f329e9bdcf..a59010421444 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
@@ -125,11 +125,11 @@ static struct usb_device_id id_table [] = { | |||
125 | MODULE_DEVICE_TABLE (usb, id_table); | 125 | MODULE_DEVICE_TABLE (usb, id_table); |
126 | 126 | ||
127 | static struct usb_driver ir_driver = { | 127 | static struct usb_driver ir_driver = { |
128 | .owner = THIS_MODULE, | ||
129 | .name = "ir-usb", | 128 | .name = "ir-usb", |
130 | .probe = usb_serial_probe, | 129 | .probe = usb_serial_probe, |
131 | .disconnect = usb_serial_disconnect, | 130 | .disconnect = usb_serial_disconnect, |
132 | .id_table = id_table, | 131 | .id_table = id_table, |
132 | .no_dynamic_id = 1, | ||
133 | }; | 133 | }; |
134 | 134 | ||
135 | 135 | ||
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 5cfc13b5e56f..7472ed6bf626 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h | |||
@@ -520,11 +520,11 @@ static struct usb_device_id keyspan_ids_combined[] = { | |||
520 | MODULE_DEVICE_TABLE(usb, keyspan_ids_combined); | 520 | MODULE_DEVICE_TABLE(usb, keyspan_ids_combined); |
521 | 521 | ||
522 | static struct usb_driver keyspan_driver = { | 522 | static struct usb_driver keyspan_driver = { |
523 | .owner = THIS_MODULE, | ||
524 | .name = "keyspan", | 523 | .name = "keyspan", |
525 | .probe = usb_serial_probe, | 524 | .probe = usb_serial_probe, |
526 | .disconnect = usb_serial_disconnect, | 525 | .disconnect = usb_serial_disconnect, |
527 | .id_table = keyspan_ids_combined, | 526 | .id_table = keyspan_ids_combined, |
527 | .no_dynamic_id = 1, | ||
528 | }; | 528 | }; |
529 | 529 | ||
530 | /* usb_device_id table for the pre-firmware download keyspan devices */ | 530 | /* usb_device_id table for the pre-firmware download keyspan devices */ |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index cd4f48bd83b6..b0441c35f98f 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -150,11 +150,11 @@ static struct usb_device_id id_table_combined [] = { | |||
150 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 150 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
151 | 151 | ||
152 | static struct usb_driver keyspan_pda_driver = { | 152 | static struct usb_driver keyspan_pda_driver = { |
153 | .owner = THIS_MODULE, | ||
154 | .name = "keyspan_pda", | 153 | .name = "keyspan_pda", |
155 | .probe = usb_serial_probe, | 154 | .probe = usb_serial_probe, |
156 | .disconnect = usb_serial_disconnect, | 155 | .disconnect = usb_serial_disconnect, |
157 | .id_table = id_table_combined, | 156 | .id_table = id_table_combined, |
157 | .no_dynamic_id = 1, | ||
158 | }; | 158 | }; |
159 | 159 | ||
160 | static struct usb_device_id id_table_std [] = { | 160 | static struct usb_device_id id_table_std [] = { |
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index a8951c0fd020..4e2f7dfb58b2 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -116,11 +116,11 @@ static struct usb_device_id id_table [] = { | |||
116 | MODULE_DEVICE_TABLE (usb, id_table); | 116 | MODULE_DEVICE_TABLE (usb, id_table); |
117 | 117 | ||
118 | static struct usb_driver kl5kusb105d_driver = { | 118 | static struct usb_driver kl5kusb105d_driver = { |
119 | .owner = THIS_MODULE, | ||
120 | .name = "kl5kusb105d", | 119 | .name = "kl5kusb105d", |
121 | .probe = usb_serial_probe, | 120 | .probe = usb_serial_probe, |
122 | .disconnect = usb_serial_disconnect, | 121 | .disconnect = usb_serial_disconnect, |
123 | .id_table = id_table, | 122 | .id_table = id_table, |
123 | .no_dynamic_id = 1, | ||
124 | }; | 124 | }; |
125 | 125 | ||
126 | static struct usb_serial_driver kl5kusb105d_device = { | 126 | static struct usb_serial_driver kl5kusb105d_device = { |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 9456dd9dd136..d9c21e275130 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -97,11 +97,11 @@ static struct usb_device_id id_table [] = { | |||
97 | MODULE_DEVICE_TABLE (usb, id_table); | 97 | MODULE_DEVICE_TABLE (usb, id_table); |
98 | 98 | ||
99 | static struct usb_driver kobil_driver = { | 99 | static struct usb_driver kobil_driver = { |
100 | .owner = THIS_MODULE, | ||
101 | .name = "kobil", | 100 | .name = "kobil", |
102 | .probe = usb_serial_probe, | 101 | .probe = usb_serial_probe, |
103 | .disconnect = usb_serial_disconnect, | 102 | .disconnect = usb_serial_disconnect, |
104 | .id_table = id_table, | 103 | .id_table = id_table, |
104 | .no_dynamic_id = 1, | ||
105 | }; | 105 | }; |
106 | 106 | ||
107 | 107 | ||
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index ca5dbadb9b7e..b6d6cab9c859 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -125,11 +125,11 @@ static struct usb_device_id id_table_combined [] = { | |||
125 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 125 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
126 | 126 | ||
127 | static struct usb_driver mct_u232_driver = { | 127 | static struct usb_driver mct_u232_driver = { |
128 | .owner = THIS_MODULE, | ||
129 | .name = "mct_u232", | 128 | .name = "mct_u232", |
130 | .probe = usb_serial_probe, | 129 | .probe = usb_serial_probe, |
131 | .disconnect = usb_serial_disconnect, | 130 | .disconnect = usb_serial_disconnect, |
132 | .id_table = id_table_combined, | 131 | .id_table = id_table_combined, |
132 | .no_dynamic_id = 1, | ||
133 | }; | 133 | }; |
134 | 134 | ||
135 | static struct usb_serial_driver mct_u232_device = { | 135 | static struct usb_serial_driver mct_u232_device = { |
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 3caf97072ac0..762d8ff9a1e4 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c | |||
@@ -80,11 +80,11 @@ static struct usb_device_id id_table [] = { | |||
80 | MODULE_DEVICE_TABLE (usb, id_table); | 80 | MODULE_DEVICE_TABLE (usb, id_table); |
81 | 81 | ||
82 | static struct usb_driver omninet_driver = { | 82 | static struct usb_driver omninet_driver = { |
83 | .owner = THIS_MODULE, | ||
84 | .name = "omninet", | 83 | .name = "omninet", |
85 | .probe = usb_serial_probe, | 84 | .probe = usb_serial_probe, |
86 | .disconnect = usb_serial_disconnect, | 85 | .disconnect = usb_serial_disconnect, |
87 | .id_table = id_table, | 86 | .id_table = id_table, |
87 | .no_dynamic_id = 1, | ||
88 | }; | 88 | }; |
89 | 89 | ||
90 | 90 | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 7716000045b7..3fd2405304fd 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -95,11 +95,11 @@ static struct usb_device_id option_ids[] = { | |||
95 | MODULE_DEVICE_TABLE(usb, option_ids); | 95 | MODULE_DEVICE_TABLE(usb, option_ids); |
96 | 96 | ||
97 | static struct usb_driver option_driver = { | 97 | static struct usb_driver option_driver = { |
98 | .owner = THIS_MODULE, | ||
99 | .name = "option", | 98 | .name = "option", |
100 | .probe = usb_serial_probe, | 99 | .probe = usb_serial_probe, |
101 | .disconnect = usb_serial_disconnect, | 100 | .disconnect = usb_serial_disconnect, |
102 | .id_table = option_ids, | 101 | .id_table = option_ids, |
102 | .no_dynamic_id = 1, | ||
103 | }; | 103 | }; |
104 | 104 | ||
105 | /* The card has three separate interfaces, wich the serial driver | 105 | /* The card has three separate interfaces, wich the serial driver |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 41a45a5025b2..f03721056190 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -82,11 +82,11 @@ static struct usb_device_id id_table [] = { | |||
82 | MODULE_DEVICE_TABLE (usb, id_table); | 82 | MODULE_DEVICE_TABLE (usb, id_table); |
83 | 83 | ||
84 | static struct usb_driver pl2303_driver = { | 84 | static struct usb_driver pl2303_driver = { |
85 | .owner = THIS_MODULE, | ||
86 | .name = "pl2303", | 85 | .name = "pl2303", |
87 | .probe = usb_serial_probe, | 86 | .probe = usb_serial_probe, |
88 | .disconnect = usb_serial_disconnect, | 87 | .disconnect = usb_serial_disconnect, |
89 | .id_table = id_table, | 88 | .id_table = id_table, |
89 | .no_dynamic_id = 1, | ||
90 | }; | 90 | }; |
91 | 91 | ||
92 | #define SET_LINE_REQUEST_TYPE 0x21 | 92 | #define SET_LINE_REQUEST_TYPE 0x21 |
@@ -810,7 +810,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port, | |||
810 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 810 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
811 | unsigned long flags; | 811 | unsigned long flags; |
812 | u8 status_idx = UART_STATE; | 812 | u8 status_idx = UART_STATE; |
813 | u8 length = UART_STATE; | 813 | u8 length = UART_STATE + 1; |
814 | 814 | ||
815 | if ((le16_to_cpu(port->serial->dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) && | 815 | if ((le16_to_cpu(port->serial->dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) && |
816 | (le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X65 || | 816 | (le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X65 || |
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index c22bdc0c4dfd..f0215f850d2d 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c | |||
@@ -160,14 +160,14 @@ static struct usb_device_id id_table[] = { | |||
160 | MODULE_DEVICE_TABLE (usb, id_table); | 160 | MODULE_DEVICE_TABLE (usb, id_table); |
161 | 161 | ||
162 | static struct usb_driver safe_driver = { | 162 | static struct usb_driver safe_driver = { |
163 | .owner = THIS_MODULE, | ||
164 | .name = "safe_serial", | 163 | .name = "safe_serial", |
165 | .probe = usb_serial_probe, | 164 | .probe = usb_serial_probe, |
166 | .disconnect = usb_serial_disconnect, | 165 | .disconnect = usb_serial_disconnect, |
167 | .id_table = id_table, | 166 | .id_table = id_table, |
167 | .no_dynamic_id = 1, | ||
168 | }; | 168 | }; |
169 | 169 | ||
170 | static __u16 crc10_table[256] = { | 170 | static const __u16 crc10_table[256] = { |
171 | 0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe, | 171 | 0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe, |
172 | 0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf, | 172 | 0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf, |
173 | 0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d, 0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c, | 173 | 0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d, 0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c, |
@@ -425,7 +425,7 @@ static int __init safe_init (void) | |||
425 | if (vendor || product) { | 425 | if (vendor || product) { |
426 | info ("vendor: %x product: %x\n", vendor, product); | 426 | info ("vendor: %x product: %x\n", vendor, product); |
427 | 427 | ||
428 | for (i = 0; i < (sizeof (id_table) / sizeof (struct usb_device_id)); i++) { | 428 | for (i = 0; i < ARRAY_SIZE(id_table); i++) { |
429 | if (!id_table[i].idVendor && !id_table[i].idProduct) { | 429 | if (!id_table[i].idVendor && !id_table[i].idProduct) { |
430 | id_table[i].idVendor = vendor; | 430 | id_table[i].idVendor = vendor; |
431 | id_table[i].idProduct = product; | 431 | id_table[i].idProduct = product; |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 205dbf7201da..abb830cb77bd 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -248,11 +248,11 @@ static struct usb_device_id ti_id_table_combined[] = { | |||
248 | }; | 248 | }; |
249 | 249 | ||
250 | static struct usb_driver ti_usb_driver = { | 250 | static struct usb_driver ti_usb_driver = { |
251 | .owner = THIS_MODULE, | ||
252 | .name = "ti_usb_3410_5052", | 251 | .name = "ti_usb_3410_5052", |
253 | .probe = usb_serial_probe, | 252 | .probe = usb_serial_probe, |
254 | .disconnect = usb_serial_disconnect, | 253 | .disconnect = usb_serial_disconnect, |
255 | .id_table = ti_id_table_combined, | 254 | .id_table = ti_id_table_combined, |
255 | .no_dynamic_id = 1, | ||
256 | }; | 256 | }; |
257 | 257 | ||
258 | static struct usb_serial_driver ti_1port_device = { | 258 | static struct usb_serial_driver ti_1port_device = { |
@@ -351,17 +351,14 @@ static int __init ti_init(void) | |||
351 | int i,j; | 351 | int i,j; |
352 | int ret; | 352 | int ret; |
353 | 353 | ||
354 | |||
355 | /* insert extra vendor and product ids */ | 354 | /* insert extra vendor and product ids */ |
356 | j = sizeof(ti_id_table_3410)/sizeof(struct usb_device_id) | 355 | j = ARRAY_SIZE(ti_id_table_3410) - TI_EXTRA_VID_PID_COUNT - 1; |
357 | - TI_EXTRA_VID_PID_COUNT - 1; | ||
358 | for (i=0; i<min(vendor_3410_count,product_3410_count); i++,j++) { | 356 | for (i=0; i<min(vendor_3410_count,product_3410_count); i++,j++) { |
359 | ti_id_table_3410[j].idVendor = vendor_3410[i]; | 357 | ti_id_table_3410[j].idVendor = vendor_3410[i]; |
360 | ti_id_table_3410[j].idProduct = product_3410[i]; | 358 | ti_id_table_3410[j].idProduct = product_3410[i]; |
361 | ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE; | 359 | ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE; |
362 | } | 360 | } |
363 | j = sizeof(ti_id_table_5052)/sizeof(struct usb_device_id) | 361 | j = ARRAY_SIZE(ti_id_table_5052) - TI_EXTRA_VID_PID_COUNT - 1; |
364 | - TI_EXTRA_VID_PID_COUNT - 1; | ||
365 | for (i=0; i<min(vendor_5052_count,product_5052_count); i++,j++) { | 362 | for (i=0; i<min(vendor_5052_count,product_5052_count); i++,j++) { |
366 | ti_id_table_5052[j].idVendor = vendor_5052[i]; | 363 | ti_id_table_5052[j].idVendor = vendor_5052[i]; |
367 | ti_id_table_5052[j].idProduct = product_5052[i]; | 364 | ti_id_table_5052[j].idProduct = product_5052[i]; |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 0c4881d18cd5..8bc8337c99c4 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/list.h> | 30 | #include <linux/list.h> |
31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
32 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
33 | #include <asm/semaphore.h> | ||
33 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
34 | #include "usb-serial.h" | 35 | #include "usb-serial.h" |
35 | #include "pl2303.h" | 36 | #include "pl2303.h" |
@@ -42,10 +43,10 @@ | |||
42 | 43 | ||
43 | /* Driver structure we register with the USB core */ | 44 | /* Driver structure we register with the USB core */ |
44 | static struct usb_driver usb_serial_driver = { | 45 | static struct usb_driver usb_serial_driver = { |
45 | .owner = THIS_MODULE, | ||
46 | .name = "usbserial", | 46 | .name = "usbserial", |
47 | .probe = usb_serial_probe, | 47 | .probe = usb_serial_probe, |
48 | .disconnect = usb_serial_disconnect, | 48 | .disconnect = usb_serial_disconnect, |
49 | .no_dynamic_id = 1, | ||
49 | }; | 50 | }; |
50 | 51 | ||
51 | /* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead | 52 | /* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead |
@@ -188,6 +189,11 @@ static int serial_open (struct tty_struct *tty, struct file * filp) | |||
188 | 189 | ||
189 | portNumber = tty->index - serial->minor; | 190 | portNumber = tty->index - serial->minor; |
190 | port = serial->port[portNumber]; | 191 | port = serial->port[portNumber]; |
192 | if (!port) | ||
193 | return -ENODEV; | ||
194 | |||
195 | if (down_interruptible(&port->sem)) | ||
196 | return -ERESTARTSYS; | ||
191 | 197 | ||
192 | ++port->open_count; | 198 | ++port->open_count; |
193 | 199 | ||
@@ -213,6 +219,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp) | |||
213 | goto bailout_module_put; | 219 | goto bailout_module_put; |
214 | } | 220 | } |
215 | 221 | ||
222 | up(&port->sem); | ||
216 | return 0; | 223 | return 0; |
217 | 224 | ||
218 | bailout_module_put: | 225 | bailout_module_put: |
@@ -220,6 +227,7 @@ bailout_module_put: | |||
220 | bailout_kref_put: | 227 | bailout_kref_put: |
221 | kref_put(&serial->kref, destroy_serial); | 228 | kref_put(&serial->kref, destroy_serial); |
222 | port->open_count = 0; | 229 | port->open_count = 0; |
230 | up(&port->sem); | ||
223 | return retval; | 231 | return retval; |
224 | } | 232 | } |
225 | 233 | ||
@@ -232,8 +240,10 @@ static void serial_close(struct tty_struct *tty, struct file * filp) | |||
232 | 240 | ||
233 | dbg("%s - port %d", __FUNCTION__, port->number); | 241 | dbg("%s - port %d", __FUNCTION__, port->number); |
234 | 242 | ||
243 | down(&port->sem); | ||
244 | |||
235 | if (port->open_count == 0) | 245 | if (port->open_count == 0) |
236 | return; | 246 | goto out; |
237 | 247 | ||
238 | --port->open_count; | 248 | --port->open_count; |
239 | if (port->open_count == 0) { | 249 | if (port->open_count == 0) { |
@@ -251,6 +261,9 @@ static void serial_close(struct tty_struct *tty, struct file * filp) | |||
251 | } | 261 | } |
252 | 262 | ||
253 | kref_put(&port->serial->kref, destroy_serial); | 263 | kref_put(&port->serial->kref, destroy_serial); |
264 | |||
265 | out: | ||
266 | up(&port->sem); | ||
254 | } | 267 | } |
255 | 268 | ||
256 | static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) | 269 | static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) |
@@ -258,6 +271,9 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int | |||
258 | struct usb_serial_port *port = tty->driver_data; | 271 | struct usb_serial_port *port = tty->driver_data; |
259 | int retval = -EINVAL; | 272 | int retval = -EINVAL; |
260 | 273 | ||
274 | if (!port) | ||
275 | goto exit; | ||
276 | |||
261 | dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); | 277 | dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); |
262 | 278 | ||
263 | if (!port->open_count) { | 279 | if (!port->open_count) { |
@@ -277,6 +293,9 @@ static int serial_write_room (struct tty_struct *tty) | |||
277 | struct usb_serial_port *port = tty->driver_data; | 293 | struct usb_serial_port *port = tty->driver_data; |
278 | int retval = -EINVAL; | 294 | int retval = -EINVAL; |
279 | 295 | ||
296 | if (!port) | ||
297 | goto exit; | ||
298 | |||
280 | dbg("%s - port %d", __FUNCTION__, port->number); | 299 | dbg("%s - port %d", __FUNCTION__, port->number); |
281 | 300 | ||
282 | if (!port->open_count) { | 301 | if (!port->open_count) { |
@@ -296,6 +315,9 @@ static int serial_chars_in_buffer (struct tty_struct *tty) | |||
296 | struct usb_serial_port *port = tty->driver_data; | 315 | struct usb_serial_port *port = tty->driver_data; |
297 | int retval = -EINVAL; | 316 | int retval = -EINVAL; |
298 | 317 | ||
318 | if (!port) | ||
319 | goto exit; | ||
320 | |||
299 | dbg("%s = port %d", __FUNCTION__, port->number); | 321 | dbg("%s = port %d", __FUNCTION__, port->number); |
300 | 322 | ||
301 | if (!port->open_count) { | 323 | if (!port->open_count) { |
@@ -314,6 +336,9 @@ static void serial_throttle (struct tty_struct * tty) | |||
314 | { | 336 | { |
315 | struct usb_serial_port *port = tty->driver_data; | 337 | struct usb_serial_port *port = tty->driver_data; |
316 | 338 | ||
339 | if (!port) | ||
340 | return; | ||
341 | |||
317 | dbg("%s - port %d", __FUNCTION__, port->number); | 342 | dbg("%s - port %d", __FUNCTION__, port->number); |
318 | 343 | ||
319 | if (!port->open_count) { | 344 | if (!port->open_count) { |
@@ -330,6 +355,9 @@ static void serial_unthrottle (struct tty_struct * tty) | |||
330 | { | 355 | { |
331 | struct usb_serial_port *port = tty->driver_data; | 356 | struct usb_serial_port *port = tty->driver_data; |
332 | 357 | ||
358 | if (!port) | ||
359 | return; | ||
360 | |||
333 | dbg("%s - port %d", __FUNCTION__, port->number); | 361 | dbg("%s - port %d", __FUNCTION__, port->number); |
334 | 362 | ||
335 | if (!port->open_count) { | 363 | if (!port->open_count) { |
@@ -347,6 +375,9 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in | |||
347 | struct usb_serial_port *port = tty->driver_data; | 375 | struct usb_serial_port *port = tty->driver_data; |
348 | int retval = -ENODEV; | 376 | int retval = -ENODEV; |
349 | 377 | ||
378 | if (!port) | ||
379 | goto exit; | ||
380 | |||
350 | dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); | 381 | dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); |
351 | 382 | ||
352 | if (!port->open_count) { | 383 | if (!port->open_count) { |
@@ -368,6 +399,9 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old) | |||
368 | { | 399 | { |
369 | struct usb_serial_port *port = tty->driver_data; | 400 | struct usb_serial_port *port = tty->driver_data; |
370 | 401 | ||
402 | if (!port) | ||
403 | return; | ||
404 | |||
371 | dbg("%s - port %d", __FUNCTION__, port->number); | 405 | dbg("%s - port %d", __FUNCTION__, port->number); |
372 | 406 | ||
373 | if (!port->open_count) { | 407 | if (!port->open_count) { |
@@ -384,6 +418,9 @@ static void serial_break (struct tty_struct *tty, int break_state) | |||
384 | { | 418 | { |
385 | struct usb_serial_port *port = tty->driver_data; | 419 | struct usb_serial_port *port = tty->driver_data; |
386 | 420 | ||
421 | if (!port) | ||
422 | return; | ||
423 | |||
387 | dbg("%s - port %d", __FUNCTION__, port->number); | 424 | dbg("%s - port %d", __FUNCTION__, port->number); |
388 | 425 | ||
389 | if (!port->open_count) { | 426 | if (!port->open_count) { |
@@ -445,6 +482,9 @@ static int serial_tiocmget (struct tty_struct *tty, struct file *file) | |||
445 | { | 482 | { |
446 | struct usb_serial_port *port = tty->driver_data; | 483 | struct usb_serial_port *port = tty->driver_data; |
447 | 484 | ||
485 | if (!port) | ||
486 | goto exit; | ||
487 | |||
448 | dbg("%s - port %d", __FUNCTION__, port->number); | 488 | dbg("%s - port %d", __FUNCTION__, port->number); |
449 | 489 | ||
450 | if (!port->open_count) { | 490 | if (!port->open_count) { |
@@ -464,6 +504,9 @@ static int serial_tiocmset (struct tty_struct *tty, struct file *file, | |||
464 | { | 504 | { |
465 | struct usb_serial_port *port = tty->driver_data; | 505 | struct usb_serial_port *port = tty->driver_data; |
466 | 506 | ||
507 | if (!port) | ||
508 | goto exit; | ||
509 | |||
467 | dbg("%s - port %d", __FUNCTION__, port->number); | 510 | dbg("%s - port %d", __FUNCTION__, port->number); |
468 | 511 | ||
469 | if (!port->open_count) { | 512 | if (!port->open_count) { |
@@ -742,6 +785,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
742 | port->number = i + serial->minor; | 785 | port->number = i + serial->minor; |
743 | port->serial = serial; | 786 | port->serial = serial; |
744 | spin_lock_init(&port->lock); | 787 | spin_lock_init(&port->lock); |
788 | sema_init(&port->sem, 1); | ||
745 | INIT_WORK(&port->work, usb_serial_port_softint, port); | 789 | INIT_WORK(&port->work, usb_serial_port_softint, port); |
746 | serial->port[i] = port; | 790 | serial->port[i] = port; |
747 | } | 791 | } |
diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index 238a5a871ed6..d7d27c3385b3 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/config.h> | 17 | #include <linux/config.h> |
18 | #include <linux/kref.h> | 18 | #include <linux/kref.h> |
19 | #include <asm/semaphore.h> | ||
19 | 20 | ||
20 | #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ | 21 | #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ |
21 | #define SERIAL_TTY_MINORS 255 /* loads of devices :) */ | 22 | #define SERIAL_TTY_MINORS 255 /* loads of devices :) */ |
@@ -30,6 +31,8 @@ | |||
30 | * @serial: pointer back to the struct usb_serial owner of this port. | 31 | * @serial: pointer back to the struct usb_serial owner of this port. |
31 | * @tty: pointer to the corresponding tty for this port. | 32 | * @tty: pointer to the corresponding tty for this port. |
32 | * @lock: spinlock to grab when updating portions of this structure. | 33 | * @lock: spinlock to grab when updating portions of this structure. |
34 | * @sem: semaphore used to synchronize serial_open() and serial_close() | ||
35 | * access for this port. | ||
33 | * @number: the number of the port (the minor number). | 36 | * @number: the number of the port (the minor number). |
34 | * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. | 37 | * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. |
35 | * @interrupt_in_urb: pointer to the interrupt in struct urb for this port. | 38 | * @interrupt_in_urb: pointer to the interrupt in struct urb for this port. |
@@ -60,6 +63,7 @@ struct usb_serial_port { | |||
60 | struct usb_serial * serial; | 63 | struct usb_serial * serial; |
61 | struct tty_struct * tty; | 64 | struct tty_struct * tty; |
62 | spinlock_t lock; | 65 | spinlock_t lock; |
66 | struct semaphore sem; | ||
63 | unsigned char number; | 67 | unsigned char number; |
64 | 68 | ||
65 | unsigned char * interrupt_in_buffer; | 69 | unsigned char * interrupt_in_buffer; |
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index a473c1c34559..49b1fbe61f25 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -173,11 +173,11 @@ static struct usb_device_id id_table_combined [] = { | |||
173 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 173 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
174 | 174 | ||
175 | static struct usb_driver visor_driver = { | 175 | static struct usb_driver visor_driver = { |
176 | .owner = THIS_MODULE, | ||
177 | .name = "visor", | 176 | .name = "visor", |
178 | .probe = usb_serial_probe, | 177 | .probe = usb_serial_probe, |
179 | .disconnect = usb_serial_disconnect, | 178 | .disconnect = usb_serial_disconnect, |
180 | .id_table = id_table_combined, | 179 | .id_table = id_table_combined, |
180 | .no_dynamic_id = 1, | ||
181 | }; | 181 | }; |
182 | 182 | ||
183 | /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */ | 183 | /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */ |
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 18c3183be769..a7c3c4734d83 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -127,11 +127,11 @@ static struct usb_device_id id_table_combined [] = { | |||
127 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 127 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
128 | 128 | ||
129 | static struct usb_driver whiteheat_driver = { | 129 | static struct usb_driver whiteheat_driver = { |
130 | .owner = THIS_MODULE, | ||
131 | .name = "whiteheat", | 130 | .name = "whiteheat", |
132 | .probe = usb_serial_probe, | 131 | .probe = usb_serial_probe, |
133 | .disconnect = usb_serial_disconnect, | 132 | .disconnect = usb_serial_disconnect, |
134 | .id_table = id_table_combined, | 133 | .id_table = id_table_combined, |
134 | .no_dynamic_id = 1, | ||
135 | }; | 135 | }; |
136 | 136 | ||
137 | /* function prototypes for the Connect Tech WhiteHEAT prerenumeration device */ | 137 | /* function prototypes for the Connect Tech WhiteHEAT prerenumeration device */ |
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index c41d64dbb0f0..92be101feba7 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
@@ -112,6 +112,15 @@ config USB_STORAGE_JUMPSHOT | |||
112 | Say Y here to include additional code to support the Lexar Jumpshot | 112 | Say Y here to include additional code to support the Lexar Jumpshot |
113 | USB CompactFlash reader. | 113 | USB CompactFlash reader. |
114 | 114 | ||
115 | config USB_STORAGE_ALAUDA | ||
116 | bool "Olympus MAUSB-10/Fuji DPC-R1 support (EXPERIMENTAL)" | ||
117 | depends on USB_STORAGE && EXPERIMENTAL | ||
118 | help | ||
119 | Say Y here to include additional code to support the Olympus MAUSB-10 | ||
120 | and Fujifilm DPC-R1 USB Card reader/writer devices. | ||
121 | |||
122 | These devices are based on the Alauda chip and support support both | ||
123 | XD and SmartMedia cards. | ||
115 | 124 | ||
116 | config USB_STORAGE_ONETOUCH | 125 | config USB_STORAGE_ONETOUCH |
117 | bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)" | 126 | bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)" |
@@ -124,3 +133,17 @@ config USB_STORAGE_ONETOUCH | |||
124 | hard drive's as an input device. An action can be associated with | 133 | hard drive's as an input device. An action can be associated with |
125 | this input in any keybinding software. (e.g. gnome's keyboard short- | 134 | this input in any keybinding software. (e.g. gnome's keyboard short- |
126 | cuts) | 135 | cuts) |
136 | |||
137 | config USB_LIBUSUAL | ||
138 | bool "The shared table of common (or usual) storage devices" | ||
139 | depends on USB | ||
140 | help | ||
141 | This module contains a table of common (or usual) devices | ||
142 | for usb-storage and ub drivers, and allows to switch binding | ||
143 | of these devices without rebuilding modules. | ||
144 | |||
145 | Typical syntax of /etc/modprobe.conf is: | ||
146 | |||
147 | options libusual bias="ub" | ||
148 | |||
149 | If unsure, say N. | ||
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index 44ab8f9978fe..8cbba22508a4 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile | |||
@@ -18,7 +18,12 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM) += dpcm.o | |||
18 | usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o | 18 | usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o |
19 | usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o | 19 | usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o |
20 | usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o | 20 | usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o |
21 | usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o | ||
21 | usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o | 22 | usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o |
22 | 23 | ||
23 | usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ | 24 | usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ |
24 | initializers.o $(usb-storage-obj-y) | 25 | initializers.o $(usb-storage-obj-y) |
26 | |||
27 | ifneq ($(CONFIG_USB_LIBUSUAL),) | ||
28 | obj-$(CONFIG_USB) += libusual.o | ||
29 | endif | ||
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c new file mode 100644 index 000000000000..4d3cbb12b713 --- /dev/null +++ b/drivers/usb/storage/alauda.c | |||
@@ -0,0 +1,1119 @@ | |||
1 | /* | ||
2 | * Driver for Alauda-based card readers | ||
3 | * | ||
4 | * Current development and maintenance by: | ||
5 | * (c) 2005 Daniel Drake <dsd@gentoo.org> | ||
6 | * | ||
7 | * The 'Alauda' is a chip manufacturered by RATOC for OEM use. | ||
8 | * | ||
9 | * Alauda implements a vendor-specific command set to access two media reader | ||
10 | * ports (XD, SmartMedia). This driver converts SCSI commands to the commands | ||
11 | * which are accepted by these devices. | ||
12 | * | ||
13 | * The driver was developed through reverse-engineering, with the help of the | ||
14 | * sddr09 driver which has many similarities, and with some help from the | ||
15 | * (very old) vendor-supplied GPL sma03 driver. | ||
16 | * | ||
17 | * For protocol info, see http://alauda.sourceforge.net | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or modify it | ||
20 | * under the terms of the GNU General Public License as published by the | ||
21 | * Free Software Foundation; either version 2, or (at your option) any | ||
22 | * later version. | ||
23 | * | ||
24 | * This program is distributed in the hope that it will be useful, but | ||
25 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
27 | * General Public License for more details. | ||
28 | * | ||
29 | * You should have received a copy of the GNU General Public License along | ||
30 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
31 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
32 | */ | ||
33 | |||
34 | #include <scsi/scsi.h> | ||
35 | #include <scsi/scsi_cmnd.h> | ||
36 | #include <scsi/scsi_device.h> | ||
37 | |||
38 | #include "usb.h" | ||
39 | #include "transport.h" | ||
40 | #include "protocol.h" | ||
41 | #include "debug.h" | ||
42 | #include "alauda.h" | ||
43 | |||
44 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) | ||
45 | #define LSB_of(s) ((s)&0xFF) | ||
46 | #define MSB_of(s) ((s)>>8) | ||
47 | |||
48 | #define MEDIA_PORT(us) us->srb->device->lun | ||
49 | #define MEDIA_INFO(us) ((struct alauda_info *)us->extra)->port[MEDIA_PORT(us)] | ||
50 | |||
51 | #define PBA_LO(pba) ((pba & 0xF) << 5) | ||
52 | #define PBA_HI(pba) (pba >> 3) | ||
53 | #define PBA_ZONE(pba) (pba >> 11) | ||
54 | |||
55 | /* | ||
56 | * Media handling | ||
57 | */ | ||
58 | |||
59 | struct alauda_card_info { | ||
60 | unsigned char id; /* id byte */ | ||
61 | unsigned char chipshift; /* 1<<cs bytes total capacity */ | ||
62 | unsigned char pageshift; /* 1<<ps bytes in a page */ | ||
63 | unsigned char blockshift; /* 1<<bs pages per block */ | ||
64 | unsigned char zoneshift; /* 1<<zs blocks per zone */ | ||
65 | }; | ||
66 | |||
67 | static struct alauda_card_info alauda_card_ids[] = { | ||
68 | /* NAND flash */ | ||
69 | { 0x6e, 20, 8, 4, 8}, /* 1 MB */ | ||
70 | { 0xe8, 20, 8, 4, 8}, /* 1 MB */ | ||
71 | { 0xec, 20, 8, 4, 8}, /* 1 MB */ | ||
72 | { 0x64, 21, 8, 4, 9}, /* 2 MB */ | ||
73 | { 0xea, 21, 8, 4, 9}, /* 2 MB */ | ||
74 | { 0x6b, 22, 9, 4, 9}, /* 4 MB */ | ||
75 | { 0xe3, 22, 9, 4, 9}, /* 4 MB */ | ||
76 | { 0xe5, 22, 9, 4, 9}, /* 4 MB */ | ||
77 | { 0xe6, 23, 9, 4, 10}, /* 8 MB */ | ||
78 | { 0x73, 24, 9, 5, 10}, /* 16 MB */ | ||
79 | { 0x75, 25, 9, 5, 10}, /* 32 MB */ | ||
80 | { 0x76, 26, 9, 5, 10}, /* 64 MB */ | ||
81 | { 0x79, 27, 9, 5, 10}, /* 128 MB */ | ||
82 | { 0x71, 28, 9, 5, 10}, /* 256 MB */ | ||
83 | |||
84 | /* MASK ROM */ | ||
85 | { 0x5d, 21, 9, 4, 8}, /* 2 MB */ | ||
86 | { 0xd5, 22, 9, 4, 9}, /* 4 MB */ | ||
87 | { 0xd6, 23, 9, 4, 10}, /* 8 MB */ | ||
88 | { 0x57, 24, 9, 4, 11}, /* 16 MB */ | ||
89 | { 0x58, 25, 9, 4, 12}, /* 32 MB */ | ||
90 | { 0,} | ||
91 | }; | ||
92 | |||
93 | static struct alauda_card_info *alauda_card_find_id(unsigned char id) { | ||
94 | int i; | ||
95 | |||
96 | for (i = 0; alauda_card_ids[i].id != 0; i++) | ||
97 | if (alauda_card_ids[i].id == id) | ||
98 | return &(alauda_card_ids[i]); | ||
99 | return NULL; | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * ECC computation. | ||
104 | */ | ||
105 | |||
106 | static unsigned char parity[256]; | ||
107 | static unsigned char ecc2[256]; | ||
108 | |||
109 | static void nand_init_ecc(void) { | ||
110 | int i, j, a; | ||
111 | |||
112 | parity[0] = 0; | ||
113 | for (i = 1; i < 256; i++) | ||
114 | parity[i] = (parity[i&(i-1)] ^ 1); | ||
115 | |||
116 | for (i = 0; i < 256; i++) { | ||
117 | a = 0; | ||
118 | for (j = 0; j < 8; j++) { | ||
119 | if (i & (1<<j)) { | ||
120 | if ((j & 1) == 0) | ||
121 | a ^= 0x04; | ||
122 | if ((j & 2) == 0) | ||
123 | a ^= 0x10; | ||
124 | if ((j & 4) == 0) | ||
125 | a ^= 0x40; | ||
126 | } | ||
127 | } | ||
128 | ecc2[i] = ~(a ^ (a<<1) ^ (parity[i] ? 0xa8 : 0)); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | /* compute 3-byte ecc on 256 bytes */ | ||
133 | static void nand_compute_ecc(unsigned char *data, unsigned char *ecc) { | ||
134 | int i, j, a; | ||
135 | unsigned char par, bit, bits[8]; | ||
136 | |||
137 | par = 0; | ||
138 | for (j = 0; j < 8; j++) | ||
139 | bits[j] = 0; | ||
140 | |||
141 | /* collect 16 checksum bits */ | ||
142 | for (i = 0; i < 256; i++) { | ||
143 | par ^= data[i]; | ||
144 | bit = parity[data[i]]; | ||
145 | for (j = 0; j < 8; j++) | ||
146 | if ((i & (1<<j)) == 0) | ||
147 | bits[j] ^= bit; | ||
148 | } | ||
149 | |||
150 | /* put 4+4+4 = 12 bits in the ecc */ | ||
151 | a = (bits[3] << 6) + (bits[2] << 4) + (bits[1] << 2) + bits[0]; | ||
152 | ecc[0] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0)); | ||
153 | |||
154 | a = (bits[7] << 6) + (bits[6] << 4) + (bits[5] << 2) + bits[4]; | ||
155 | ecc[1] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0)); | ||
156 | |||
157 | ecc[2] = ecc2[par]; | ||
158 | } | ||
159 | |||
160 | static int nand_compare_ecc(unsigned char *data, unsigned char *ecc) { | ||
161 | return (data[0] == ecc[0] && data[1] == ecc[1] && data[2] == ecc[2]); | ||
162 | } | ||
163 | |||
164 | static void nand_store_ecc(unsigned char *data, unsigned char *ecc) { | ||
165 | memcpy(data, ecc, 3); | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * Alauda driver | ||
170 | */ | ||
171 | |||
172 | /* | ||
173 | * Forget our PBA <---> LBA mappings for a particular port | ||
174 | */ | ||
175 | static void alauda_free_maps (struct alauda_media_info *media_info) | ||
176 | { | ||
177 | unsigned int shift = media_info->zoneshift | ||
178 | + media_info->blockshift + media_info->pageshift; | ||
179 | unsigned int num_zones = media_info->capacity >> shift; | ||
180 | unsigned int i; | ||
181 | |||
182 | if (media_info->lba_to_pba != NULL) | ||
183 | for (i = 0; i < num_zones; i++) { | ||
184 | kfree(media_info->lba_to_pba[i]); | ||
185 | media_info->lba_to_pba[i] = NULL; | ||
186 | } | ||
187 | |||
188 | if (media_info->pba_to_lba != NULL) | ||
189 | for (i = 0; i < num_zones; i++) { | ||
190 | kfree(media_info->pba_to_lba[i]); | ||
191 | media_info->pba_to_lba[i] = NULL; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * Returns 2 bytes of status data | ||
197 | * The first byte describes media status, and second byte describes door status | ||
198 | */ | ||
199 | static int alauda_get_media_status(struct us_data *us, unsigned char *data) | ||
200 | { | ||
201 | int rc; | ||
202 | unsigned char command; | ||
203 | |||
204 | if (MEDIA_PORT(us) == ALAUDA_PORT_XD) | ||
205 | command = ALAUDA_GET_XD_MEDIA_STATUS; | ||
206 | else | ||
207 | command = ALAUDA_GET_SM_MEDIA_STATUS; | ||
208 | |||
209 | rc = usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe, | ||
210 | command, 0xc0, 0, 1, data, 2); | ||
211 | |||
212 | US_DEBUGP("alauda_get_media_status: Media status %02X %02X\n", | ||
213 | data[0], data[1]); | ||
214 | |||
215 | return rc; | ||
216 | } | ||
217 | |||
218 | /* | ||
219 | * Clears the "media was changed" bit so that we know when it changes again | ||
220 | * in the future. | ||
221 | */ | ||
222 | static int alauda_ack_media(struct us_data *us) | ||
223 | { | ||
224 | unsigned char command; | ||
225 | |||
226 | if (MEDIA_PORT(us) == ALAUDA_PORT_XD) | ||
227 | command = ALAUDA_ACK_XD_MEDIA_CHANGE; | ||
228 | else | ||
229 | command = ALAUDA_ACK_SM_MEDIA_CHANGE; | ||
230 | |||
231 | return usb_stor_ctrl_transfer(us, us->send_ctrl_pipe, | ||
232 | command, 0x40, 0, 1, NULL, 0); | ||
233 | } | ||
234 | |||
235 | /* | ||
236 | * Retrieves a 4-byte media signature, which indicates manufacturer, capacity, | ||
237 | * and some other details. | ||
238 | */ | ||
239 | static int alauda_get_media_signature(struct us_data *us, unsigned char *data) | ||
240 | { | ||
241 | unsigned char command; | ||
242 | |||
243 | if (MEDIA_PORT(us) == ALAUDA_PORT_XD) | ||
244 | command = ALAUDA_GET_XD_MEDIA_SIG; | ||
245 | else | ||
246 | command = ALAUDA_GET_SM_MEDIA_SIG; | ||
247 | |||
248 | return usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe, | ||
249 | command, 0xc0, 0, 0, data, 4); | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * Resets the media status (but not the whole device?) | ||
254 | */ | ||
255 | static int alauda_reset_media(struct us_data *us) | ||
256 | { | ||
257 | unsigned char *command = us->iobuf; | ||
258 | |||
259 | memset(command, 0, 9); | ||
260 | command[0] = ALAUDA_BULK_CMD; | ||
261 | command[1] = ALAUDA_BULK_RESET_MEDIA; | ||
262 | command[8] = MEDIA_PORT(us); | ||
263 | |||
264 | return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
265 | command, 9, NULL); | ||
266 | } | ||
267 | |||
268 | /* | ||
269 | * Examines the media and deduces capacity, etc. | ||
270 | */ | ||
271 | static int alauda_init_media(struct us_data *us) | ||
272 | { | ||
273 | unsigned char *data = us->iobuf; | ||
274 | int ready = 0; | ||
275 | struct alauda_card_info *media_info; | ||
276 | unsigned int num_zones; | ||
277 | |||
278 | while (ready == 0) { | ||
279 | msleep(20); | ||
280 | |||
281 | if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD) | ||
282 | return USB_STOR_TRANSPORT_ERROR; | ||
283 | |||
284 | if (data[0] & 0x10) | ||
285 | ready = 1; | ||
286 | } | ||
287 | |||
288 | US_DEBUGP("alauda_init_media: We are ready for action!\n"); | ||
289 | |||
290 | if (alauda_ack_media(us) != USB_STOR_XFER_GOOD) | ||
291 | return USB_STOR_TRANSPORT_ERROR; | ||
292 | |||
293 | msleep(10); | ||
294 | |||
295 | if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD) | ||
296 | return USB_STOR_TRANSPORT_ERROR; | ||
297 | |||
298 | if (data[0] != 0x14) { | ||
299 | US_DEBUGP("alauda_init_media: Media not ready after ack\n"); | ||
300 | return USB_STOR_TRANSPORT_ERROR; | ||
301 | } | ||
302 | |||
303 | if (alauda_get_media_signature(us, data) != USB_STOR_XFER_GOOD) | ||
304 | return USB_STOR_TRANSPORT_ERROR; | ||
305 | |||
306 | US_DEBUGP("alauda_init_media: Media signature: %02X %02X %02X %02X\n", | ||
307 | data[0], data[1], data[2], data[3]); | ||
308 | media_info = alauda_card_find_id(data[1]); | ||
309 | if (media_info == NULL) { | ||
310 | printk("alauda_init_media: Unrecognised media signature: " | ||
311 | "%02X %02X %02X %02X\n", | ||
312 | data[0], data[1], data[2], data[3]); | ||
313 | return USB_STOR_TRANSPORT_ERROR; | ||
314 | } | ||
315 | |||
316 | MEDIA_INFO(us).capacity = 1 << media_info->chipshift; | ||
317 | US_DEBUGP("Found media with capacity: %ldMB\n", | ||
318 | MEDIA_INFO(us).capacity >> 20); | ||
319 | |||
320 | MEDIA_INFO(us).pageshift = media_info->pageshift; | ||
321 | MEDIA_INFO(us).blockshift = media_info->blockshift; | ||
322 | MEDIA_INFO(us).zoneshift = media_info->zoneshift; | ||
323 | |||
324 | MEDIA_INFO(us).pagesize = 1 << media_info->pageshift; | ||
325 | MEDIA_INFO(us).blocksize = 1 << media_info->blockshift; | ||
326 | MEDIA_INFO(us).zonesize = 1 << media_info->zoneshift; | ||
327 | |||
328 | MEDIA_INFO(us).uzonesize = ((1 << media_info->zoneshift) / 128) * 125; | ||
329 | MEDIA_INFO(us).blockmask = MEDIA_INFO(us).blocksize - 1; | ||
330 | |||
331 | num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift | ||
332 | + MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift); | ||
333 | MEDIA_INFO(us).pba_to_lba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO); | ||
334 | MEDIA_INFO(us).lba_to_pba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO); | ||
335 | |||
336 | if (alauda_reset_media(us) != USB_STOR_XFER_GOOD) | ||
337 | return USB_STOR_TRANSPORT_ERROR; | ||
338 | |||
339 | return USB_STOR_TRANSPORT_GOOD; | ||
340 | } | ||
341 | |||
342 | /* | ||
343 | * Examines the media status and does the right thing when the media has gone, | ||
344 | * appeared, or changed. | ||
345 | */ | ||
346 | static int alauda_check_media(struct us_data *us) | ||
347 | { | ||
348 | struct alauda_info *info = (struct alauda_info *) us->extra; | ||
349 | unsigned char status[2]; | ||
350 | int rc; | ||
351 | |||
352 | rc = alauda_get_media_status(us, status); | ||
353 | |||
354 | /* Check for no media or door open */ | ||
355 | if ((status[0] & 0x80) || ((status[0] & 0x1F) == 0x10) | ||
356 | || ((status[1] & 0x01) == 0)) { | ||
357 | US_DEBUGP("alauda_check_media: No media, or door open\n"); | ||
358 | alauda_free_maps(&MEDIA_INFO(us)); | ||
359 | info->sense_key = 0x02; | ||
360 | info->sense_asc = 0x3A; | ||
361 | info->sense_ascq = 0x00; | ||
362 | return USB_STOR_TRANSPORT_FAILED; | ||
363 | } | ||
364 | |||
365 | /* Check for media change */ | ||
366 | if (status[0] & 0x08) { | ||
367 | US_DEBUGP("alauda_check_media: Media change detected\n"); | ||
368 | alauda_free_maps(&MEDIA_INFO(us)); | ||
369 | alauda_init_media(us); | ||
370 | |||
371 | info->sense_key = UNIT_ATTENTION; | ||
372 | info->sense_asc = 0x28; | ||
373 | info->sense_ascq = 0x00; | ||
374 | return USB_STOR_TRANSPORT_FAILED; | ||
375 | } | ||
376 | |||
377 | return USB_STOR_TRANSPORT_GOOD; | ||
378 | } | ||
379 | |||
380 | /* | ||
381 | * Checks the status from the 2nd status register | ||
382 | * Returns 3 bytes of status data, only the first is known | ||
383 | */ | ||
384 | static int alauda_check_status2(struct us_data *us) | ||
385 | { | ||
386 | int rc; | ||
387 | unsigned char command[] = { | ||
388 | ALAUDA_BULK_CMD, ALAUDA_BULK_GET_STATUS2, | ||
389 | 0, 0, 0, 0, 3, 0, MEDIA_PORT(us) | ||
390 | }; | ||
391 | unsigned char data[3]; | ||
392 | |||
393 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
394 | command, 9, NULL); | ||
395 | if (rc != USB_STOR_XFER_GOOD) | ||
396 | return rc; | ||
397 | |||
398 | rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | ||
399 | data, 3, NULL); | ||
400 | if (rc != USB_STOR_XFER_GOOD) | ||
401 | return rc; | ||
402 | |||
403 | US_DEBUGP("alauda_check_status2: %02X %02X %02X\n", data[0], data[1], data[2]); | ||
404 | if (data[0] & ALAUDA_STATUS_ERROR) | ||
405 | return USB_STOR_XFER_ERROR; | ||
406 | |||
407 | return USB_STOR_XFER_GOOD; | ||
408 | } | ||
409 | |||
410 | /* | ||
411 | * Gets the redundancy data for the first page of a PBA | ||
412 | * Returns 16 bytes. | ||
413 | */ | ||
414 | static int alauda_get_redu_data(struct us_data *us, u16 pba, unsigned char *data) | ||
415 | { | ||
416 | int rc; | ||
417 | unsigned char command[] = { | ||
418 | ALAUDA_BULK_CMD, ALAUDA_BULK_GET_REDU_DATA, | ||
419 | PBA_HI(pba), PBA_ZONE(pba), 0, PBA_LO(pba), 0, 0, MEDIA_PORT(us) | ||
420 | }; | ||
421 | |||
422 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
423 | command, 9, NULL); | ||
424 | if (rc != USB_STOR_XFER_GOOD) | ||
425 | return rc; | ||
426 | |||
427 | return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | ||
428 | data, 16, NULL); | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * Finds the first unused PBA in a zone | ||
433 | * Returns the absolute PBA of an unused PBA, or 0 if none found. | ||
434 | */ | ||
435 | static u16 alauda_find_unused_pba(struct alauda_media_info *info, | ||
436 | unsigned int zone) | ||
437 | { | ||
438 | u16 *pba_to_lba = info->pba_to_lba[zone]; | ||
439 | unsigned int i; | ||
440 | |||
441 | for (i = 0; i < info->zonesize; i++) | ||
442 | if (pba_to_lba[i] == UNDEF) | ||
443 | return (zone << info->zoneshift) + i; | ||
444 | |||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | /* | ||
449 | * Reads the redundancy data for all PBA's in a zone | ||
450 | * Produces lba <--> pba mappings | ||
451 | */ | ||
452 | static int alauda_read_map(struct us_data *us, unsigned int zone) | ||
453 | { | ||
454 | unsigned char *data = us->iobuf; | ||
455 | int result; | ||
456 | int i, j; | ||
457 | unsigned int zonesize = MEDIA_INFO(us).zonesize; | ||
458 | unsigned int uzonesize = MEDIA_INFO(us).uzonesize; | ||
459 | unsigned int lba_offset, lba_real, blocknum; | ||
460 | unsigned int zone_base_lba = zone * uzonesize; | ||
461 | unsigned int zone_base_pba = zone * zonesize; | ||
462 | u16 *lba_to_pba = kcalloc(zonesize, sizeof(u16), GFP_NOIO); | ||
463 | u16 *pba_to_lba = kcalloc(zonesize, sizeof(u16), GFP_NOIO); | ||
464 | if (lba_to_pba == NULL || pba_to_lba == NULL) { | ||
465 | result = USB_STOR_TRANSPORT_ERROR; | ||
466 | goto error; | ||
467 | } | ||
468 | |||
469 | US_DEBUGP("alauda_read_map: Mapping blocks for zone %d\n", zone); | ||
470 | |||
471 | /* 1024 PBA's per zone */ | ||
472 | for (i = 0; i < zonesize; i++) | ||
473 | lba_to_pba[i] = pba_to_lba[i] = UNDEF; | ||
474 | |||
475 | for (i = 0; i < zonesize; i++) { | ||
476 | blocknum = zone_base_pba + i; | ||
477 | |||
478 | result = alauda_get_redu_data(us, blocknum, data); | ||
479 | if (result != USB_STOR_XFER_GOOD) { | ||
480 | result = USB_STOR_TRANSPORT_ERROR; | ||
481 | goto error; | ||
482 | } | ||
483 | |||
484 | /* special PBAs have control field 0^16 */ | ||
485 | for (j = 0; j < 16; j++) | ||
486 | if (data[j] != 0) | ||
487 | goto nonz; | ||
488 | pba_to_lba[i] = UNUSABLE; | ||
489 | US_DEBUGP("alauda_read_map: PBA %d has no logical mapping\n", blocknum); | ||
490 | continue; | ||
491 | |||
492 | nonz: | ||
493 | /* unwritten PBAs have control field FF^16 */ | ||
494 | for (j = 0; j < 16; j++) | ||
495 | if (data[j] != 0xff) | ||
496 | goto nonff; | ||
497 | continue; | ||
498 | |||
499 | nonff: | ||
500 | /* normal PBAs start with six FFs */ | ||
501 | if (j < 6) { | ||
502 | US_DEBUGP("alauda_read_map: PBA %d has no logical mapping: " | ||
503 | "reserved area = %02X%02X%02X%02X " | ||
504 | "data status %02X block status %02X\n", | ||
505 | blocknum, data[0], data[1], data[2], data[3], | ||
506 | data[4], data[5]); | ||
507 | pba_to_lba[i] = UNUSABLE; | ||
508 | continue; | ||
509 | } | ||
510 | |||
511 | if ((data[6] >> 4) != 0x01) { | ||
512 | US_DEBUGP("alauda_read_map: PBA %d has invalid address " | ||
513 | "field %02X%02X/%02X%02X\n", | ||
514 | blocknum, data[6], data[7], data[11], data[12]); | ||
515 | pba_to_lba[i] = UNUSABLE; | ||
516 | continue; | ||
517 | } | ||
518 | |||
519 | /* check even parity */ | ||
520 | if (parity[data[6] ^ data[7]]) { | ||
521 | printk("alauda_read_map: Bad parity in LBA for block %d" | ||
522 | " (%02X %02X)\n", i, data[6], data[7]); | ||
523 | pba_to_lba[i] = UNUSABLE; | ||
524 | continue; | ||
525 | } | ||
526 | |||
527 | lba_offset = short_pack(data[7], data[6]); | ||
528 | lba_offset = (lba_offset & 0x07FF) >> 1; | ||
529 | lba_real = lba_offset + zone_base_lba; | ||
530 | |||
531 | /* | ||
532 | * Every 1024 physical blocks ("zone"), the LBA numbers | ||
533 | * go back to zero, but are within a higher block of LBA's. | ||
534 | * Also, there is a maximum of 1000 LBA's per zone. | ||
535 | * In other words, in PBA 1024-2047 you will find LBA 0-999 | ||
536 | * which are really LBA 1000-1999. This allows for 24 bad | ||
537 | * or special physical blocks per zone. | ||
538 | */ | ||
539 | |||
540 | if (lba_offset >= uzonesize) { | ||
541 | printk("alauda_read_map: Bad low LBA %d for block %d\n", | ||
542 | lba_real, blocknum); | ||
543 | continue; | ||
544 | } | ||
545 | |||
546 | if (lba_to_pba[lba_offset] != UNDEF) { | ||
547 | printk("alauda_read_map: LBA %d seen for PBA %d and %d\n", | ||
548 | lba_real, lba_to_pba[lba_offset], blocknum); | ||
549 | continue; | ||
550 | } | ||
551 | |||
552 | pba_to_lba[i] = lba_real; | ||
553 | lba_to_pba[lba_offset] = blocknum; | ||
554 | continue; | ||
555 | } | ||
556 | |||
557 | MEDIA_INFO(us).lba_to_pba[zone] = lba_to_pba; | ||
558 | MEDIA_INFO(us).pba_to_lba[zone] = pba_to_lba; | ||
559 | result = 0; | ||
560 | goto out; | ||
561 | |||
562 | error: | ||
563 | kfree(lba_to_pba); | ||
564 | kfree(pba_to_lba); | ||
565 | out: | ||
566 | return result; | ||
567 | } | ||
568 | |||
569 | /* | ||
570 | * Checks to see whether we have already mapped a certain zone | ||
571 | * If we haven't, the map is generated | ||
572 | */ | ||
573 | static void alauda_ensure_map_for_zone(struct us_data *us, unsigned int zone) | ||
574 | { | ||
575 | if (MEDIA_INFO(us).lba_to_pba[zone] == NULL | ||
576 | || MEDIA_INFO(us).pba_to_lba[zone] == NULL) | ||
577 | alauda_read_map(us, zone); | ||
578 | } | ||
579 | |||
580 | /* | ||
581 | * Erases an entire block | ||
582 | */ | ||
583 | static int alauda_erase_block(struct us_data *us, u16 pba) | ||
584 | { | ||
585 | int rc; | ||
586 | unsigned char command[] = { | ||
587 | ALAUDA_BULK_CMD, ALAUDA_BULK_ERASE_BLOCK, PBA_HI(pba), | ||
588 | PBA_ZONE(pba), 0, PBA_LO(pba), 0x02, 0, MEDIA_PORT(us) | ||
589 | }; | ||
590 | unsigned char buf[2]; | ||
591 | |||
592 | US_DEBUGP("alauda_erase_block: Erasing PBA %d\n", pba); | ||
593 | |||
594 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
595 | command, 9, NULL); | ||
596 | if (rc != USB_STOR_XFER_GOOD) | ||
597 | return rc; | ||
598 | |||
599 | rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | ||
600 | buf, 2, NULL); | ||
601 | if (rc != USB_STOR_XFER_GOOD) | ||
602 | return rc; | ||
603 | |||
604 | US_DEBUGP("alauda_erase_block: Erase result: %02X %02X\n", | ||
605 | buf[0], buf[1]); | ||
606 | return rc; | ||
607 | } | ||
608 | |||
609 | /* | ||
610 | * Reads data from a certain offset page inside a PBA, including interleaved | ||
611 | * redundancy data. Returns (pagesize+64)*pages bytes in data. | ||
612 | */ | ||
613 | static int alauda_read_block_raw(struct us_data *us, u16 pba, | ||
614 | unsigned int page, unsigned int pages, unsigned char *data) | ||
615 | { | ||
616 | int rc; | ||
617 | unsigned char command[] = { | ||
618 | ALAUDA_BULK_CMD, ALAUDA_BULK_READ_BLOCK, PBA_HI(pba), | ||
619 | PBA_ZONE(pba), 0, PBA_LO(pba) + page, pages, 0, MEDIA_PORT(us) | ||
620 | }; | ||
621 | |||
622 | US_DEBUGP("alauda_read_block: pba %d page %d count %d\n", | ||
623 | pba, page, pages); | ||
624 | |||
625 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
626 | command, 9, NULL); | ||
627 | if (rc != USB_STOR_XFER_GOOD) | ||
628 | return rc; | ||
629 | |||
630 | return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | ||
631 | data, (MEDIA_INFO(us).pagesize + 64) * pages, NULL); | ||
632 | } | ||
633 | |||
634 | /* | ||
635 | * Reads data from a certain offset page inside a PBA, excluding redundancy | ||
636 | * data. Returns pagesize*pages bytes in data. Note that data must be big enough | ||
637 | * to hold (pagesize+64)*pages bytes of data, but you can ignore those 'extra' | ||
638 | * trailing bytes outside this function. | ||
639 | */ | ||
640 | static int alauda_read_block(struct us_data *us, u16 pba, | ||
641 | unsigned int page, unsigned int pages, unsigned char *data) | ||
642 | { | ||
643 | int i, rc; | ||
644 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | ||
645 | |||
646 | rc = alauda_read_block_raw(us, pba, page, pages, data); | ||
647 | if (rc != USB_STOR_XFER_GOOD) | ||
648 | return rc; | ||
649 | |||
650 | /* Cut out the redundancy data */ | ||
651 | for (i = 0; i < pages; i++) { | ||
652 | int dest_offset = i * pagesize; | ||
653 | int src_offset = i * (pagesize + 64); | ||
654 | memmove(data + dest_offset, data + src_offset, pagesize); | ||
655 | } | ||
656 | |||
657 | return rc; | ||
658 | } | ||
659 | |||
660 | /* | ||
661 | * Writes an entire block of data and checks status after write. | ||
662 | * Redundancy data must be already included in data. Data should be | ||
663 | * (pagesize+64)*blocksize bytes in length. | ||
664 | */ | ||
665 | static int alauda_write_block(struct us_data *us, u16 pba, unsigned char *data) | ||
666 | { | ||
667 | int rc; | ||
668 | struct alauda_info *info = (struct alauda_info *) us->extra; | ||
669 | unsigned char command[] = { | ||
670 | ALAUDA_BULK_CMD, ALAUDA_BULK_WRITE_BLOCK, PBA_HI(pba), | ||
671 | PBA_ZONE(pba), 0, PBA_LO(pba), 32, 0, MEDIA_PORT(us) | ||
672 | }; | ||
673 | |||
674 | US_DEBUGP("alauda_write_block: pba %d\n", pba); | ||
675 | |||
676 | rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, | ||
677 | command, 9, NULL); | ||
678 | if (rc != USB_STOR_XFER_GOOD) | ||
679 | return rc; | ||
680 | |||
681 | rc = usb_stor_bulk_transfer_buf(us, info->wr_ep, data, | ||
682 | (MEDIA_INFO(us).pagesize + 64) * MEDIA_INFO(us).blocksize, | ||
683 | NULL); | ||
684 | if (rc != USB_STOR_XFER_GOOD) | ||
685 | return rc; | ||
686 | |||
687 | return alauda_check_status2(us); | ||
688 | } | ||
689 | |||
690 | /* | ||
691 | * Write some data to a specific LBA. | ||
692 | */ | ||
693 | static int alauda_write_lba(struct us_data *us, u16 lba, | ||
694 | unsigned int page, unsigned int pages, | ||
695 | unsigned char *ptr, unsigned char *blockbuffer) | ||
696 | { | ||
697 | u16 pba, lbap, new_pba; | ||
698 | unsigned char *bptr, *cptr, *xptr; | ||
699 | unsigned char ecc[3]; | ||
700 | int i, result; | ||
701 | unsigned int uzonesize = MEDIA_INFO(us).uzonesize; | ||
702 | unsigned int zonesize = MEDIA_INFO(us).zonesize; | ||
703 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | ||
704 | unsigned int blocksize = MEDIA_INFO(us).blocksize; | ||
705 | unsigned int lba_offset = lba % uzonesize; | ||
706 | unsigned int new_pba_offset; | ||
707 | unsigned int zone = lba / uzonesize; | ||
708 | |||
709 | alauda_ensure_map_for_zone(us, zone); | ||
710 | |||
711 | pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset]; | ||
712 | if (pba == 1) { | ||
713 | /* Maybe it is impossible to write to PBA 1. | ||
714 | Fake success, but don't do anything. */ | ||
715 | printk("alauda_write_lba: avoid writing to pba 1\n"); | ||
716 | return USB_STOR_TRANSPORT_GOOD; | ||
717 | } | ||
718 | |||
719 | new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone); | ||
720 | if (!new_pba) { | ||
721 | printk("alauda_write_lba: Out of unused blocks\n"); | ||
722 | return USB_STOR_TRANSPORT_ERROR; | ||
723 | } | ||
724 | |||
725 | /* read old contents */ | ||
726 | if (pba != UNDEF) { | ||
727 | result = alauda_read_block_raw(us, pba, 0, | ||
728 | blocksize, blockbuffer); | ||
729 | if (result != USB_STOR_XFER_GOOD) | ||
730 | return result; | ||
731 | } else { | ||
732 | memset(blockbuffer, 0, blocksize * (pagesize + 64)); | ||
733 | } | ||
734 | |||
735 | lbap = (lba_offset << 1) | 0x1000; | ||
736 | if (parity[MSB_of(lbap) ^ LSB_of(lbap)]) | ||
737 | lbap ^= 1; | ||
738 | |||
739 | /* check old contents and fill lba */ | ||
740 | for (i = 0; i < blocksize; i++) { | ||
741 | bptr = blockbuffer + (i * (pagesize + 64)); | ||
742 | cptr = bptr + pagesize; | ||
743 | nand_compute_ecc(bptr, ecc); | ||
744 | if (!nand_compare_ecc(cptr+13, ecc)) { | ||
745 | US_DEBUGP("Warning: bad ecc in page %d- of pba %d\n", | ||
746 | i, pba); | ||
747 | nand_store_ecc(cptr+13, ecc); | ||
748 | } | ||
749 | nand_compute_ecc(bptr + (pagesize / 2), ecc); | ||
750 | if (!nand_compare_ecc(cptr+8, ecc)) { | ||
751 | US_DEBUGP("Warning: bad ecc in page %d+ of pba %d\n", | ||
752 | i, pba); | ||
753 | nand_store_ecc(cptr+8, ecc); | ||
754 | } | ||
755 | cptr[6] = cptr[11] = MSB_of(lbap); | ||
756 | cptr[7] = cptr[12] = LSB_of(lbap); | ||
757 | } | ||
758 | |||
759 | /* copy in new stuff and compute ECC */ | ||
760 | xptr = ptr; | ||
761 | for (i = page; i < page+pages; i++) { | ||
762 | bptr = blockbuffer + (i * (pagesize + 64)); | ||
763 | cptr = bptr + pagesize; | ||
764 | memcpy(bptr, xptr, pagesize); | ||
765 | xptr += pagesize; | ||
766 | nand_compute_ecc(bptr, ecc); | ||
767 | nand_store_ecc(cptr+13, ecc); | ||
768 | nand_compute_ecc(bptr + (pagesize / 2), ecc); | ||
769 | nand_store_ecc(cptr+8, ecc); | ||
770 | } | ||
771 | |||
772 | result = alauda_write_block(us, new_pba, blockbuffer); | ||
773 | if (result != USB_STOR_XFER_GOOD) | ||
774 | return result; | ||
775 | |||
776 | new_pba_offset = new_pba - (zone * zonesize); | ||
777 | MEDIA_INFO(us).pba_to_lba[zone][new_pba_offset] = lba; | ||
778 | MEDIA_INFO(us).lba_to_pba[zone][lba_offset] = new_pba; | ||
779 | US_DEBUGP("alauda_write_lba: Remapped LBA %d to PBA %d\n", | ||
780 | lba, new_pba); | ||
781 | |||
782 | if (pba != UNDEF) { | ||
783 | unsigned int pba_offset = pba - (zone * zonesize); | ||
784 | result = alauda_erase_block(us, pba); | ||
785 | if (result != USB_STOR_XFER_GOOD) | ||
786 | return result; | ||
787 | MEDIA_INFO(us).pba_to_lba[zone][pba_offset] = UNDEF; | ||
788 | } | ||
789 | |||
790 | return USB_STOR_TRANSPORT_GOOD; | ||
791 | } | ||
792 | |||
793 | /* | ||
794 | * Read data from a specific sector address | ||
795 | */ | ||
796 | static int alauda_read_data(struct us_data *us, unsigned long address, | ||
797 | unsigned int sectors) | ||
798 | { | ||
799 | unsigned char *buffer; | ||
800 | u16 lba, max_lba; | ||
801 | unsigned int page, len, index, offset; | ||
802 | unsigned int blockshift = MEDIA_INFO(us).blockshift; | ||
803 | unsigned int pageshift = MEDIA_INFO(us).pageshift; | ||
804 | unsigned int blocksize = MEDIA_INFO(us).blocksize; | ||
805 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | ||
806 | unsigned int uzonesize = MEDIA_INFO(us).uzonesize; | ||
807 | int result; | ||
808 | |||
809 | /* | ||
810 | * Since we only read in one block at a time, we have to create | ||
811 | * a bounce buffer and move the data a piece at a time between the | ||
812 | * bounce buffer and the actual transfer buffer. | ||
813 | * We make this buffer big enough to hold temporary redundancy data, | ||
814 | * which we use when reading the data blocks. | ||
815 | */ | ||
816 | |||
817 | len = min(sectors, blocksize) * (pagesize + 64); | ||
818 | buffer = kmalloc(len, GFP_NOIO); | ||
819 | if (buffer == NULL) { | ||
820 | printk("alauda_read_data: Out of memory\n"); | ||
821 | return USB_STOR_TRANSPORT_ERROR; | ||
822 | } | ||
823 | |||
824 | /* Figure out the initial LBA and page */ | ||
825 | lba = address >> blockshift; | ||
826 | page = (address & MEDIA_INFO(us).blockmask); | ||
827 | max_lba = MEDIA_INFO(us).capacity >> (blockshift + pageshift); | ||
828 | |||
829 | result = USB_STOR_TRANSPORT_GOOD; | ||
830 | index = offset = 0; | ||
831 | |||
832 | while (sectors > 0) { | ||
833 | unsigned int zone = lba / uzonesize; /* integer division */ | ||
834 | unsigned int lba_offset = lba - (zone * uzonesize); | ||
835 | unsigned int pages; | ||
836 | u16 pba; | ||
837 | alauda_ensure_map_for_zone(us, zone); | ||
838 | |||
839 | /* Not overflowing capacity? */ | ||
840 | if (lba >= max_lba) { | ||
841 | US_DEBUGP("Error: Requested lba %u exceeds " | ||
842 | "maximum %u\n", lba, max_lba); | ||
843 | result = USB_STOR_TRANSPORT_ERROR; | ||
844 | break; | ||
845 | } | ||
846 | |||
847 | /* Find number of pages we can read in this block */ | ||
848 | pages = min(sectors, blocksize - page); | ||
849 | len = pages << pageshift; | ||
850 | |||
851 | /* Find where this lba lives on disk */ | ||
852 | pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset]; | ||
853 | |||
854 | if (pba == UNDEF) { /* this lba was never written */ | ||
855 | US_DEBUGP("Read %d zero pages (LBA %d) page %d\n", | ||
856 | pages, lba, page); | ||
857 | |||
858 | /* This is not really an error. It just means | ||
859 | that the block has never been written. | ||
860 | Instead of returning USB_STOR_TRANSPORT_ERROR | ||
861 | it is better to return all zero data. */ | ||
862 | |||
863 | memset(buffer, 0, len); | ||
864 | } else { | ||
865 | US_DEBUGP("Read %d pages, from PBA %d" | ||
866 | " (LBA %d) page %d\n", | ||
867 | pages, pba, lba, page); | ||
868 | |||
869 | result = alauda_read_block(us, pba, page, pages, buffer); | ||
870 | if (result != USB_STOR_TRANSPORT_GOOD) | ||
871 | break; | ||
872 | } | ||
873 | |||
874 | /* Store the data in the transfer buffer */ | ||
875 | usb_stor_access_xfer_buf(buffer, len, us->srb, | ||
876 | &index, &offset, TO_XFER_BUF); | ||
877 | |||
878 | page = 0; | ||
879 | lba++; | ||
880 | sectors -= pages; | ||
881 | } | ||
882 | |||
883 | kfree(buffer); | ||
884 | return result; | ||
885 | } | ||
886 | |||
887 | /* | ||
888 | * Write data to a specific sector address | ||
889 | */ | ||
890 | static int alauda_write_data(struct us_data *us, unsigned long address, | ||
891 | unsigned int sectors) | ||
892 | { | ||
893 | unsigned char *buffer, *blockbuffer; | ||
894 | unsigned int page, len, index, offset; | ||
895 | unsigned int blockshift = MEDIA_INFO(us).blockshift; | ||
896 | unsigned int pageshift = MEDIA_INFO(us).pageshift; | ||
897 | unsigned int blocksize = MEDIA_INFO(us).blocksize; | ||
898 | unsigned int pagesize = MEDIA_INFO(us).pagesize; | ||
899 | u16 lba, max_lba; | ||
900 | int result; | ||
901 | |||
902 | /* | ||
903 | * Since we don't write the user data directly to the device, | ||
904 | * we have to create a bounce buffer and move the data a piece | ||
905 | * at a time between the bounce buffer and the actual transfer buffer. | ||
906 | */ | ||
907 | |||
908 | len = min(sectors, blocksize) * pagesize; | ||
909 | buffer = kmalloc(len, GFP_NOIO); | ||
910 | if (buffer == NULL) { | ||
911 | printk("alauda_write_data: Out of memory\n"); | ||
912 | return USB_STOR_TRANSPORT_ERROR; | ||
913 | } | ||
914 | |||
915 | /* | ||
916 | * We also need a temporary block buffer, where we read in the old data, | ||
917 | * overwrite parts with the new data, and manipulate the redundancy data | ||
918 | */ | ||
919 | blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO); | ||
920 | if (blockbuffer == NULL) { | ||
921 | printk("alauda_write_data: Out of memory\n"); | ||
922 | kfree(buffer); | ||
923 | return USB_STOR_TRANSPORT_ERROR; | ||
924 | } | ||
925 | |||
926 | /* Figure out the initial LBA and page */ | ||
927 | lba = address >> blockshift; | ||
928 | page = (address & MEDIA_INFO(us).blockmask); | ||
929 | max_lba = MEDIA_INFO(us).capacity >> (pageshift + blockshift); | ||
930 | |||
931 | result = USB_STOR_TRANSPORT_GOOD; | ||
932 | index = offset = 0; | ||
933 | |||
934 | while (sectors > 0) { | ||
935 | /* Write as many sectors as possible in this block */ | ||
936 | unsigned int pages = min(sectors, blocksize - page); | ||
937 | len = pages << pageshift; | ||
938 | |||
939 | /* Not overflowing capacity? */ | ||
940 | if (lba >= max_lba) { | ||
941 | US_DEBUGP("alauda_write_data: Requested lba %u exceeds " | ||
942 | "maximum %u\n", lba, max_lba); | ||
943 | result = USB_STOR_TRANSPORT_ERROR; | ||
944 | break; | ||
945 | } | ||
946 | |||
947 | /* Get the data from the transfer buffer */ | ||
948 | usb_stor_access_xfer_buf(buffer, len, us->srb, | ||
949 | &index, &offset, FROM_XFER_BUF); | ||
950 | |||
951 | result = alauda_write_lba(us, lba, page, pages, buffer, | ||
952 | blockbuffer); | ||
953 | if (result != USB_STOR_TRANSPORT_GOOD) | ||
954 | break; | ||
955 | |||
956 | page = 0; | ||
957 | lba++; | ||
958 | sectors -= pages; | ||
959 | } | ||
960 | |||
961 | kfree(buffer); | ||
962 | kfree(blockbuffer); | ||
963 | return result; | ||
964 | } | ||
965 | |||
966 | /* | ||
967 | * Our interface with the rest of the world | ||
968 | */ | ||
969 | |||
970 | static void alauda_info_destructor(void *extra) | ||
971 | { | ||
972 | struct alauda_info *info = (struct alauda_info *) extra; | ||
973 | int port; | ||
974 | |||
975 | if (!info) | ||
976 | return; | ||
977 | |||
978 | for (port = 0; port < 2; port++) { | ||
979 | struct alauda_media_info *media_info = &info->port[port]; | ||
980 | |||
981 | alauda_free_maps(media_info); | ||
982 | kfree(media_info->lba_to_pba); | ||
983 | kfree(media_info->pba_to_lba); | ||
984 | } | ||
985 | } | ||
986 | |||
987 | /* | ||
988 | * Initialize alauda_info struct and find the data-write endpoint | ||
989 | */ | ||
990 | int init_alauda(struct us_data *us) | ||
991 | { | ||
992 | struct alauda_info *info; | ||
993 | struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting; | ||
994 | nand_init_ecc(); | ||
995 | |||
996 | us->extra = kzalloc(sizeof(struct alauda_info), GFP_NOIO); | ||
997 | if (!us->extra) { | ||
998 | US_DEBUGP("init_alauda: Gah! Can't allocate storage for" | ||
999 | "alauda info struct!\n"); | ||
1000 | return USB_STOR_TRANSPORT_ERROR; | ||
1001 | } | ||
1002 | info = (struct alauda_info *) us->extra; | ||
1003 | us->extra_destructor = alauda_info_destructor; | ||
1004 | |||
1005 | info->wr_ep = usb_sndbulkpipe(us->pusb_dev, | ||
1006 | altsetting->endpoint[0].desc.bEndpointAddress | ||
1007 | & USB_ENDPOINT_NUMBER_MASK); | ||
1008 | |||
1009 | return USB_STOR_TRANSPORT_GOOD; | ||
1010 | } | ||
1011 | |||
1012 | int alauda_transport(struct scsi_cmnd *srb, struct us_data *us) | ||
1013 | { | ||
1014 | int rc; | ||
1015 | struct alauda_info *info = (struct alauda_info *) us->extra; | ||
1016 | unsigned char *ptr = us->iobuf; | ||
1017 | static unsigned char inquiry_response[36] = { | ||
1018 | 0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00 | ||
1019 | }; | ||
1020 | |||
1021 | if (srb->cmnd[0] == INQUIRY) { | ||
1022 | US_DEBUGP("alauda_transport: INQUIRY. " | ||
1023 | "Returning bogus response.\n"); | ||
1024 | memcpy(ptr, inquiry_response, sizeof(inquiry_response)); | ||
1025 | fill_inquiry_response(us, ptr, 36); | ||
1026 | return USB_STOR_TRANSPORT_GOOD; | ||
1027 | } | ||
1028 | |||
1029 | if (srb->cmnd[0] == TEST_UNIT_READY) { | ||
1030 | US_DEBUGP("alauda_transport: TEST_UNIT_READY.\n"); | ||
1031 | return alauda_check_media(us); | ||
1032 | } | ||
1033 | |||
1034 | if (srb->cmnd[0] == READ_CAPACITY) { | ||
1035 | unsigned int num_zones; | ||
1036 | unsigned long capacity; | ||
1037 | |||
1038 | rc = alauda_check_media(us); | ||
1039 | if (rc != USB_STOR_TRANSPORT_GOOD) | ||
1040 | return rc; | ||
1041 | |||
1042 | num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift | ||
1043 | + MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift); | ||
1044 | |||
1045 | capacity = num_zones * MEDIA_INFO(us).uzonesize | ||
1046 | * MEDIA_INFO(us).blocksize; | ||
1047 | |||
1048 | /* Report capacity and page size */ | ||
1049 | ((__be32 *) ptr)[0] = cpu_to_be32(capacity - 1); | ||
1050 | ((__be32 *) ptr)[1] = cpu_to_be32(512); | ||
1051 | |||
1052 | usb_stor_set_xfer_buf(ptr, 8, srb); | ||
1053 | return USB_STOR_TRANSPORT_GOOD; | ||
1054 | } | ||
1055 | |||
1056 | if (srb->cmnd[0] == READ_10) { | ||
1057 | unsigned int page, pages; | ||
1058 | |||
1059 | rc = alauda_check_media(us); | ||
1060 | if (rc != USB_STOR_TRANSPORT_GOOD) | ||
1061 | return rc; | ||
1062 | |||
1063 | page = short_pack(srb->cmnd[3], srb->cmnd[2]); | ||
1064 | page <<= 16; | ||
1065 | page |= short_pack(srb->cmnd[5], srb->cmnd[4]); | ||
1066 | pages = short_pack(srb->cmnd[8], srb->cmnd[7]); | ||
1067 | |||
1068 | US_DEBUGP("alauda_transport: READ_10: page %d pagect %d\n", | ||
1069 | page, pages); | ||
1070 | |||
1071 | return alauda_read_data(us, page, pages); | ||
1072 | } | ||
1073 | |||
1074 | if (srb->cmnd[0] == WRITE_10) { | ||
1075 | unsigned int page, pages; | ||
1076 | |||
1077 | rc = alauda_check_media(us); | ||
1078 | if (rc != USB_STOR_TRANSPORT_GOOD) | ||
1079 | return rc; | ||
1080 | |||
1081 | page = short_pack(srb->cmnd[3], srb->cmnd[2]); | ||
1082 | page <<= 16; | ||
1083 | page |= short_pack(srb->cmnd[5], srb->cmnd[4]); | ||
1084 | pages = short_pack(srb->cmnd[8], srb->cmnd[7]); | ||
1085 | |||
1086 | US_DEBUGP("alauda_transport: WRITE_10: page %d pagect %d\n", | ||
1087 | page, pages); | ||
1088 | |||
1089 | return alauda_write_data(us, page, pages); | ||
1090 | } | ||
1091 | |||
1092 | if (srb->cmnd[0] == REQUEST_SENSE) { | ||
1093 | US_DEBUGP("alauda_transport: REQUEST_SENSE.\n"); | ||
1094 | |||
1095 | memset(ptr, 0, 18); | ||
1096 | ptr[0] = 0xF0; | ||
1097 | ptr[2] = info->sense_key; | ||
1098 | ptr[7] = 11; | ||
1099 | ptr[12] = info->sense_asc; | ||
1100 | ptr[13] = info->sense_ascq; | ||
1101 | usb_stor_set_xfer_buf(ptr, 18, srb); | ||
1102 | |||
1103 | return USB_STOR_TRANSPORT_GOOD; | ||
1104 | } | ||
1105 | |||
1106 | if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { | ||
1107 | /* sure. whatever. not like we can stop the user from popping | ||
1108 | the media out of the device (no locking doors, etc) */ | ||
1109 | return USB_STOR_TRANSPORT_GOOD; | ||
1110 | } | ||
1111 | |||
1112 | US_DEBUGP("alauda_transport: Gah! Unknown command: %d (0x%x)\n", | ||
1113 | srb->cmnd[0], srb->cmnd[0]); | ||
1114 | info->sense_key = 0x05; | ||
1115 | info->sense_asc = 0x20; | ||
1116 | info->sense_ascq = 0x00; | ||
1117 | return USB_STOR_TRANSPORT_FAILED; | ||
1118 | } | ||
1119 | |||
diff --git a/drivers/usb/storage/alauda.h b/drivers/usb/storage/alauda.h new file mode 100644 index 000000000000..a700f87d0803 --- /dev/null +++ b/drivers/usb/storage/alauda.h | |||
@@ -0,0 +1,100 @@ | |||
1 | /* | ||
2 | * Driver for Alauda-based card readers | ||
3 | * | ||
4 | * Current development and maintenance by: | ||
5 | * (c) 2005 Daniel Drake <dsd@gentoo.org> | ||
6 | * | ||
7 | * See alauda.c for more explanation. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2, or (at your option) any | ||
12 | * later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #ifndef _USB_ALAUDA_H | ||
25 | #define _USB_ALAUDA_H | ||
26 | |||
27 | /* | ||
28 | * Status bytes | ||
29 | */ | ||
30 | #define ALAUDA_STATUS_ERROR 0x01 | ||
31 | #define ALAUDA_STATUS_READY 0x40 | ||
32 | |||
33 | /* | ||
34 | * Control opcodes (for request field) | ||
35 | */ | ||
36 | #define ALAUDA_GET_XD_MEDIA_STATUS 0x08 | ||
37 | #define ALAUDA_GET_SM_MEDIA_STATUS 0x98 | ||
38 | #define ALAUDA_ACK_XD_MEDIA_CHANGE 0x0a | ||
39 | #define ALAUDA_ACK_SM_MEDIA_CHANGE 0x9a | ||
40 | #define ALAUDA_GET_XD_MEDIA_SIG 0x86 | ||
41 | #define ALAUDA_GET_SM_MEDIA_SIG 0x96 | ||
42 | |||
43 | /* | ||
44 | * Bulk command identity (byte 0) | ||
45 | */ | ||
46 | #define ALAUDA_BULK_CMD 0x40 | ||
47 | |||
48 | /* | ||
49 | * Bulk opcodes (byte 1) | ||
50 | */ | ||
51 | #define ALAUDA_BULK_GET_REDU_DATA 0x85 | ||
52 | #define ALAUDA_BULK_READ_BLOCK 0x94 | ||
53 | #define ALAUDA_BULK_ERASE_BLOCK 0xa3 | ||
54 | #define ALAUDA_BULK_WRITE_BLOCK 0xb4 | ||
55 | #define ALAUDA_BULK_GET_STATUS2 0xb7 | ||
56 | #define ALAUDA_BULK_RESET_MEDIA 0xe0 | ||
57 | |||
58 | /* | ||
59 | * Port to operate on (byte 8) | ||
60 | */ | ||
61 | #define ALAUDA_PORT_XD 0x00 | ||
62 | #define ALAUDA_PORT_SM 0x01 | ||
63 | |||
64 | /* | ||
65 | * LBA and PBA are unsigned ints. Special values. | ||
66 | */ | ||
67 | #define UNDEF 0xffff | ||
68 | #define SPARE 0xfffe | ||
69 | #define UNUSABLE 0xfffd | ||
70 | |||
71 | int init_alauda(struct us_data *us); | ||
72 | int alauda_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
73 | |||
74 | struct alauda_media_info { | ||
75 | unsigned long capacity; /* total media size in bytes */ | ||
76 | unsigned int pagesize; /* page size in bytes */ | ||
77 | unsigned int blocksize; /* number of pages per block */ | ||
78 | unsigned int uzonesize; /* number of usable blocks per zone */ | ||
79 | unsigned int zonesize; /* number of blocks per zone */ | ||
80 | unsigned int blockmask; /* mask to get page from address */ | ||
81 | |||
82 | unsigned char pageshift; | ||
83 | unsigned char blockshift; | ||
84 | unsigned char zoneshift; | ||
85 | |||
86 | u16 **lba_to_pba; /* logical to physical block map */ | ||
87 | u16 **pba_to_lba; /* physical to logical block map */ | ||
88 | }; | ||
89 | |||
90 | struct alauda_info { | ||
91 | struct alauda_media_info port[2]; | ||
92 | int wr_ep; /* endpoint to write data out of */ | ||
93 | |||
94 | unsigned char sense_key; | ||
95 | unsigned long sense_asc; /* additional sense code */ | ||
96 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
97 | }; | ||
98 | |||
99 | #endif | ||
100 | |||
diff --git a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c index 5a9321705a74..01e430654a13 100644 --- a/drivers/usb/storage/debug.c +++ b/drivers/usb/storage/debug.c | |||
@@ -132,6 +132,7 @@ void usb_stor_show_command(struct scsi_cmnd *srb) | |||
132 | case 0x5C: what = "READ BUFFER CAPACITY"; break; | 132 | case 0x5C: what = "READ BUFFER CAPACITY"; break; |
133 | case 0x5D: what = "SEND CUE SHEET"; break; | 133 | case 0x5D: what = "SEND CUE SHEET"; break; |
134 | case GPCMD_BLANK: what = "BLANK"; break; | 134 | case GPCMD_BLANK: what = "BLANK"; break; |
135 | case REPORT_LUNS: what = "REPORT LUNS"; break; | ||
135 | case MOVE_MEDIUM: what = "MOVE_MEDIUM or PLAY AUDIO (12)"; break; | 136 | case MOVE_MEDIUM: what = "MOVE_MEDIUM or PLAY AUDIO (12)"; break; |
136 | case READ_12: what = "READ_12"; break; | 137 | case READ_12: what = "READ_12"; break; |
137 | case WRITE_12: what = "WRITE_12"; break; | 138 | case WRITE_12: what = "WRITE_12"; break; |
diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h index 7372386f33d5..4c1b2bd2e2e4 100644 --- a/drivers/usb/storage/initializers.h +++ b/drivers/usb/storage/initializers.h | |||
@@ -45,10 +45,6 @@ | |||
45 | * mode */ | 45 | * mode */ |
46 | int usb_stor_euscsi_init(struct us_data *us); | 46 | int usb_stor_euscsi_init(struct us_data *us); |
47 | 47 | ||
48 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
49 | int sddr09_init(struct us_data *us); | ||
50 | #endif | ||
51 | |||
52 | /* This function is required to activate all four slots on the UCR-61S2B | 48 | /* This function is required to activate all four slots on the UCR-61S2B |
53 | * flash reader */ | 49 | * flash reader */ |
54 | int usb_stor_ucr61s2b_init(struct us_data *us); | 50 | int usb_stor_ucr61s2b_init(struct us_data *us); |
diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c new file mode 100644 index 000000000000..b28151d1b609 --- /dev/null +++ b/drivers/usb/storage/libusual.c | |||
@@ -0,0 +1,266 @@ | |||
1 | /* | ||
2 | * libusual | ||
3 | * | ||
4 | * The libusual contains the table of devices common for ub and usb-storage. | ||
5 | */ | ||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/usb.h> | ||
9 | #include <linux/usb_usual.h> | ||
10 | #include <linux/vmalloc.h> | ||
11 | |||
12 | /* | ||
13 | */ | ||
14 | #define USU_MOD_FL_THREAD 1 /* Thread is running */ | ||
15 | #define USU_MOD_FL_PRESENT 2 /* The module is loaded */ | ||
16 | |||
17 | struct mod_status { | ||
18 | unsigned long fls; | ||
19 | }; | ||
20 | |||
21 | static struct mod_status stat[3]; | ||
22 | static DEFINE_SPINLOCK(usu_lock); | ||
23 | |||
24 | /* | ||
25 | */ | ||
26 | #define USB_US_DEFAULT_BIAS USB_US_TYPE_STOR | ||
27 | static atomic_t usu_bias = ATOMIC_INIT(USB_US_DEFAULT_BIAS); | ||
28 | |||
29 | #define BIAS_NAME_SIZE (sizeof("usb-storage")) | ||
30 | static const char *bias_names[3] = { "none", "usb-storage", "ub" }; | ||
31 | |||
32 | static DECLARE_MUTEX_LOCKED(usu_init_notify); | ||
33 | static DECLARE_COMPLETION(usu_end_notify); | ||
34 | static atomic_t total_threads = ATOMIC_INIT(0); | ||
35 | |||
36 | static int usu_probe_thread(void *arg); | ||
37 | |||
38 | /* | ||
39 | * The table. | ||
40 | */ | ||
41 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
42 | vendorName, productName,useProtocol, useTransport, \ | ||
43 | initFunction, flags) \ | ||
44 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ | ||
45 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
46 | |||
47 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
48 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
49 | .driver_info = ((useType)<<24) } | ||
50 | |||
51 | struct usb_device_id storage_usb_ids [] = { | ||
52 | # include "unusual_devs.h" | ||
53 | { } /* Terminating entry */ | ||
54 | }; | ||
55 | |||
56 | #undef USUAL_DEV | ||
57 | #undef UNUSUAL_DEV | ||
58 | |||
59 | MODULE_DEVICE_TABLE(usb, storage_usb_ids); | ||
60 | EXPORT_SYMBOL_GPL(storage_usb_ids); | ||
61 | |||
62 | /* | ||
63 | * @type: the module type as an integer | ||
64 | */ | ||
65 | void usb_usual_set_present(int type) | ||
66 | { | ||
67 | struct mod_status *st; | ||
68 | unsigned long flags; | ||
69 | |||
70 | if (type <= 0 || type >= 3) | ||
71 | return; | ||
72 | st = &stat[type]; | ||
73 | spin_lock_irqsave(&usu_lock, flags); | ||
74 | st->fls |= USU_MOD_FL_PRESENT; | ||
75 | spin_unlock_irqrestore(&usu_lock, flags); | ||
76 | } | ||
77 | EXPORT_SYMBOL_GPL(usb_usual_set_present); | ||
78 | |||
79 | void usb_usual_clear_present(int type) | ||
80 | { | ||
81 | struct mod_status *st; | ||
82 | unsigned long flags; | ||
83 | |||
84 | if (type <= 0 || type >= 3) | ||
85 | return; | ||
86 | st = &stat[type]; | ||
87 | spin_lock_irqsave(&usu_lock, flags); | ||
88 | st->fls &= ~USU_MOD_FL_PRESENT; | ||
89 | spin_unlock_irqrestore(&usu_lock, flags); | ||
90 | } | ||
91 | EXPORT_SYMBOL_GPL(usb_usual_clear_present); | ||
92 | |||
93 | /* | ||
94 | * Match the calling driver type against the table. | ||
95 | * Returns: 0 if the device matches. | ||
96 | */ | ||
97 | int usb_usual_check_type(const struct usb_device_id *id, int caller_type) | ||
98 | { | ||
99 | int id_type = USB_US_TYPE(id->driver_info); | ||
100 | |||
101 | if (caller_type <= 0 || caller_type >= 3) | ||
102 | return -EINVAL; | ||
103 | |||
104 | /* Drivers grab fixed assignment devices */ | ||
105 | if (id_type == caller_type) | ||
106 | return 0; | ||
107 | /* Drivers grab devices biased to them */ | ||
108 | if (id_type == USB_US_TYPE_NONE && caller_type == atomic_read(&usu_bias)) | ||
109 | return 0; | ||
110 | return -ENODEV; | ||
111 | } | ||
112 | EXPORT_SYMBOL_GPL(usb_usual_check_type); | ||
113 | |||
114 | /* | ||
115 | */ | ||
116 | static int usu_probe(struct usb_interface *intf, | ||
117 | const struct usb_device_id *id) | ||
118 | { | ||
119 | int type; | ||
120 | int rc; | ||
121 | unsigned long flags; | ||
122 | |||
123 | type = USB_US_TYPE(id->driver_info); | ||
124 | if (type == 0) | ||
125 | type = atomic_read(&usu_bias); | ||
126 | |||
127 | spin_lock_irqsave(&usu_lock, flags); | ||
128 | if ((stat[type].fls & (USU_MOD_FL_THREAD|USU_MOD_FL_PRESENT)) != 0) { | ||
129 | spin_unlock_irqrestore(&usu_lock, flags); | ||
130 | return -ENXIO; | ||
131 | } | ||
132 | stat[type].fls |= USU_MOD_FL_THREAD; | ||
133 | spin_unlock_irqrestore(&usu_lock, flags); | ||
134 | |||
135 | rc = kernel_thread(usu_probe_thread, (void*)type, CLONE_VM); | ||
136 | if (rc < 0) { | ||
137 | printk(KERN_WARNING "libusual: " | ||
138 | "Unable to start the thread for %s: %d\n", | ||
139 | bias_names[type], rc); | ||
140 | spin_lock_irqsave(&usu_lock, flags); | ||
141 | stat[type].fls &= ~USU_MOD_FL_THREAD; | ||
142 | spin_unlock_irqrestore(&usu_lock, flags); | ||
143 | return rc; /* Not being -ENXIO causes a message printed */ | ||
144 | } | ||
145 | atomic_inc(&total_threads); | ||
146 | |||
147 | return -ENXIO; | ||
148 | } | ||
149 | |||
150 | static void usu_disconnect(struct usb_interface *intf) | ||
151 | { | ||
152 | ; /* We should not be here. */ | ||
153 | } | ||
154 | |||
155 | static struct usb_driver usu_driver = { | ||
156 | .name = "libusual", | ||
157 | .probe = usu_probe, | ||
158 | .disconnect = usu_disconnect, | ||
159 | .id_table = storage_usb_ids, | ||
160 | }; | ||
161 | |||
162 | /* | ||
163 | * A whole new thread for a purpose of request_module seems quite stupid. | ||
164 | * The request_module forks once inside again. However, if we attempt | ||
165 | * to load a storage module from our own modprobe thread, that module | ||
166 | * references our symbols, which cannot be resolved until our module is | ||
167 | * initialized. I wish there was a way to wait for the end of initialization. | ||
168 | * The module notifier reports MODULE_STATE_COMING only. | ||
169 | * So, we wait until module->init ends as the next best thing. | ||
170 | */ | ||
171 | static int usu_probe_thread(void *arg) | ||
172 | { | ||
173 | int type = (unsigned long) arg; | ||
174 | struct mod_status *st = &stat[type]; | ||
175 | int rc; | ||
176 | unsigned long flags; | ||
177 | |||
178 | daemonize("libusual_%d", type); /* "usb-storage" is kinda too long */ | ||
179 | |||
180 | /* A completion does not work here because it's counted. */ | ||
181 | down(&usu_init_notify); | ||
182 | up(&usu_init_notify); | ||
183 | |||
184 | rc = request_module(bias_names[type]); | ||
185 | spin_lock_irqsave(&usu_lock, flags); | ||
186 | if (rc == 0 && (st->fls & USU_MOD_FL_PRESENT) == 0) { | ||
187 | /* | ||
188 | * This should not happen, but let us keep tabs on it. | ||
189 | */ | ||
190 | printk(KERN_NOTICE "libusual: " | ||
191 | "modprobe for %s succeeded, but module is not present\n", | ||
192 | bias_names[type]); | ||
193 | } | ||
194 | st->fls &= ~USU_MOD_FL_THREAD; | ||
195 | spin_unlock_irqrestore(&usu_lock, flags); | ||
196 | |||
197 | complete_and_exit(&usu_end_notify, 0); | ||
198 | } | ||
199 | |||
200 | /* | ||
201 | */ | ||
202 | static int __init usb_usual_init(void) | ||
203 | { | ||
204 | int rc; | ||
205 | |||
206 | rc = usb_register(&usu_driver); | ||
207 | up(&usu_init_notify); | ||
208 | return rc; | ||
209 | } | ||
210 | |||
211 | static void __exit usb_usual_exit(void) | ||
212 | { | ||
213 | /* | ||
214 | * We do not check for any drivers present, because | ||
215 | * they keep us pinned with symbol references. | ||
216 | */ | ||
217 | |||
218 | usb_deregister(&usu_driver); | ||
219 | |||
220 | while (atomic_read(&total_threads) > 0) { | ||
221 | wait_for_completion(&usu_end_notify); | ||
222 | atomic_dec(&total_threads); | ||
223 | } | ||
224 | } | ||
225 | |||
226 | /* | ||
227 | * Validate and accept the bias parameter. | ||
228 | */ | ||
229 | static int usu_set_bias(const char *bias_s, struct kernel_param *kp) | ||
230 | { | ||
231 | int i; | ||
232 | int len; | ||
233 | int bias_n = 0; | ||
234 | |||
235 | len = strlen(bias_s); | ||
236 | if (len == 0) | ||
237 | return -EDOM; | ||
238 | if (bias_s[len-1] == '\n') | ||
239 | --len; | ||
240 | |||
241 | for (i = 1; i < 3; i++) { | ||
242 | if (strncmp(bias_s, bias_names[i], len) == 0) { | ||
243 | bias_n = i; | ||
244 | break; | ||
245 | } | ||
246 | } | ||
247 | if (bias_n == 0) | ||
248 | return -EINVAL; | ||
249 | |||
250 | atomic_set(&usu_bias, bias_n); | ||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | static int usu_get_bias(char *buffer, struct kernel_param *kp) | ||
255 | { | ||
256 | return strlen(strcpy(buffer, bias_names[atomic_read(&usu_bias)])); | ||
257 | } | ||
258 | |||
259 | module_init(usb_usual_init); | ||
260 | module_exit(usb_usual_exit); | ||
261 | |||
262 | module_param_call(bias, usu_set_bias, usu_get_bias, NULL, S_IRUGO|S_IWUSR); | ||
263 | __MODULE_PARM_TYPE(bias, "string"); | ||
264 | MODULE_PARM_DESC(bias, "Bias to usb-storage or ub"); | ||
265 | |||
266 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index 89401a59f952..55ee2d36d585 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c | |||
@@ -52,6 +52,7 @@ struct usb_onetouch { | |||
52 | struct urb *irq; /* urb for interrupt in report */ | 52 | struct urb *irq; /* urb for interrupt in report */ |
53 | unsigned char *data; /* input data */ | 53 | unsigned char *data; /* input data */ |
54 | dma_addr_t data_dma; | 54 | dma_addr_t data_dma; |
55 | unsigned int is_open:1; | ||
55 | }; | 56 | }; |
56 | 57 | ||
57 | static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs) | 58 | static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs) |
@@ -89,6 +90,7 @@ static int usb_onetouch_open(struct input_dev *dev) | |||
89 | { | 90 | { |
90 | struct usb_onetouch *onetouch = dev->private; | 91 | struct usb_onetouch *onetouch = dev->private; |
91 | 92 | ||
93 | onetouch->is_open = 1; | ||
92 | onetouch->irq->dev = onetouch->udev; | 94 | onetouch->irq->dev = onetouch->udev; |
93 | if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) { | 95 | if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) { |
94 | err("usb_submit_urb failed"); | 96 | err("usb_submit_urb failed"); |
@@ -103,8 +105,30 @@ static void usb_onetouch_close(struct input_dev *dev) | |||
103 | struct usb_onetouch *onetouch = dev->private; | 105 | struct usb_onetouch *onetouch = dev->private; |
104 | 106 | ||
105 | usb_kill_urb(onetouch->irq); | 107 | usb_kill_urb(onetouch->irq); |
108 | onetouch->is_open = 0; | ||
106 | } | 109 | } |
107 | 110 | ||
111 | #ifdef CONFIG_PM | ||
112 | static void usb_onetouch_pm_hook(struct us_data *us, int action) | ||
113 | { | ||
114 | struct usb_onetouch *onetouch = (struct usb_onetouch *) us->extra; | ||
115 | |||
116 | if (onetouch->is_open) { | ||
117 | switch (action) { | ||
118 | case US_SUSPEND: | ||
119 | usb_kill_urb(onetouch->irq); | ||
120 | break; | ||
121 | case US_RESUME: | ||
122 | if (usb_submit_urb(onetouch->irq, GFP_KERNEL) != 0) | ||
123 | err("usb_submit_urb failed"); | ||
124 | break; | ||
125 | default: | ||
126 | break; | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | #endif /* CONFIG_PM */ | ||
131 | |||
108 | int onetouch_connect_input(struct us_data *ss) | 132 | int onetouch_connect_input(struct us_data *ss) |
109 | { | 133 | { |
110 | struct usb_device *udev = ss->pusb_dev; | 134 | struct usb_device *udev = ss->pusb_dev; |
@@ -185,6 +209,9 @@ int onetouch_connect_input(struct us_data *ss) | |||
185 | 209 | ||
186 | ss->extra_destructor = onetouch_release_input; | 210 | ss->extra_destructor = onetouch_release_input; |
187 | ss->extra = onetouch; | 211 | ss->extra = onetouch; |
212 | #ifdef CONFIG_PM | ||
213 | ss->suspend_resume_hook = usb_onetouch_pm_hook; | ||
214 | #endif | ||
188 | 215 | ||
189 | input_register_device(onetouch->dev); | 216 | input_register_device(onetouch->dev); |
190 | 217 | ||
diff --git a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h index 02bff01ab09c..845bed4b8031 100644 --- a/drivers/usb/storage/protocol.h +++ b/drivers/usb/storage/protocol.h | |||
@@ -41,20 +41,6 @@ | |||
41 | #ifndef _PROTOCOL_H_ | 41 | #ifndef _PROTOCOL_H_ |
42 | #define _PROTOCOL_H_ | 42 | #define _PROTOCOL_H_ |
43 | 43 | ||
44 | /* Sub Classes */ | ||
45 | |||
46 | #define US_SC_RBC 0x01 /* Typically, flash devices */ | ||
47 | #define US_SC_8020 0x02 /* CD-ROM */ | ||
48 | #define US_SC_QIC 0x03 /* QIC-157 Tapes */ | ||
49 | #define US_SC_UFI 0x04 /* Floppy */ | ||
50 | #define US_SC_8070 0x05 /* Removable media */ | ||
51 | #define US_SC_SCSI 0x06 /* Transparent */ | ||
52 | #define US_SC_ISD200 0x07 /* ISD200 ATA */ | ||
53 | #define US_SC_MIN US_SC_RBC | ||
54 | #define US_SC_MAX US_SC_ISD200 | ||
55 | |||
56 | #define US_SC_DEVICE 0xff /* Use device's value */ | ||
57 | |||
58 | /* Protocol handling routines */ | 44 | /* Protocol handling routines */ |
59 | extern void usb_stor_ATAPI_command(struct scsi_cmnd*, struct us_data*); | 45 | extern void usb_stor_ATAPI_command(struct scsi_cmnd*, struct us_data*); |
60 | extern void usb_stor_qic157_command(struct scsi_cmnd*, struct us_data*); | 46 | extern void usb_stor_qic157_command(struct scsi_cmnd*, struct us_data*); |
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 4837524eada7..4ef5527028c5 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
@@ -109,7 +109,7 @@ static int slave_configure(struct scsi_device *sdev) | |||
109 | * data comes from. | 109 | * data comes from. |
110 | */ | 110 | */ |
111 | if (sdev->scsi_level < SCSI_2) | 111 | if (sdev->scsi_level < SCSI_2) |
112 | sdev->scsi_level = SCSI_2; | 112 | sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2; |
113 | 113 | ||
114 | /* According to the technical support people at Genesys Logic, | 114 | /* According to the technical support people at Genesys Logic, |
115 | * devices using their chips have problems transferring more than | 115 | * devices using their chips have problems transferring more than |
@@ -162,7 +162,7 @@ static int slave_configure(struct scsi_device *sdev) | |||
162 | * a Get-Max-LUN request, we won't lose much by setting the | 162 | * a Get-Max-LUN request, we won't lose much by setting the |
163 | * revision level down to 2. The only devices that would be | 163 | * revision level down to 2. The only devices that would be |
164 | * affected are those with sparse LUNs. */ | 164 | * affected are those with sparse LUNs. */ |
165 | sdev->scsi_level = SCSI_2; | 165 | sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2; |
166 | 166 | ||
167 | /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable | 167 | /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable |
168 | * Hardware Error) when any low-level error occurs, | 168 | * Hardware Error) when any low-level error occurs, |
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 0ea2f5ab66ba..fb8bacaae27c 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c | |||
@@ -133,13 +133,11 @@ static struct nand_flash_dev nand_flash_ids[] = { | |||
133 | { 0,} | 133 | { 0,} |
134 | }; | 134 | }; |
135 | 135 | ||
136 | #define SIZE(a) (sizeof(a)/sizeof((a)[0])) | ||
137 | |||
138 | static struct nand_flash_dev * | 136 | static struct nand_flash_dev * |
139 | nand_find_id(unsigned char id) { | 137 | nand_find_id(unsigned char id) { |
140 | int i; | 138 | int i; |
141 | 139 | ||
142 | for (i = 0; i < SIZE(nand_flash_ids); i++) | 140 | for (i = 0; i < ARRAY_SIZE(nand_flash_ids); i++) |
143 | if (nand_flash_ids[i].model_id == id) | 141 | if (nand_flash_ids[i].model_id == id) |
144 | return &(nand_flash_ids[i]); | 142 | return &(nand_flash_ids[i]); |
145 | return NULL; | 143 | return NULL; |
@@ -214,6 +212,20 @@ static void nand_store_ecc(unsigned char *data, unsigned char *ecc) { | |||
214 | * The actual driver starts here. | 212 | * The actual driver starts here. |
215 | */ | 213 | */ |
216 | 214 | ||
215 | struct sddr09_card_info { | ||
216 | unsigned long capacity; /* Size of card in bytes */ | ||
217 | int pagesize; /* Size of page in bytes */ | ||
218 | int pageshift; /* log2 of pagesize */ | ||
219 | int blocksize; /* Size of block in pages */ | ||
220 | int blockshift; /* log2 of blocksize */ | ||
221 | int blockmask; /* 2^blockshift - 1 */ | ||
222 | int *lba_to_pba; /* logical to physical map */ | ||
223 | int *pba_to_lba; /* physical to logical map */ | ||
224 | int lbact; /* number of available pages */ | ||
225 | int flags; | ||
226 | #define SDDR09_WP 1 /* write protected */ | ||
227 | }; | ||
228 | |||
217 | /* | 229 | /* |
218 | * On my 16MB card, control blocks have size 64 (16 real control bytes, | 230 | * On my 16MB card, control blocks have size 64 (16 real control bytes, |
219 | * and 48 junk bytes). In reality of course the card uses 16 control bytes, | 231 | * and 48 junk bytes). In reality of course the card uses 16 control bytes, |
@@ -237,7 +249,7 @@ static void nand_store_ecc(unsigned char *data, unsigned char *ecc) { | |||
237 | #define SPARE 0xfffffffe | 249 | #define SPARE 0xfffffffe |
238 | #define UNUSABLE 0xfffffffd | 250 | #define UNUSABLE 0xfffffffd |
239 | 251 | ||
240 | static int erase_bad_lba_entries = 0; | 252 | static const int erase_bad_lba_entries = 0; |
241 | 253 | ||
242 | /* send vendor interface command (0x41) */ | 254 | /* send vendor interface command (0x41) */ |
243 | /* called for requests 0, 1, 8 */ | 255 | /* called for requests 0, 1, 8 */ |
@@ -260,8 +272,11 @@ sddr09_send_command(struct us_data *us, | |||
260 | 272 | ||
261 | rc = usb_stor_ctrl_transfer(us, pipe, request, requesttype, | 273 | rc = usb_stor_ctrl_transfer(us, pipe, request, requesttype, |
262 | 0, 0, xfer_data, xfer_len); | 274 | 0, 0, xfer_data, xfer_len); |
263 | return (rc == USB_STOR_XFER_GOOD ? USB_STOR_TRANSPORT_GOOD : | 275 | switch (rc) { |
264 | USB_STOR_TRANSPORT_ERROR); | 276 | case USB_STOR_XFER_GOOD: return 0; |
277 | case USB_STOR_XFER_STALLED: return -EPIPE; | ||
278 | default: return -EIO; | ||
279 | } | ||
265 | } | 280 | } |
266 | 281 | ||
267 | static int | 282 | static int |
@@ -308,20 +323,12 @@ sddr09_request_sense(struct us_data *us, unsigned char *sensebuf, int buflen) { | |||
308 | command[4] = buflen; | 323 | command[4] = buflen; |
309 | 324 | ||
310 | result = sddr09_send_scsi_command(us, command, 12); | 325 | result = sddr09_send_scsi_command(us, command, 12); |
311 | if (result != USB_STOR_TRANSPORT_GOOD) { | 326 | if (result) |
312 | US_DEBUGP("request sense failed\n"); | ||
313 | return result; | 327 | return result; |
314 | } | ||
315 | 328 | ||
316 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | 329 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, |
317 | sensebuf, buflen, NULL); | 330 | sensebuf, buflen, NULL); |
318 | if (result != USB_STOR_XFER_GOOD) { | 331 | return (result == USB_STOR_XFER_GOOD ? 0 : -EIO); |
319 | US_DEBUGP("request sense bulk in failed\n"); | ||
320 | return USB_STOR_TRANSPORT_ERROR; | ||
321 | } else { | ||
322 | US_DEBUGP("request sense worked\n"); | ||
323 | return USB_STOR_TRANSPORT_GOOD; | ||
324 | } | ||
325 | } | 332 | } |
326 | 333 | ||
327 | /* | 334 | /* |
@@ -369,7 +376,7 @@ sddr09_readX(struct us_data *us, int x, unsigned long fromaddress, | |||
369 | 376 | ||
370 | result = sddr09_send_scsi_command(us, command, 12); | 377 | result = sddr09_send_scsi_command(us, command, 12); |
371 | 378 | ||
372 | if (result != USB_STOR_TRANSPORT_GOOD) { | 379 | if (result) { |
373 | US_DEBUGP("Result for send_control in sddr09_read2%d %d\n", | 380 | US_DEBUGP("Result for send_control in sddr09_read2%d %d\n", |
374 | x, result); | 381 | x, result); |
375 | return result; | 382 | return result; |
@@ -381,9 +388,9 @@ sddr09_readX(struct us_data *us, int x, unsigned long fromaddress, | |||
381 | if (result != USB_STOR_XFER_GOOD) { | 388 | if (result != USB_STOR_XFER_GOOD) { |
382 | US_DEBUGP("Result for bulk_transfer in sddr09_read2%d %d\n", | 389 | US_DEBUGP("Result for bulk_transfer in sddr09_read2%d %d\n", |
383 | x, result); | 390 | x, result); |
384 | return USB_STOR_TRANSPORT_ERROR; | 391 | return -EIO; |
385 | } | 392 | } |
386 | return USB_STOR_TRANSPORT_GOOD; | 393 | return 0; |
387 | } | 394 | } |
388 | 395 | ||
389 | /* | 396 | /* |
@@ -497,7 +504,7 @@ sddr09_erase(struct us_data *us, unsigned long Eaddress) { | |||
497 | 504 | ||
498 | result = sddr09_send_scsi_command(us, command, 12); | 505 | result = sddr09_send_scsi_command(us, command, 12); |
499 | 506 | ||
500 | if (result != USB_STOR_TRANSPORT_GOOD) | 507 | if (result) |
501 | US_DEBUGP("Result for send_control in sddr09_erase %d\n", | 508 | US_DEBUGP("Result for send_control in sddr09_erase %d\n", |
502 | result); | 509 | result); |
503 | 510 | ||
@@ -555,7 +562,7 @@ sddr09_writeX(struct us_data *us, | |||
555 | 562 | ||
556 | result = sddr09_send_scsi_command(us, command, 12); | 563 | result = sddr09_send_scsi_command(us, command, 12); |
557 | 564 | ||
558 | if (result != USB_STOR_TRANSPORT_GOOD) { | 565 | if (result) { |
559 | US_DEBUGP("Result for send_control in sddr09_writeX %d\n", | 566 | US_DEBUGP("Result for send_control in sddr09_writeX %d\n", |
560 | result); | 567 | result); |
561 | return result; | 568 | return result; |
@@ -567,9 +574,9 @@ sddr09_writeX(struct us_data *us, | |||
567 | if (result != USB_STOR_XFER_GOOD) { | 574 | if (result != USB_STOR_XFER_GOOD) { |
568 | US_DEBUGP("Result for bulk_transfer in sddr09_writeX %d\n", | 575 | US_DEBUGP("Result for bulk_transfer in sddr09_writeX %d\n", |
569 | result); | 576 | result); |
570 | return USB_STOR_TRANSPORT_ERROR; | 577 | return -EIO; |
571 | } | 578 | } |
572 | return USB_STOR_TRANSPORT_GOOD; | 579 | return 0; |
573 | } | 580 | } |
574 | 581 | ||
575 | /* erase address, write same address */ | 582 | /* erase address, write same address */ |
@@ -633,7 +640,7 @@ sddr09_read_sg_test_only(struct us_data *us) { | |||
633 | 640 | ||
634 | result = sddr09_send_scsi_command(us, command, 4*nsg+3); | 641 | result = sddr09_send_scsi_command(us, command, 4*nsg+3); |
635 | 642 | ||
636 | if (result != USB_STOR_TRANSPORT_GOOD) { | 643 | if (result) { |
637 | US_DEBUGP("Result for send_control in sddr09_read_sg %d\n", | 644 | US_DEBUGP("Result for send_control in sddr09_read_sg %d\n", |
638 | result); | 645 | result); |
639 | return result; | 646 | return result; |
@@ -641,7 +648,7 @@ sddr09_read_sg_test_only(struct us_data *us) { | |||
641 | 648 | ||
642 | buf = (unsigned char *) kmalloc(bulklen, GFP_NOIO); | 649 | buf = (unsigned char *) kmalloc(bulklen, GFP_NOIO); |
643 | if (!buf) | 650 | if (!buf) |
644 | return USB_STOR_TRANSPORT_ERROR; | 651 | return -ENOMEM; |
645 | 652 | ||
646 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | 653 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, |
647 | buf, bulklen, NULL); | 654 | buf, bulklen, NULL); |
@@ -649,10 +656,10 @@ sddr09_read_sg_test_only(struct us_data *us) { | |||
649 | if (result != USB_STOR_XFER_GOOD) { | 656 | if (result != USB_STOR_XFER_GOOD) { |
650 | US_DEBUGP("Result for bulk_transfer in sddr09_read_sg %d\n", | 657 | US_DEBUGP("Result for bulk_transfer in sddr09_read_sg %d\n", |
651 | result); | 658 | result); |
652 | return USB_STOR_TRANSPORT_ERROR; | 659 | return -EIO; |
653 | } | 660 | } |
654 | 661 | ||
655 | return USB_STOR_TRANSPORT_GOOD; | 662 | return 0; |
656 | } | 663 | } |
657 | #endif | 664 | #endif |
658 | 665 | ||
@@ -681,14 +688,13 @@ sddr09_read_status(struct us_data *us, unsigned char *status) { | |||
681 | command[1] = LUNBITS; | 688 | command[1] = LUNBITS; |
682 | 689 | ||
683 | result = sddr09_send_scsi_command(us, command, 12); | 690 | result = sddr09_send_scsi_command(us, command, 12); |
684 | if (result != USB_STOR_TRANSPORT_GOOD) | 691 | if (result) |
685 | return result; | 692 | return result; |
686 | 693 | ||
687 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | 694 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, |
688 | data, 64, NULL); | 695 | data, 64, NULL); |
689 | *status = data[0]; | 696 | *status = data[0]; |
690 | return (result == USB_STOR_XFER_GOOD ? | 697 | return (result == USB_STOR_XFER_GOOD ? 0 : -EIO); |
691 | USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR); | ||
692 | } | 698 | } |
693 | 699 | ||
694 | static int | 700 | static int |
@@ -703,6 +709,13 @@ sddr09_read_data(struct us_data *us, | |||
703 | unsigned int len, index, offset; | 709 | unsigned int len, index, offset; |
704 | int result; | 710 | int result; |
705 | 711 | ||
712 | // Figure out the initial LBA and page | ||
713 | lba = address >> info->blockshift; | ||
714 | page = (address & info->blockmask); | ||
715 | maxlba = info->capacity >> (info->pageshift + info->blockshift); | ||
716 | if (lba >= maxlba) | ||
717 | return -EIO; | ||
718 | |||
706 | // Since we only read in one block at a time, we have to create | 719 | // Since we only read in one block at a time, we have to create |
707 | // a bounce buffer and move the data a piece at a time between the | 720 | // a bounce buffer and move the data a piece at a time between the |
708 | // bounce buffer and the actual transfer buffer. | 721 | // bounce buffer and the actual transfer buffer. |
@@ -711,18 +724,13 @@ sddr09_read_data(struct us_data *us, | |||
711 | buffer = kmalloc(len, GFP_NOIO); | 724 | buffer = kmalloc(len, GFP_NOIO); |
712 | if (buffer == NULL) { | 725 | if (buffer == NULL) { |
713 | printk("sddr09_read_data: Out of memory\n"); | 726 | printk("sddr09_read_data: Out of memory\n"); |
714 | return USB_STOR_TRANSPORT_ERROR; | 727 | return -ENOMEM; |
715 | } | 728 | } |
716 | 729 | ||
717 | // Figure out the initial LBA and page | ||
718 | lba = address >> info->blockshift; | ||
719 | page = (address & info->blockmask); | ||
720 | maxlba = info->capacity >> (info->pageshift + info->blockshift); | ||
721 | |||
722 | // This could be made much more efficient by checking for | 730 | // This could be made much more efficient by checking for |
723 | // contiguous LBA's. Another exercise left to the student. | 731 | // contiguous LBA's. Another exercise left to the student. |
724 | 732 | ||
725 | result = USB_STOR_TRANSPORT_GOOD; | 733 | result = 0; |
726 | index = offset = 0; | 734 | index = offset = 0; |
727 | 735 | ||
728 | while (sectors > 0) { | 736 | while (sectors > 0) { |
@@ -735,7 +743,7 @@ sddr09_read_data(struct us_data *us, | |||
735 | if (lba >= maxlba) { | 743 | if (lba >= maxlba) { |
736 | US_DEBUGP("Error: Requested lba %u exceeds " | 744 | US_DEBUGP("Error: Requested lba %u exceeds " |
737 | "maximum %u\n", lba, maxlba); | 745 | "maximum %u\n", lba, maxlba); |
738 | result = USB_STOR_TRANSPORT_ERROR; | 746 | result = -EIO; |
739 | break; | 747 | break; |
740 | } | 748 | } |
741 | 749 | ||
@@ -749,7 +757,7 @@ sddr09_read_data(struct us_data *us, | |||
749 | 757 | ||
750 | /* This is not really an error. It just means | 758 | /* This is not really an error. It just means |
751 | that the block has never been written. | 759 | that the block has never been written. |
752 | Instead of returning USB_STOR_TRANSPORT_ERROR | 760 | Instead of returning an error |
753 | it is better to return all zero data. */ | 761 | it is better to return all zero data. */ |
754 | 762 | ||
755 | memset(buffer, 0, len); | 763 | memset(buffer, 0, len); |
@@ -764,7 +772,7 @@ sddr09_read_data(struct us_data *us, | |||
764 | 772 | ||
765 | result = sddr09_read20(us, address>>1, | 773 | result = sddr09_read20(us, address>>1, |
766 | pages, info->pageshift, buffer, 0); | 774 | pages, info->pageshift, buffer, 0); |
767 | if (result != USB_STOR_TRANSPORT_GOOD) | 775 | if (result) |
768 | break; | 776 | break; |
769 | } | 777 | } |
770 | 778 | ||
@@ -830,7 +838,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
830 | pba = sddr09_find_unused_pba(info, lba); | 838 | pba = sddr09_find_unused_pba(info, lba); |
831 | if (!pba) { | 839 | if (!pba) { |
832 | printk("sddr09_write_lba: Out of unused blocks\n"); | 840 | printk("sddr09_write_lba: Out of unused blocks\n"); |
833 | return USB_STOR_TRANSPORT_ERROR; | 841 | return -ENOSPC; |
834 | } | 842 | } |
835 | info->pba_to_lba[pba] = lba; | 843 | info->pba_to_lba[pba] = lba; |
836 | info->lba_to_pba[lba] = pba; | 844 | info->lba_to_pba[lba] = pba; |
@@ -841,7 +849,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
841 | /* Maybe it is impossible to write to PBA 1. | 849 | /* Maybe it is impossible to write to PBA 1. |
842 | Fake success, but don't do anything. */ | 850 | Fake success, but don't do anything. */ |
843 | printk("sddr09: avoid writing to pba 1\n"); | 851 | printk("sddr09: avoid writing to pba 1\n"); |
844 | return USB_STOR_TRANSPORT_GOOD; | 852 | return 0; |
845 | } | 853 | } |
846 | 854 | ||
847 | pagelen = (1 << info->pageshift) + (1 << CONTROL_SHIFT); | 855 | pagelen = (1 << info->pageshift) + (1 << CONTROL_SHIFT); |
@@ -850,7 +858,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
850 | address = (pba << (info->pageshift + info->blockshift)); | 858 | address = (pba << (info->pageshift + info->blockshift)); |
851 | result = sddr09_read22(us, address>>1, info->blocksize, | 859 | result = sddr09_read22(us, address>>1, info->blocksize, |
852 | info->pageshift, blockbuffer, 0); | 860 | info->pageshift, blockbuffer, 0); |
853 | if (result != USB_STOR_TRANSPORT_GOOD) | 861 | if (result) |
854 | return result; | 862 | return result; |
855 | 863 | ||
856 | /* check old contents and fill lba */ | 864 | /* check old contents and fill lba */ |
@@ -897,7 +905,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
897 | { | 905 | { |
898 | unsigned char status = 0; | 906 | unsigned char status = 0; |
899 | int result2 = sddr09_read_status(us, &status); | 907 | int result2 = sddr09_read_status(us, &status); |
900 | if (result2 != USB_STOR_TRANSPORT_GOOD) | 908 | if (result2) |
901 | US_DEBUGP("sddr09_write_inplace: cannot read status\n"); | 909 | US_DEBUGP("sddr09_write_inplace: cannot read status\n"); |
902 | else if (status != 0xc0) | 910 | else if (status != 0xc0) |
903 | US_DEBUGP("sddr09_write_inplace: status after write: 0x%x\n", | 911 | US_DEBUGP("sddr09_write_inplace: status after write: 0x%x\n", |
@@ -920,13 +928,20 @@ sddr09_write_data(struct us_data *us, | |||
920 | unsigned int sectors) { | 928 | unsigned int sectors) { |
921 | 929 | ||
922 | struct sddr09_card_info *info = (struct sddr09_card_info *) us->extra; | 930 | struct sddr09_card_info *info = (struct sddr09_card_info *) us->extra; |
923 | unsigned int lba, page, pages; | 931 | unsigned int lba, maxlba, page, pages; |
924 | unsigned int pagelen, blocklen; | 932 | unsigned int pagelen, blocklen; |
925 | unsigned char *blockbuffer; | 933 | unsigned char *blockbuffer; |
926 | unsigned char *buffer; | 934 | unsigned char *buffer; |
927 | unsigned int len, index, offset; | 935 | unsigned int len, index, offset; |
928 | int result; | 936 | int result; |
929 | 937 | ||
938 | // Figure out the initial LBA and page | ||
939 | lba = address >> info->blockshift; | ||
940 | page = (address & info->blockmask); | ||
941 | maxlba = info->capacity >> (info->pageshift + info->blockshift); | ||
942 | if (lba >= maxlba) | ||
943 | return -EIO; | ||
944 | |||
930 | // blockbuffer is used for reading in the old data, overwriting | 945 | // blockbuffer is used for reading in the old data, overwriting |
931 | // with the new data, and performing ECC calculations | 946 | // with the new data, and performing ECC calculations |
932 | 947 | ||
@@ -938,7 +953,7 @@ sddr09_write_data(struct us_data *us, | |||
938 | blockbuffer = kmalloc(blocklen, GFP_NOIO); | 953 | blockbuffer = kmalloc(blocklen, GFP_NOIO); |
939 | if (!blockbuffer) { | 954 | if (!blockbuffer) { |
940 | printk("sddr09_write_data: Out of memory\n"); | 955 | printk("sddr09_write_data: Out of memory\n"); |
941 | return USB_STOR_TRANSPORT_ERROR; | 956 | return -ENOMEM; |
942 | } | 957 | } |
943 | 958 | ||
944 | // Since we don't write the user data directly to the device, | 959 | // Since we don't write the user data directly to the device, |
@@ -950,14 +965,10 @@ sddr09_write_data(struct us_data *us, | |||
950 | if (buffer == NULL) { | 965 | if (buffer == NULL) { |
951 | printk("sddr09_write_data: Out of memory\n"); | 966 | printk("sddr09_write_data: Out of memory\n"); |
952 | kfree(blockbuffer); | 967 | kfree(blockbuffer); |
953 | return USB_STOR_TRANSPORT_ERROR; | 968 | return -ENOMEM; |
954 | } | 969 | } |
955 | 970 | ||
956 | // Figure out the initial LBA and page | 971 | result = 0; |
957 | lba = address >> info->blockshift; | ||
958 | page = (address & info->blockmask); | ||
959 | |||
960 | result = USB_STOR_TRANSPORT_GOOD; | ||
961 | index = offset = 0; | 972 | index = offset = 0; |
962 | 973 | ||
963 | while (sectors > 0) { | 974 | while (sectors > 0) { |
@@ -967,13 +978,21 @@ sddr09_write_data(struct us_data *us, | |||
967 | pages = min(sectors, info->blocksize - page); | 978 | pages = min(sectors, info->blocksize - page); |
968 | len = (pages << info->pageshift); | 979 | len = (pages << info->pageshift); |
969 | 980 | ||
981 | /* Not overflowing capacity? */ | ||
982 | if (lba >= maxlba) { | ||
983 | US_DEBUGP("Error: Requested lba %u exceeds " | ||
984 | "maximum %u\n", lba, maxlba); | ||
985 | result = -EIO; | ||
986 | break; | ||
987 | } | ||
988 | |||
970 | // Get the data from the transfer buffer | 989 | // Get the data from the transfer buffer |
971 | usb_stor_access_xfer_buf(buffer, len, us->srb, | 990 | usb_stor_access_xfer_buf(buffer, len, us->srb, |
972 | &index, &offset, FROM_XFER_BUF); | 991 | &index, &offset, FROM_XFER_BUF); |
973 | 992 | ||
974 | result = sddr09_write_lba(us, lba, page, pages, | 993 | result = sddr09_write_lba(us, lba, page, pages, |
975 | buffer, blockbuffer); | 994 | buffer, blockbuffer); |
976 | if (result != USB_STOR_TRANSPORT_GOOD) | 995 | if (result) |
977 | break; | 996 | break; |
978 | 997 | ||
979 | page = 0; | 998 | page = 0; |
@@ -1022,7 +1041,7 @@ sddr09_read_deviceID(struct us_data *us, unsigned char *deviceID) { | |||
1022 | command[1] = LUNBITS; | 1041 | command[1] = LUNBITS; |
1023 | 1042 | ||
1024 | result = sddr09_send_scsi_command(us, command, 12); | 1043 | result = sddr09_send_scsi_command(us, command, 12); |
1025 | if (result != USB_STOR_TRANSPORT_GOOD) | 1044 | if (result) |
1026 | return result; | 1045 | return result; |
1027 | 1046 | ||
1028 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, | 1047 | result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, |
@@ -1031,8 +1050,7 @@ sddr09_read_deviceID(struct us_data *us, unsigned char *deviceID) { | |||
1031 | for (i = 0; i < 4; i++) | 1050 | for (i = 0; i < 4; i++) |
1032 | deviceID[i] = content[i]; | 1051 | deviceID[i] = content[i]; |
1033 | 1052 | ||
1034 | return (result == USB_STOR_XFER_GOOD ? | 1053 | return (result == USB_STOR_XFER_GOOD ? 0 : -EIO); |
1035 | USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR); | ||
1036 | } | 1054 | } |
1037 | 1055 | ||
1038 | static int | 1056 | static int |
@@ -1041,7 +1059,7 @@ sddr09_get_wp(struct us_data *us, struct sddr09_card_info *info) { | |||
1041 | unsigned char status; | 1059 | unsigned char status; |
1042 | 1060 | ||
1043 | result = sddr09_read_status(us, &status); | 1061 | result = sddr09_read_status(us, &status); |
1044 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1062 | if (result) { |
1045 | US_DEBUGP("sddr09_get_wp: read_status fails\n"); | 1063 | US_DEBUGP("sddr09_get_wp: read_status fails\n"); |
1046 | return result; | 1064 | return result; |
1047 | } | 1065 | } |
@@ -1057,7 +1075,7 @@ sddr09_get_wp(struct us_data *us, struct sddr09_card_info *info) { | |||
1057 | if (status & 0x1) | 1075 | if (status & 0x1) |
1058 | US_DEBUGP(" Error"); | 1076 | US_DEBUGP(" Error"); |
1059 | US_DEBUGP("\n"); | 1077 | US_DEBUGP("\n"); |
1060 | return USB_STOR_TRANSPORT_GOOD; | 1078 | return 0; |
1061 | } | 1079 | } |
1062 | 1080 | ||
1063 | #if 0 | 1081 | #if 0 |
@@ -1089,7 +1107,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) { | |||
1089 | 1107 | ||
1090 | result = sddr09_read_deviceID(us, deviceID); | 1108 | result = sddr09_read_deviceID(us, deviceID); |
1091 | 1109 | ||
1092 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1110 | if (result) { |
1093 | US_DEBUGP("Result of read_deviceID is %d\n", result); | 1111 | US_DEBUGP("Result of read_deviceID is %d\n", result); |
1094 | printk("sddr09: could not read card info\n"); | 1112 | printk("sddr09: could not read card info\n"); |
1095 | return NULL; | 1113 | return NULL; |
@@ -1200,7 +1218,7 @@ sddr09_read_map(struct us_data *us) { | |||
1200 | us, address>>1, | 1218 | us, address>>1, |
1201 | min(alloc_blocks, numblocks - i), | 1219 | min(alloc_blocks, numblocks - i), |
1202 | buffer, 0); | 1220 | buffer, 0); |
1203 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1221 | if (result) { |
1204 | result = -1; | 1222 | result = -1; |
1205 | goto done; | 1223 | goto done; |
1206 | } | 1224 | } |
@@ -1342,29 +1360,53 @@ sddr09_card_info_destructor(void *extra) { | |||
1342 | kfree(info->pba_to_lba); | 1360 | kfree(info->pba_to_lba); |
1343 | } | 1361 | } |
1344 | 1362 | ||
1345 | static void | 1363 | static int |
1346 | sddr09_init_card_info(struct us_data *us) { | 1364 | sddr09_common_init(struct us_data *us) { |
1347 | if (!us->extra) { | 1365 | int result; |
1348 | us->extra = kmalloc(sizeof(struct sddr09_card_info), GFP_NOIO); | 1366 | |
1349 | if (us->extra) { | 1367 | /* set the configuration -- STALL is an acceptable response here */ |
1350 | memset(us->extra, 0, sizeof(struct sddr09_card_info)); | 1368 | if (us->pusb_dev->actconfig->desc.bConfigurationValue != 1) { |
1351 | us->extra_destructor = sddr09_card_info_destructor; | 1369 | US_DEBUGP("active config #%d != 1 ??\n", us->pusb_dev |
1352 | } | 1370 | ->actconfig->desc.bConfigurationValue); |
1371 | return -EINVAL; | ||
1372 | } | ||
1373 | |||
1374 | result = usb_reset_configuration(us->pusb_dev); | ||
1375 | US_DEBUGP("Result of usb_reset_configuration is %d\n", result); | ||
1376 | if (result == -EPIPE) { | ||
1377 | US_DEBUGP("-- stall on control interface\n"); | ||
1378 | } else if (result != 0) { | ||
1379 | /* it's not a stall, but another error -- time to bail */ | ||
1380 | US_DEBUGP("-- Unknown error. Rejecting device\n"); | ||
1381 | return -EINVAL; | ||
1353 | } | 1382 | } |
1383 | |||
1384 | us->extra = kzalloc(sizeof(struct sddr09_card_info), GFP_NOIO); | ||
1385 | if (!us->extra) | ||
1386 | return -ENOMEM; | ||
1387 | us->extra_destructor = sddr09_card_info_destructor; | ||
1388 | |||
1389 | nand_init_ecc(); | ||
1390 | return 0; | ||
1354 | } | 1391 | } |
1355 | 1392 | ||
1393 | |||
1356 | /* | 1394 | /* |
1357 | * This is needed at a very early stage. If this is not listed in the | 1395 | * This is needed at a very early stage. If this is not listed in the |
1358 | * unusual devices list but called from here then LUN 0 of the combo reader | 1396 | * unusual devices list but called from here then LUN 0 of the combo reader |
1359 | * is not recognized. But I do not know what precisely these calls do. | 1397 | * is not recognized. But I do not know what precisely these calls do. |
1360 | */ | 1398 | */ |
1361 | int | 1399 | int |
1362 | sddr09_init(struct us_data *us) { | 1400 | usb_stor_sddr09_dpcm_init(struct us_data *us) { |
1363 | int result; | 1401 | int result; |
1364 | unsigned char *data = us->iobuf; | 1402 | unsigned char *data = us->iobuf; |
1365 | 1403 | ||
1404 | result = sddr09_common_init(us); | ||
1405 | if (result) | ||
1406 | return result; | ||
1407 | |||
1366 | result = sddr09_send_command(us, 0x01, USB_DIR_IN, data, 2); | 1408 | result = sddr09_send_command(us, 0x01, USB_DIR_IN, data, 2); |
1367 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1409 | if (result) { |
1368 | US_DEBUGP("sddr09_init: send_command fails\n"); | 1410 | US_DEBUGP("sddr09_init: send_command fails\n"); |
1369 | return result; | 1411 | return result; |
1370 | } | 1412 | } |
@@ -1373,7 +1415,7 @@ sddr09_init(struct us_data *us) { | |||
1373 | // get 07 02 | 1415 | // get 07 02 |
1374 | 1416 | ||
1375 | result = sddr09_send_command(us, 0x08, USB_DIR_IN, data, 2); | 1417 | result = sddr09_send_command(us, 0x08, USB_DIR_IN, data, 2); |
1376 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1418 | if (result) { |
1377 | US_DEBUGP("sddr09_init: 2nd send_command fails\n"); | 1419 | US_DEBUGP("sddr09_init: 2nd send_command fails\n"); |
1378 | return result; | 1420 | return result; |
1379 | } | 1421 | } |
@@ -1382,7 +1424,7 @@ sddr09_init(struct us_data *us) { | |||
1382 | // get 07 00 | 1424 | // get 07 00 |
1383 | 1425 | ||
1384 | result = sddr09_request_sense(us, data, 18); | 1426 | result = sddr09_request_sense(us, data, 18); |
1385 | if (result == USB_STOR_TRANSPORT_GOOD && data[2] != 0) { | 1427 | if (result == 0 && data[2] != 0) { |
1386 | int j; | 1428 | int j; |
1387 | for (j=0; j<18; j++) | 1429 | for (j=0; j<18; j++) |
1388 | printk(" %02X", data[j]); | 1430 | printk(" %02X", data[j]); |
@@ -1398,7 +1440,7 @@ sddr09_init(struct us_data *us) { | |||
1398 | 1440 | ||
1399 | // test unit ready | 1441 | // test unit ready |
1400 | 1442 | ||
1401 | return USB_STOR_TRANSPORT_GOOD; /* not result */ | 1443 | return 0; /* not result */ |
1402 | } | 1444 | } |
1403 | 1445 | ||
1404 | /* | 1446 | /* |
@@ -1427,13 +1469,6 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1427 | }; | 1469 | }; |
1428 | 1470 | ||
1429 | info = (struct sddr09_card_info *)us->extra; | 1471 | info = (struct sddr09_card_info *)us->extra; |
1430 | if (!info) { | ||
1431 | nand_init_ecc(); | ||
1432 | sddr09_init_card_info(us); | ||
1433 | info = (struct sddr09_card_info *)us->extra; | ||
1434 | if (!info) | ||
1435 | return USB_STOR_TRANSPORT_ERROR; | ||
1436 | } | ||
1437 | 1472 | ||
1438 | if (srb->cmnd[0] == REQUEST_SENSE && havefakesense) { | 1473 | if (srb->cmnd[0] == REQUEST_SENSE && havefakesense) { |
1439 | /* for a faked command, we have to follow with a faked sense */ | 1474 | /* for a faked command, we have to follow with a faked sense */ |
@@ -1536,7 +1571,9 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1536 | US_DEBUGP("READ_10: read page %d pagect %d\n", | 1571 | US_DEBUGP("READ_10: read page %d pagect %d\n", |
1537 | page, pages); | 1572 | page, pages); |
1538 | 1573 | ||
1539 | return sddr09_read_data(us, page, pages); | 1574 | result = sddr09_read_data(us, page, pages); |
1575 | return (result == 0 ? USB_STOR_TRANSPORT_GOOD : | ||
1576 | USB_STOR_TRANSPORT_ERROR); | ||
1540 | } | 1577 | } |
1541 | 1578 | ||
1542 | if (srb->cmnd[0] == WRITE_10) { | 1579 | if (srb->cmnd[0] == WRITE_10) { |
@@ -1549,7 +1586,9 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1549 | US_DEBUGP("WRITE_10: write page %d pagect %d\n", | 1586 | US_DEBUGP("WRITE_10: write page %d pagect %d\n", |
1550 | page, pages); | 1587 | page, pages); |
1551 | 1588 | ||
1552 | return sddr09_write_data(us, page, pages); | 1589 | result = sddr09_write_data(us, page, pages); |
1590 | return (result == 0 ? USB_STOR_TRANSPORT_GOOD : | ||
1591 | USB_STOR_TRANSPORT_ERROR); | ||
1553 | } | 1592 | } |
1554 | 1593 | ||
1555 | /* catch-all for all other commands, except | 1594 | /* catch-all for all other commands, except |
@@ -1575,10 +1614,10 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1575 | US_DEBUGP("SDDR09: Send control for command %s\n", ptr); | 1614 | US_DEBUGP("SDDR09: Send control for command %s\n", ptr); |
1576 | 1615 | ||
1577 | result = sddr09_send_scsi_command(us, srb->cmnd, 12); | 1616 | result = sddr09_send_scsi_command(us, srb->cmnd, 12); |
1578 | if (result != USB_STOR_TRANSPORT_GOOD) { | 1617 | if (result) { |
1579 | US_DEBUGP("sddr09_transport: sddr09_send_scsi_command " | 1618 | US_DEBUGP("sddr09_transport: sddr09_send_scsi_command " |
1580 | "returns %d\n", result); | 1619 | "returns %d\n", result); |
1581 | return result; | 1620 | return USB_STOR_TRANSPORT_ERROR; |
1582 | } | 1621 | } |
1583 | 1622 | ||
1584 | if (srb->request_bufflen == 0) | 1623 | if (srb->request_bufflen == 0) |
@@ -1606,3 +1645,10 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1606 | return USB_STOR_TRANSPORT_GOOD; | 1645 | return USB_STOR_TRANSPORT_GOOD; |
1607 | } | 1646 | } |
1608 | 1647 | ||
1648 | /* | ||
1649 | * Initialization routine for the sddr09 subdriver | ||
1650 | */ | ||
1651 | int | ||
1652 | usb_stor_sddr09_init(struct us_data *us) { | ||
1653 | return sddr09_common_init(us); | ||
1654 | } | ||
diff --git a/drivers/usb/storage/sddr09.h b/drivers/usb/storage/sddr09.h index c9d78d6188b1..c03089a9ec38 100644 --- a/drivers/usb/storage/sddr09.h +++ b/drivers/usb/storage/sddr09.h | |||
@@ -31,18 +31,7 @@ | |||
31 | 31 | ||
32 | extern int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us); | 32 | extern int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us); |
33 | 33 | ||
34 | struct sddr09_card_info { | 34 | extern int usb_stor_sddr09_dpcm_init(struct us_data *us); |
35 | unsigned long capacity; /* Size of card in bytes */ | 35 | extern int usb_stor_sddr09_init(struct us_data *us); |
36 | int pagesize; /* Size of page in bytes */ | ||
37 | int pageshift; /* log2 of pagesize */ | ||
38 | int blocksize; /* Size of block in pages */ | ||
39 | int blockshift; /* log2 of blocksize */ | ||
40 | int blockmask; /* 2^blockshift - 1 */ | ||
41 | int *lba_to_pba; /* logical to physical map */ | ||
42 | int *pba_to_lba; /* physical to logical map */ | ||
43 | int lbact; /* number of available pages */ | ||
44 | int flags; | ||
45 | #define SDDR09_WP 1 /* write protected */ | ||
46 | }; | ||
47 | 36 | ||
48 | #endif | 37 | #endif |
diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h index 0a362cc781ad..633a715850a4 100644 --- a/drivers/usb/storage/transport.h +++ b/drivers/usb/storage/transport.h | |||
@@ -41,39 +41,8 @@ | |||
41 | #ifndef _TRANSPORT_H_ | 41 | #ifndef _TRANSPORT_H_ |
42 | #define _TRANSPORT_H_ | 42 | #define _TRANSPORT_H_ |
43 | 43 | ||
44 | #include <linux/config.h> | ||
45 | #include <linux/blkdev.h> | 44 | #include <linux/blkdev.h> |
46 | 45 | ||
47 | /* Protocols */ | ||
48 | |||
49 | #define US_PR_CBI 0x00 /* Control/Bulk/Interrupt */ | ||
50 | #define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */ | ||
51 | #define US_PR_BULK 0x50 /* bulk only */ | ||
52 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
53 | #define US_PR_USBAT 0x80 /* SCM-ATAPI bridge */ | ||
54 | #endif | ||
55 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
56 | #define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */ | ||
57 | #endif | ||
58 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
59 | #define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */ | ||
60 | #endif | ||
61 | #define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */ | ||
62 | |||
63 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
64 | #define US_PR_FREECOM 0xf1 /* Freecom */ | ||
65 | #endif | ||
66 | |||
67 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
68 | #define US_PR_DATAFAB 0xf2 /* Datafab chipsets */ | ||
69 | #endif | ||
70 | |||
71 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | ||
72 | #define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */ | ||
73 | #endif | ||
74 | |||
75 | #define US_PR_DEVICE 0xff /* Use device's value */ | ||
76 | |||
77 | /* | 46 | /* |
78 | * Bulk only data structures | 47 | * Bulk only data structures |
79 | */ | 48 | */ |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index f5f47a34b168..dc301e567cfc 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -79,13 +79,6 @@ UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, | |||
79 | US_SC_8070, US_PR_USBAT, init_usbat, 0), | 79 | US_SC_8070, US_PR_USBAT, init_usbat, 0), |
80 | #endif | 80 | #endif |
81 | 81 | ||
82 | /* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */ | ||
83 | UNUSUAL_DEV( 0x040d, 0x6205, 0x0003, 0x0003, | ||
84 | "VIA Technologies Inc.", | ||
85 | "USB 2.0 Card Reader", | ||
86 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
87 | US_FL_IGNORE_RESIDUE ), | ||
88 | |||
89 | /* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net> | 82 | /* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net> |
90 | * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product) | 83 | * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product) |
91 | * for USB floppies that need the SINGLE_LUN enforcement. | 84 | * for USB floppies that need the SINGLE_LUN enforcement. |
@@ -96,6 +89,13 @@ UNUSUAL_DEV( 0x0409, 0x0040, 0x0000, 0x9999, | |||
96 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 89 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
97 | US_FL_SINGLE_LUN ), | 90 | US_FL_SINGLE_LUN ), |
98 | 91 | ||
92 | /* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */ | ||
93 | UNUSUAL_DEV( 0x040d, 0x6205, 0x0003, 0x0003, | ||
94 | "VIA Technologies Inc.", | ||
95 | "USB 2.0 Card Reader", | ||
96 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
97 | US_FL_IGNORE_RESIDUE ), | ||
98 | |||
99 | /* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au> | 99 | /* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au> |
100 | * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message | 100 | * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message |
101 | * always fails and confuses drive. | 101 | * always fails and confuses drive. |
@@ -187,6 +187,14 @@ UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, | |||
187 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 187 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
188 | US_FL_FIX_CAPACITY), | 188 | US_FL_FIX_CAPACITY), |
189 | 189 | ||
190 | /* Patch for Nikon coolpix 2000 | ||
191 | * Submitted by Fabien Cosse <fabien.cosse@wanadoo.fr>*/ | ||
192 | UNUSUAL_DEV( 0x04b0, 0x0301, 0x0010, 0x0010, | ||
193 | "NIKON", | ||
194 | "NIKON DSC E2000", | ||
195 | US_SC_DEVICE, US_PR_DEVICE,NULL, | ||
196 | US_FL_NOT_LOCKABLE ), | ||
197 | |||
190 | /* BENQ DC5330 | 198 | /* BENQ DC5330 |
191 | * Reported by Manuel Fombuena <mfombuena@ya.com> and | 199 | * Reported by Manuel Fombuena <mfombuena@ya.com> and |
192 | * Frank Copeland <fjc@thingy.apana.org.au> */ | 200 | * Frank Copeland <fjc@thingy.apana.org.au> */ |
@@ -276,14 +284,14 @@ UNUSUAL_DEV( 0x04e6, 0x0002, 0x0100, 0x0100, | |||
276 | UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999, | 284 | UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999, |
277 | "Sandisk", | 285 | "Sandisk", |
278 | "ImageMate SDDR09", | 286 | "ImageMate SDDR09", |
279 | US_SC_SCSI, US_PR_EUSB_SDDR09, NULL, | 287 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, |
280 | US_FL_SINGLE_LUN ), | 288 | 0), |
281 | 289 | ||
282 | /* This entry is from Andries.Brouwer@cwi.nl */ | 290 | /* This entry is from Andries.Brouwer@cwi.nl */ |
283 | UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, | 291 | UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, |
284 | "SCM Microsystems", | 292 | "SCM Microsystems", |
285 | "eUSB SmartMedia / CompactFlash Adapter", | 293 | "eUSB SmartMedia / CompactFlash Adapter", |
286 | US_SC_SCSI, US_PR_DPCM_USB, sddr09_init, | 294 | US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init, |
287 | 0), | 295 | 0), |
288 | #endif | 296 | #endif |
289 | 297 | ||
@@ -527,6 +535,13 @@ UNUSUAL_DEV( 0x057b, 0x0022, 0x0000, 0x9999, | |||
527 | "Silicon Media R/W", | 535 | "Silicon Media R/W", |
528 | US_SC_DEVICE, US_PR_DEVICE, NULL, 0), | 536 | US_SC_DEVICE, US_PR_DEVICE, NULL, 0), |
529 | 537 | ||
538 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
539 | UNUSUAL_DEV( 0x0584, 0x0008, 0x0102, 0x0102, | ||
540 | "Fujifilm", | ||
541 | "DPC-R1 (Alauda)", | ||
542 | US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ), | ||
543 | #endif | ||
544 | |||
530 | /* Fabrizio Fellini <fello@libero.it> */ | 545 | /* Fabrizio Fellini <fello@libero.it> */ |
531 | UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, | 546 | UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, |
532 | "Fujifilm", | 547 | "Fujifilm", |
@@ -673,8 +688,8 @@ UNUSUAL_DEV( 0x0644, 0x0000, 0x0100, 0x0100, | |||
673 | UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100, | 688 | UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100, |
674 | "Olympus", | 689 | "Olympus", |
675 | "Camedia MAUSB-2", | 690 | "Camedia MAUSB-2", |
676 | US_SC_SCSI, US_PR_EUSB_SDDR09, NULL, | 691 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, |
677 | US_FL_SINGLE_LUN ), | 692 | 0), |
678 | #endif | 693 | #endif |
679 | 694 | ||
680 | /* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */ | 695 | /* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */ |
@@ -739,8 +754,8 @@ UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100, | |||
739 | UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999, | 754 | UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999, |
740 | "Sandisk", | 755 | "Sandisk", |
741 | "ImageMate SDDR-09", | 756 | "ImageMate SDDR-09", |
742 | US_SC_SCSI, US_PR_EUSB_SDDR09, NULL, | 757 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, |
743 | US_FL_SINGLE_LUN ), | 758 | 0), |
744 | #endif | 759 | #endif |
745 | 760 | ||
746 | #ifdef CONFIG_USB_STORAGE_FREECOM | 761 | #ifdef CONFIG_USB_STORAGE_FREECOM |
@@ -776,6 +791,13 @@ UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, | |||
776 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ), | 791 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ), |
777 | #endif | 792 | #endif |
778 | 793 | ||
794 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
795 | UNUSUAL_DEV( 0x07b4, 0x010a, 0x0102, 0x0102, | ||
796 | "Olympus", | ||
797 | "MAUSB-10 (Alauda)", | ||
798 | US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ), | ||
799 | #endif | ||
800 | |||
779 | #ifdef CONFIG_USB_STORAGE_DATAFAB | 801 | #ifdef CONFIG_USB_STORAGE_DATAFAB |
780 | UNUSUAL_DEV( 0x07c4, 0xa000, 0x0000, 0x0015, | 802 | UNUSUAL_DEV( 0x07c4, 0xa000, 0x0000, 0x0015, |
781 | "Datafab", | 803 | "Datafab", |
@@ -1134,3 +1156,27 @@ UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999, | |||
1134 | US_SC_SCSI, US_PR_SDDR55, NULL, | 1156 | US_SC_SCSI, US_PR_SDDR55, NULL, |
1135 | US_FL_SINGLE_LUN), | 1157 | US_FL_SINGLE_LUN), |
1136 | #endif | 1158 | #endif |
1159 | |||
1160 | /* Control/Bulk transport for all SubClass values */ | ||
1161 | USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), | ||
1162 | USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), | ||
1163 | USUAL_DEV(US_SC_QIC, US_PR_CB, USB_US_TYPE_STOR), | ||
1164 | USUAL_DEV(US_SC_UFI, US_PR_CB, USB_US_TYPE_STOR), | ||
1165 | USUAL_DEV(US_SC_8070, US_PR_CB, USB_US_TYPE_STOR), | ||
1166 | USUAL_DEV(US_SC_SCSI, US_PR_CB, USB_US_TYPE_STOR), | ||
1167 | |||
1168 | /* Control/Bulk/Interrupt transport for all SubClass values */ | ||
1169 | USUAL_DEV(US_SC_RBC, US_PR_CBI, USB_US_TYPE_STOR), | ||
1170 | USUAL_DEV(US_SC_8020, US_PR_CBI, USB_US_TYPE_STOR), | ||
1171 | USUAL_DEV(US_SC_QIC, US_PR_CBI, USB_US_TYPE_STOR), | ||
1172 | USUAL_DEV(US_SC_UFI, US_PR_CBI, USB_US_TYPE_STOR), | ||
1173 | USUAL_DEV(US_SC_8070, US_PR_CBI, USB_US_TYPE_STOR), | ||
1174 | USUAL_DEV(US_SC_SCSI, US_PR_CBI, USB_US_TYPE_STOR), | ||
1175 | |||
1176 | /* Bulk-only transport for all SubClass values */ | ||
1177 | USUAL_DEV(US_SC_RBC, US_PR_BULK, USB_US_TYPE_STOR), | ||
1178 | USUAL_DEV(US_SC_8020, US_PR_BULK, USB_US_TYPE_STOR), | ||
1179 | USUAL_DEV(US_SC_QIC, US_PR_BULK, USB_US_TYPE_STOR), | ||
1180 | USUAL_DEV(US_SC_UFI, US_PR_BULK, USB_US_TYPE_STOR), | ||
1181 | USUAL_DEV(US_SC_8070, US_PR_BULK, USB_US_TYPE_STOR), | ||
1182 | USUAL_DEV(US_SC_SCSI, US_PR_BULK, 0), | ||
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 3847ebed2aa4..dbcf23980ff1 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -94,6 +94,9 @@ | |||
94 | #ifdef CONFIG_USB_STORAGE_ONETOUCH | 94 | #ifdef CONFIG_USB_STORAGE_ONETOUCH |
95 | #include "onetouch.h" | 95 | #include "onetouch.h" |
96 | #endif | 96 | #endif |
97 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
98 | #include "alauda.h" | ||
99 | #endif | ||
97 | 100 | ||
98 | /* Some informational data */ | 101 | /* Some informational data */ |
99 | MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); | 102 | MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); |
@@ -112,49 +115,33 @@ static atomic_t total_threads = ATOMIC_INIT(0); | |||
112 | static DECLARE_COMPLETION(threads_gone); | 115 | static DECLARE_COMPLETION(threads_gone); |
113 | 116 | ||
114 | 117 | ||
115 | /* The entries in this table, except for final ones here | 118 | /* |
116 | * (USB_MASS_STORAGE_CLASS and the empty entry), correspond, | 119 | * The entries in this table correspond, line for line, |
117 | * line for line with the entries of us_unsuaul_dev_list[]. | 120 | * with the entries of us_unusual_dev_list[]. |
118 | */ | 121 | */ |
122 | #ifndef CONFIG_USB_LIBUSUAL | ||
119 | 123 | ||
120 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | 124 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ |
121 | vendorName, productName,useProtocol, useTransport, \ | 125 | vendorName, productName,useProtocol, useTransport, \ |
122 | initFunction, flags) \ | 126 | initFunction, flags) \ |
123 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax) } | 127 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ |
128 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
129 | |||
130 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
131 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
132 | .driver_info = (USB_US_TYPE_STOR<<24) } | ||
124 | 133 | ||
125 | static struct usb_device_id storage_usb_ids [] = { | 134 | static struct usb_device_id storage_usb_ids [] = { |
126 | 135 | ||
127 | # include "unusual_devs.h" | 136 | # include "unusual_devs.h" |
128 | #undef UNUSUAL_DEV | 137 | #undef UNUSUAL_DEV |
129 | /* Control/Bulk transport for all SubClass values */ | 138 | #undef USUAL_DEV |
130 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CB) }, | ||
131 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CB) }, | ||
132 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CB) }, | ||
133 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CB) }, | ||
134 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CB) }, | ||
135 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CB) }, | ||
136 | |||
137 | /* Control/Bulk/Interrupt transport for all SubClass values */ | ||
138 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CBI) }, | ||
139 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CBI) }, | ||
140 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CBI) }, | ||
141 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CBI) }, | ||
142 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CBI) }, | ||
143 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CBI) }, | ||
144 | |||
145 | /* Bulk-only transport for all SubClass values */ | ||
146 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_BULK) }, | ||
147 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_BULK) }, | ||
148 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_BULK) }, | ||
149 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_BULK) }, | ||
150 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_BULK) }, | ||
151 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) }, | ||
152 | |||
153 | /* Terminating entry */ | 139 | /* Terminating entry */ |
154 | { } | 140 | { } |
155 | }; | 141 | }; |
156 | 142 | ||
157 | MODULE_DEVICE_TABLE (usb, storage_usb_ids); | 143 | MODULE_DEVICE_TABLE (usb, storage_usb_ids); |
144 | #endif /* CONFIG_USB_LIBUSUAL */ | ||
158 | 145 | ||
159 | /* This is the list of devices we recognize, along with their flag data */ | 146 | /* This is the list of devices we recognize, along with their flag data */ |
160 | 147 | ||
@@ -167,7 +154,6 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids); | |||
167 | * are free to use as many characters as you like. | 154 | * are free to use as many characters as you like. |
168 | */ | 155 | */ |
169 | 156 | ||
170 | #undef UNUSUAL_DEV | ||
171 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | 157 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ |
172 | vendor_name, product_name, use_protocol, use_transport, \ | 158 | vendor_name, product_name, use_protocol, use_transport, \ |
173 | init_function, Flags) \ | 159 | init_function, Flags) \ |
@@ -177,53 +163,18 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids); | |||
177 | .useProtocol = use_protocol, \ | 163 | .useProtocol = use_protocol, \ |
178 | .useTransport = use_transport, \ | 164 | .useTransport = use_transport, \ |
179 | .initFunction = init_function, \ | 165 | .initFunction = init_function, \ |
180 | .flags = Flags, \ | 166 | } |
167 | |||
168 | #define USUAL_DEV(use_protocol, use_transport, use_type) \ | ||
169 | { \ | ||
170 | .useProtocol = use_protocol, \ | ||
171 | .useTransport = use_transport, \ | ||
181 | } | 172 | } |
182 | 173 | ||
183 | static struct us_unusual_dev us_unusual_dev_list[] = { | 174 | static struct us_unusual_dev us_unusual_dev_list[] = { |
184 | # include "unusual_devs.h" | 175 | # include "unusual_devs.h" |
185 | # undef UNUSUAL_DEV | 176 | # undef UNUSUAL_DEV |
186 | /* Control/Bulk transport for all SubClass values */ | 177 | # undef USUAL_DEV |
187 | { .useProtocol = US_SC_RBC, | ||
188 | .useTransport = US_PR_CB}, | ||
189 | { .useProtocol = US_SC_8020, | ||
190 | .useTransport = US_PR_CB}, | ||
191 | { .useProtocol = US_SC_QIC, | ||
192 | .useTransport = US_PR_CB}, | ||
193 | { .useProtocol = US_SC_UFI, | ||
194 | .useTransport = US_PR_CB}, | ||
195 | { .useProtocol = US_SC_8070, | ||
196 | .useTransport = US_PR_CB}, | ||
197 | { .useProtocol = US_SC_SCSI, | ||
198 | .useTransport = US_PR_CB}, | ||
199 | |||
200 | /* Control/Bulk/Interrupt transport for all SubClass values */ | ||
201 | { .useProtocol = US_SC_RBC, | ||
202 | .useTransport = US_PR_CBI}, | ||
203 | { .useProtocol = US_SC_8020, | ||
204 | .useTransport = US_PR_CBI}, | ||
205 | { .useProtocol = US_SC_QIC, | ||
206 | .useTransport = US_PR_CBI}, | ||
207 | { .useProtocol = US_SC_UFI, | ||
208 | .useTransport = US_PR_CBI}, | ||
209 | { .useProtocol = US_SC_8070, | ||
210 | .useTransport = US_PR_CBI}, | ||
211 | { .useProtocol = US_SC_SCSI, | ||
212 | .useTransport = US_PR_CBI}, | ||
213 | |||
214 | /* Bulk-only transport for all SubClass values */ | ||
215 | { .useProtocol = US_SC_RBC, | ||
216 | .useTransport = US_PR_BULK}, | ||
217 | { .useProtocol = US_SC_8020, | ||
218 | .useTransport = US_PR_BULK}, | ||
219 | { .useProtocol = US_SC_QIC, | ||
220 | .useTransport = US_PR_BULK}, | ||
221 | { .useProtocol = US_SC_UFI, | ||
222 | .useTransport = US_PR_BULK}, | ||
223 | { .useProtocol = US_SC_8070, | ||
224 | .useTransport = US_PR_BULK}, | ||
225 | { .useProtocol = US_SC_SCSI, | ||
226 | .useTransport = US_PR_BULK}, | ||
227 | 178 | ||
228 | /* Terminating entry */ | 179 | /* Terminating entry */ |
229 | { NULL } | 180 | { NULL } |
@@ -240,6 +191,8 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) | |||
240 | down(&us->dev_semaphore); | 191 | down(&us->dev_semaphore); |
241 | 192 | ||
242 | US_DEBUGP("%s\n", __FUNCTION__); | 193 | US_DEBUGP("%s\n", __FUNCTION__); |
194 | if (us->suspend_resume_hook) | ||
195 | (us->suspend_resume_hook)(us, US_SUSPEND); | ||
243 | iface->dev.power.power_state.event = message.event; | 196 | iface->dev.power.power_state.event = message.event; |
244 | 197 | ||
245 | /* When runtime PM is working, we'll set a flag to indicate | 198 | /* When runtime PM is working, we'll set a flag to indicate |
@@ -256,6 +209,8 @@ static int storage_resume(struct usb_interface *iface) | |||
256 | down(&us->dev_semaphore); | 209 | down(&us->dev_semaphore); |
257 | 210 | ||
258 | US_DEBUGP("%s\n", __FUNCTION__); | 211 | US_DEBUGP("%s\n", __FUNCTION__); |
212 | if (us->suspend_resume_hook) | ||
213 | (us->suspend_resume_hook)(us, US_RESUME); | ||
259 | iface->dev.power.power_state.event = PM_EVENT_ON; | 214 | iface->dev.power.power_state.event = PM_EVENT_ON; |
260 | 215 | ||
261 | up(&us->dev_semaphore); | 216 | up(&us->dev_semaphore); |
@@ -484,14 +439,20 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf) | |||
484 | return 0; | 439 | return 0; |
485 | } | 440 | } |
486 | 441 | ||
442 | /* Find an unusual_dev descriptor (always succeeds in the current code) */ | ||
443 | static struct us_unusual_dev *find_unusual(const struct usb_device_id *id) | ||
444 | { | ||
445 | const int id_index = id - storage_usb_ids; | ||
446 | return &us_unusual_dev_list[id_index]; | ||
447 | } | ||
448 | |||
487 | /* Get the unusual_devs entries and the string descriptors */ | 449 | /* Get the unusual_devs entries and the string descriptors */ |
488 | static void get_device_info(struct us_data *us, int id_index) | 450 | static void get_device_info(struct us_data *us, const struct usb_device_id *id) |
489 | { | 451 | { |
490 | struct usb_device *dev = us->pusb_dev; | 452 | struct usb_device *dev = us->pusb_dev; |
491 | struct usb_interface_descriptor *idesc = | 453 | struct usb_interface_descriptor *idesc = |
492 | &us->pusb_intf->cur_altsetting->desc; | 454 | &us->pusb_intf->cur_altsetting->desc; |
493 | struct us_unusual_dev *unusual_dev = &us_unusual_dev_list[id_index]; | 455 | struct us_unusual_dev *unusual_dev = find_unusual(id); |
494 | struct usb_device_id *id = &storage_usb_ids[id_index]; | ||
495 | 456 | ||
496 | /* Store the entries */ | 457 | /* Store the entries */ |
497 | us->unusual_dev = unusual_dev; | 458 | us->unusual_dev = unusual_dev; |
@@ -501,7 +462,7 @@ static void get_device_info(struct us_data *us, int id_index) | |||
501 | us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ? | 462 | us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ? |
502 | idesc->bInterfaceProtocol : | 463 | idesc->bInterfaceProtocol : |
503 | unusual_dev->useTransport; | 464 | unusual_dev->useTransport; |
504 | us->flags = unusual_dev->flags; | 465 | us->flags = USB_US_ORIG_FLAGS(id->driver_info); |
505 | 466 | ||
506 | /* | 467 | /* |
507 | * This flag is only needed when we're in high-speed, so let's | 468 | * This flag is only needed when we're in high-speed, so let's |
@@ -516,7 +477,7 @@ static void get_device_info(struct us_data *us, int id_index) | |||
516 | * from the unusual_devs.h table. | 477 | * from the unusual_devs.h table. |
517 | */ | 478 | */ |
518 | if (id->idVendor || id->idProduct) { | 479 | if (id->idVendor || id->idProduct) { |
519 | static char *msgs[3] = { | 480 | static const char *msgs[3] = { |
520 | "an unneeded SubClass entry", | 481 | "an unneeded SubClass entry", |
521 | "an unneeded Protocol entry", | 482 | "an unneeded Protocol entry", |
522 | "unneeded SubClass and Protocol entries"}; | 483 | "unneeded SubClass and Protocol entries"}; |
@@ -529,7 +490,7 @@ static void get_device_info(struct us_data *us, int id_index) | |||
529 | if (unusual_dev->useTransport != US_PR_DEVICE && | 490 | if (unusual_dev->useTransport != US_PR_DEVICE && |
530 | us->protocol == idesc->bInterfaceProtocol) | 491 | us->protocol == idesc->bInterfaceProtocol) |
531 | msg += 2; | 492 | msg += 2; |
532 | if (msg >= 0 && !(unusual_dev->flags & US_FL_NEED_OVERRIDE)) | 493 | if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE)) |
533 | printk(KERN_NOTICE USB_STORAGE "This device " | 494 | printk(KERN_NOTICE USB_STORAGE "This device " |
534 | "(%04x,%04x,%04x S %02x P %02x)" | 495 | "(%04x,%04x,%04x S %02x P %02x)" |
535 | " has %s in unusual_devs.h\n" | 496 | " has %s in unusual_devs.h\n" |
@@ -686,6 +647,15 @@ static int get_protocol(struct us_data *us) | |||
686 | break; | 647 | break; |
687 | #endif | 648 | #endif |
688 | 649 | ||
650 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
651 | case US_PR_ALAUDA: | ||
652 | us->transport_name = "Alauda Control/Bulk"; | ||
653 | us->transport = alauda_transport; | ||
654 | us->transport_reset = usb_stor_Bulk_reset; | ||
655 | us->max_lun = 1; | ||
656 | break; | ||
657 | #endif | ||
658 | |||
689 | default: | 659 | default: |
690 | return -EIO; | 660 | return -EIO; |
691 | } | 661 | } |
@@ -921,10 +891,12 @@ static int storage_probe(struct usb_interface *intf, | |||
921 | { | 891 | { |
922 | struct Scsi_Host *host; | 892 | struct Scsi_Host *host; |
923 | struct us_data *us; | 893 | struct us_data *us; |
924 | const int id_index = id - storage_usb_ids; | ||
925 | int result; | 894 | int result; |
926 | struct task_struct *th; | 895 | struct task_struct *th; |
927 | 896 | ||
897 | if (usb_usual_check_type(id, USB_US_TYPE_STOR)) | ||
898 | return -ENXIO; | ||
899 | |||
928 | US_DEBUGP("USB Mass Storage device detected\n"); | 900 | US_DEBUGP("USB Mass Storage device detected\n"); |
929 | 901 | ||
930 | /* | 902 | /* |
@@ -957,29 +929,7 @@ static int storage_probe(struct usb_interface *intf, | |||
957 | * of the match from the usb_device_id table, so we can find the | 929 | * of the match from the usb_device_id table, so we can find the |
958 | * corresponding entry in the private table. | 930 | * corresponding entry in the private table. |
959 | */ | 931 | */ |
960 | get_device_info(us, id_index); | 932 | get_device_info(us, id); |
961 | |||
962 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
963 | if (us->protocol == US_PR_EUSB_SDDR09 || | ||
964 | us->protocol == US_PR_DPCM_USB) { | ||
965 | /* set the configuration -- STALL is an acceptable response here */ | ||
966 | if (us->pusb_dev->actconfig->desc.bConfigurationValue != 1) { | ||
967 | US_DEBUGP("active config #%d != 1 ??\n", us->pusb_dev | ||
968 | ->actconfig->desc.bConfigurationValue); | ||
969 | goto BadDevice; | ||
970 | } | ||
971 | result = usb_reset_configuration(us->pusb_dev); | ||
972 | |||
973 | US_DEBUGP("Result of usb_reset_configuration is %d\n", result); | ||
974 | if (result == -EPIPE) { | ||
975 | US_DEBUGP("-- stall on control interface\n"); | ||
976 | } else if (result != 0) { | ||
977 | /* it's not a stall, but another error -- time to bail */ | ||
978 | US_DEBUGP("-- Unknown error. Rejecting device\n"); | ||
979 | goto BadDevice; | ||
980 | } | ||
981 | } | ||
982 | #endif | ||
983 | 933 | ||
984 | /* Get the transport, protocol, and pipe settings */ | 934 | /* Get the transport, protocol, and pipe settings */ |
985 | result = get_transport(us); | 935 | result = get_transport(us); |
@@ -1044,7 +994,6 @@ static void storage_disconnect(struct usb_interface *intf) | |||
1044 | ***********************************************************************/ | 994 | ***********************************************************************/ |
1045 | 995 | ||
1046 | static struct usb_driver usb_storage_driver = { | 996 | static struct usb_driver usb_storage_driver = { |
1047 | .owner = THIS_MODULE, | ||
1048 | .name = "usb-storage", | 997 | .name = "usb-storage", |
1049 | .probe = storage_probe, | 998 | .probe = storage_probe, |
1050 | .disconnect = storage_disconnect, | 999 | .disconnect = storage_disconnect, |
@@ -1062,9 +1011,10 @@ static int __init usb_stor_init(void) | |||
1062 | 1011 | ||
1063 | /* register the driver, return usb_register return code if error */ | 1012 | /* register the driver, return usb_register return code if error */ |
1064 | retval = usb_register(&usb_storage_driver); | 1013 | retval = usb_register(&usb_storage_driver); |
1065 | if (retval == 0) | 1014 | if (retval == 0) { |
1066 | printk(KERN_INFO "USB Mass Storage support registered.\n"); | 1015 | printk(KERN_INFO "USB Mass Storage support registered.\n"); |
1067 | 1016 | usb_usual_set_present(USB_US_TYPE_STOR); | |
1017 | } | ||
1068 | return retval; | 1018 | return retval; |
1069 | } | 1019 | } |
1070 | 1020 | ||
@@ -1088,6 +1038,8 @@ static void __exit usb_stor_exit(void) | |||
1088 | wait_for_completion(&threads_gone); | 1038 | wait_for_completion(&threads_gone); |
1089 | atomic_dec(&total_threads); | 1039 | atomic_dec(&total_threads); |
1090 | } | 1040 | } |
1041 | |||
1042 | usb_usual_clear_present(USB_US_TYPE_STOR); | ||
1091 | } | 1043 | } |
1092 | 1044 | ||
1093 | module_init(usb_stor_init); | 1045 | module_init(usb_stor_init); |
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 98b09711a739..7259fd1f6b0d 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h | |||
@@ -45,6 +45,7 @@ | |||
45 | #define _USB_H_ | 45 | #define _USB_H_ |
46 | 46 | ||
47 | #include <linux/usb.h> | 47 | #include <linux/usb.h> |
48 | #include <linux/usb_usual.h> | ||
48 | #include <linux/blkdev.h> | 49 | #include <linux/blkdev.h> |
49 | #include <linux/smp_lock.h> | 50 | #include <linux/smp_lock.h> |
50 | #include <linux/completion.h> | 51 | #include <linux/completion.h> |
@@ -63,38 +64,8 @@ struct us_unusual_dev { | |||
63 | __u8 useProtocol; | 64 | __u8 useProtocol; |
64 | __u8 useTransport; | 65 | __u8 useTransport; |
65 | int (*initFunction)(struct us_data *); | 66 | int (*initFunction)(struct us_data *); |
66 | unsigned int flags; | ||
67 | }; | 67 | }; |
68 | 68 | ||
69 | /* | ||
70 | * Static flag definitions. We use this roundabout technique so that the | ||
71 | * proc_info() routine can automatically display a message for each flag. | ||
72 | */ | ||
73 | #define US_DO_ALL_FLAGS \ | ||
74 | US_FLAG(SINGLE_LUN, 0x00000001) \ | ||
75 | /* allow access to only LUN 0 */ \ | ||
76 | US_FLAG(NEED_OVERRIDE, 0x00000002) \ | ||
77 | /* unusual_devs entry is necessary */ \ | ||
78 | US_FLAG(SCM_MULT_TARG, 0x00000004) \ | ||
79 | /* supports multiple targets */ \ | ||
80 | US_FLAG(FIX_INQUIRY, 0x00000008) \ | ||
81 | /* INQUIRY response needs faking */ \ | ||
82 | US_FLAG(FIX_CAPACITY, 0x00000010) \ | ||
83 | /* READ CAPACITY response too big */ \ | ||
84 | US_FLAG(IGNORE_RESIDUE, 0x00000020) \ | ||
85 | /* reported residue is wrong */ \ | ||
86 | US_FLAG(BULK32, 0x00000040) \ | ||
87 | /* Uses 32-byte CBW length */ \ | ||
88 | US_FLAG(NOT_LOCKABLE, 0x00000080) \ | ||
89 | /* PREVENT/ALLOW not supported */ \ | ||
90 | US_FLAG(GO_SLOW, 0x00000100) \ | ||
91 | /* Need delay after Command phase */ \ | ||
92 | US_FLAG(NO_WP_DETECT, 0x00000200) \ | ||
93 | /* Don't check for write-protect */ \ | ||
94 | |||
95 | #define US_FLAG(name, value) US_FL_##name = value , | ||
96 | enum { US_DO_ALL_FLAGS }; | ||
97 | #undef US_FLAG | ||
98 | 69 | ||
99 | /* Dynamic flag definitions: used in set_bit() etc. */ | 70 | /* Dynamic flag definitions: used in set_bit() etc. */ |
100 | #define US_FLIDX_URB_ACTIVE 18 /* 0x00040000 current_urb is in use */ | 71 | #define US_FLIDX_URB_ACTIVE 18 /* 0x00040000 current_urb is in use */ |
@@ -122,7 +93,11 @@ enum { US_DO_ALL_FLAGS }; | |||
122 | typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); | 93 | typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); |
123 | typedef int (*trans_reset)(struct us_data*); | 94 | typedef int (*trans_reset)(struct us_data*); |
124 | typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*); | 95 | typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*); |
125 | typedef void (*extra_data_destructor)(void *); /* extra data destructor */ | 96 | typedef void (*extra_data_destructor)(void *); /* extra data destructor */ |
97 | typedef void (*pm_hook)(struct us_data *, int); /* power management hook */ | ||
98 | |||
99 | #define US_SUSPEND 0 | ||
100 | #define US_RESUME 1 | ||
126 | 101 | ||
127 | /* we allocate one of these for every device that we remember */ | 102 | /* we allocate one of these for every device that we remember */ |
128 | struct us_data { | 103 | struct us_data { |
@@ -178,6 +153,9 @@ struct us_data { | |||
178 | /* subdriver information */ | 153 | /* subdriver information */ |
179 | void *extra; /* Any extra data */ | 154 | void *extra; /* Any extra data */ |
180 | extra_data_destructor extra_destructor;/* extra data destructor */ | 155 | extra_data_destructor extra_destructor;/* extra data destructor */ |
156 | #ifdef CONFIG_PM | ||
157 | pm_hook suspend_resume_hook; | ||
158 | #endif | ||
181 | }; | 159 | }; |
182 | 160 | ||
183 | /* Convert between us_data and the corresponding Scsi_Host */ | 161 | /* Convert between us_data and the corresponding Scsi_Host */ |
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 6c3a53f8f26c..5d02f16b7d0e 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c | |||
@@ -39,10 +39,15 @@ MODULE_DEVICE_TABLE (usb, skel_table); | |||
39 | /* Get a minor range for your devices from the usb maintainer */ | 39 | /* Get a minor range for your devices from the usb maintainer */ |
40 | #define USB_SKEL_MINOR_BASE 192 | 40 | #define USB_SKEL_MINOR_BASE 192 |
41 | 41 | ||
42 | /* our private defines. if this grows any larger, use your own .h file */ | ||
43 | #define MAX_TRANSFER ( PAGE_SIZE - 512 ) | ||
44 | #define WRITES_IN_FLIGHT 8 | ||
45 | |||
42 | /* Structure to hold all of our device specific stuff */ | 46 | /* Structure to hold all of our device specific stuff */ |
43 | struct usb_skel { | 47 | struct usb_skel { |
44 | struct usb_device * udev; /* the usb device for this device */ | 48 | struct usb_device * udev; /* the usb device for this device */ |
45 | struct usb_interface * interface; /* the interface for this device */ | 49 | struct usb_interface * interface; /* the interface for this device */ |
50 | struct semaphore limit_sem; /* limiting the number of writes in progress */ | ||
46 | unsigned char * bulk_in_buffer; /* the buffer to receive data */ | 51 | unsigned char * bulk_in_buffer; /* the buffer to receive data */ |
47 | size_t bulk_in_size; /* the size of the receive buffer */ | 52 | size_t bulk_in_size; /* the size of the receive buffer */ |
48 | __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ | 53 | __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ |
@@ -152,6 +157,7 @@ static void skel_write_bulk_callback(struct urb *urb, struct pt_regs *regs) | |||
152 | /* free up our allocated buffer */ | 157 | /* free up our allocated buffer */ |
153 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, | 158 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, |
154 | urb->transfer_buffer, urb->transfer_dma); | 159 | urb->transfer_buffer, urb->transfer_dma); |
160 | up(&dev->limit_sem); | ||
155 | } | 161 | } |
156 | 162 | ||
157 | static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) | 163 | static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos) |
@@ -160,6 +166,7 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou | |||
160 | int retval = 0; | 166 | int retval = 0; |
161 | struct urb *urb = NULL; | 167 | struct urb *urb = NULL; |
162 | char *buf = NULL; | 168 | char *buf = NULL; |
169 | size_t writesize = min(count, (size_t)MAX_TRANSFER); | ||
163 | 170 | ||
164 | dev = (struct usb_skel *)file->private_data; | 171 | dev = (struct usb_skel *)file->private_data; |
165 | 172 | ||
@@ -167,6 +174,12 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou | |||
167 | if (count == 0) | 174 | if (count == 0) |
168 | goto exit; | 175 | goto exit; |
169 | 176 | ||
177 | /* limit the number of URBs in flight to stop a user from using up all RAM */ | ||
178 | if (down_interruptible(&dev->limit_sem)) { | ||
179 | retval = -ERESTARTSYS; | ||
180 | goto exit; | ||
181 | } | ||
182 | |||
170 | /* create a urb, and a buffer for it, and copy the data to the urb */ | 183 | /* create a urb, and a buffer for it, and copy the data to the urb */ |
171 | urb = usb_alloc_urb(0, GFP_KERNEL); | 184 | urb = usb_alloc_urb(0, GFP_KERNEL); |
172 | if (!urb) { | 185 | if (!urb) { |
@@ -174,13 +187,13 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou | |||
174 | goto error; | 187 | goto error; |
175 | } | 188 | } |
176 | 189 | ||
177 | buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma); | 190 | buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma); |
178 | if (!buf) { | 191 | if (!buf) { |
179 | retval = -ENOMEM; | 192 | retval = -ENOMEM; |
180 | goto error; | 193 | goto error; |
181 | } | 194 | } |
182 | 195 | ||
183 | if (copy_from_user(buf, user_buffer, count)) { | 196 | if (copy_from_user(buf, user_buffer, writesize)) { |
184 | retval = -EFAULT; | 197 | retval = -EFAULT; |
185 | goto error; | 198 | goto error; |
186 | } | 199 | } |
@@ -188,7 +201,7 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou | |||
188 | /* initialize the urb properly */ | 201 | /* initialize the urb properly */ |
189 | usb_fill_bulk_urb(urb, dev->udev, | 202 | usb_fill_bulk_urb(urb, dev->udev, |
190 | usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), | 203 | usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), |
191 | buf, count, skel_write_bulk_callback, dev); | 204 | buf, writesize, skel_write_bulk_callback, dev); |
192 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 205 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
193 | 206 | ||
194 | /* send the data out the bulk port */ | 207 | /* send the data out the bulk port */ |
@@ -202,11 +215,12 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, size_t cou | |||
202 | usb_free_urb(urb); | 215 | usb_free_urb(urb); |
203 | 216 | ||
204 | exit: | 217 | exit: |
205 | return count; | 218 | return writesize; |
206 | 219 | ||
207 | error: | 220 | error: |
208 | usb_buffer_free(dev->udev, count, buf, urb->transfer_dma); | 221 | usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma); |
209 | usb_free_urb(urb); | 222 | usb_free_urb(urb); |
223 | up(&dev->limit_sem); | ||
210 | return retval; | 224 | return retval; |
211 | } | 225 | } |
212 | 226 | ||
@@ -238,13 +252,13 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i | |||
238 | int retval = -ENOMEM; | 252 | int retval = -ENOMEM; |
239 | 253 | ||
240 | /* allocate memory for our device state and initialize it */ | 254 | /* allocate memory for our device state and initialize it */ |
241 | dev = kmalloc(sizeof(*dev), GFP_KERNEL); | 255 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
242 | if (dev == NULL) { | 256 | if (dev == NULL) { |
243 | err("Out of memory"); | 257 | err("Out of memory"); |
244 | goto error; | 258 | goto error; |
245 | } | 259 | } |
246 | memset(dev, 0x00, sizeof(*dev)); | ||
247 | kref_init(&dev->kref); | 260 | kref_init(&dev->kref); |
261 | sema_init(&dev->limit_sem, WRITES_IN_FLIGHT); | ||
248 | 262 | ||
249 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); | 263 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); |
250 | dev->interface = interface; | 264 | dev->interface = interface; |
@@ -330,7 +344,6 @@ static void skel_disconnect(struct usb_interface *interface) | |||
330 | } | 344 | } |
331 | 345 | ||
332 | static struct usb_driver skel_driver = { | 346 | static struct usb_driver skel_driver = { |
333 | .owner = THIS_MODULE, | ||
334 | .name = "skeleton", | 347 | .name = "skeleton", |
335 | .probe = skel_probe, | 348 | .probe = skel_probe, |
336 | .disconnect = skel_disconnect, | 349 | .disconnect = skel_disconnect, |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 3e470c8b4193..cc8e3bf5001b 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -536,13 +536,13 @@ config FB_SUN3 | |||
536 | 536 | ||
537 | config FB_SBUS | 537 | config FB_SBUS |
538 | bool "SBUS and UPA framebuffers" | 538 | bool "SBUS and UPA framebuffers" |
539 | depends on (FB = y) && (SPARC32 || SPARC64) | 539 | depends on (FB = y) && SPARC |
540 | help | 540 | help |
541 | Say Y if you want support for SBUS or UPA based frame buffer device. | 541 | Say Y if you want support for SBUS or UPA based frame buffer device. |
542 | 542 | ||
543 | config FB_BW2 | 543 | config FB_BW2 |
544 | bool "BWtwo support" | 544 | bool "BWtwo support" |
545 | depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) | 545 | depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) |
546 | select FB_CFB_FILLRECT | 546 | select FB_CFB_FILLRECT |
547 | select FB_CFB_COPYAREA | 547 | select FB_CFB_COPYAREA |
548 | select FB_CFB_IMAGEBLIT | 548 | select FB_CFB_IMAGEBLIT |
@@ -551,7 +551,7 @@ config FB_BW2 | |||
551 | 551 | ||
552 | config FB_CG3 | 552 | config FB_CG3 |
553 | bool "CGthree support" | 553 | bool "CGthree support" |
554 | depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) | 554 | depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) |
555 | select FB_CFB_FILLRECT | 555 | select FB_CFB_FILLRECT |
556 | select FB_CFB_COPYAREA | 556 | select FB_CFB_COPYAREA |
557 | select FB_CFB_IMAGEBLIT | 557 | select FB_CFB_IMAGEBLIT |
@@ -560,7 +560,7 @@ config FB_CG3 | |||
560 | 560 | ||
561 | config FB_CG6 | 561 | config FB_CG6 |
562 | bool "CGsix (GX,TurboGX) support" | 562 | bool "CGsix (GX,TurboGX) support" |
563 | depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) | 563 | depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) |
564 | select FB_CFB_COPYAREA | 564 | select FB_CFB_COPYAREA |
565 | select FB_CFB_IMAGEBLIT | 565 | select FB_CFB_IMAGEBLIT |
566 | help | 566 | help |
@@ -1268,7 +1268,7 @@ config FB_LEO | |||
1268 | 1268 | ||
1269 | config FB_PCI | 1269 | config FB_PCI |
1270 | bool "PCI framebuffers" | 1270 | bool "PCI framebuffers" |
1271 | depends on (FB = y) && PCI && (SPARC64 || SPARC32) | 1271 | depends on (FB = y) && PCI && SPARC |
1272 | 1272 | ||
1273 | config FB_IGA | 1273 | config FB_IGA |
1274 | bool "IGA 168x display support" | 1274 | bool "IGA 168x display support" |
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 5f74df993406..a5d09e159cd1 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig | |||
@@ -6,7 +6,7 @@ menu "Console display driver support" | |||
6 | 6 | ||
7 | config VGA_CONSOLE | 7 | config VGA_CONSOLE |
8 | bool "VGA text console" if EMBEDDED || !X86 | 8 | bool "VGA text console" if EMBEDDED || !X86 |
9 | depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC32 && !SPARC64 && !M68K && !PARISC && !ARCH_VERSATILE | 9 | depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !ARCH_VERSATILE |
10 | default y | 10 | default y |
11 | help | 11 | help |
12 | Saying Y here will allow you to use Linux in text mode through a | 12 | Saying Y here will allow you to use Linux in text mode through a |
@@ -68,7 +68,7 @@ config SGI_NEWPORT_CONSOLE | |||
68 | 68 | ||
69 | config PROM_CONSOLE | 69 | config PROM_CONSOLE |
70 | bool "PROM console" | 70 | bool "PROM console" |
71 | depends on SPARC32 || SPARC64 | 71 | depends on SPARC |
72 | help | 72 | help |
73 | Say Y to build a console driver for Sun machines that uses the | 73 | Say Y to build a console driver for Sun machines that uses the |
74 | terminal emulation built into their console PROMS. | 74 | terminal emulation built into their console PROMS. |
@@ -136,7 +136,7 @@ config FONTS | |||
136 | config FONT_8x8 | 136 | config FONT_8x8 |
137 | bool "VGA 8x8 font" if FONTS | 137 | bool "VGA 8x8 font" if FONTS |
138 | depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE | 138 | depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE |
139 | default y if !SPARC32 && !SPARC64 && !FONTS | 139 | default y if !SPARC && !FONTS |
140 | help | 140 | help |
141 | This is the "high resolution" font for the VGA frame buffer (the one | 141 | This is the "high resolution" font for the VGA frame buffer (the one |
142 | provided by the text console 80x50 (and higher) modes). | 142 | provided by the text console 80x50 (and higher) modes). |
@@ -150,7 +150,7 @@ config FONT_8x8 | |||
150 | config FONT_8x16 | 150 | config FONT_8x16 |
151 | bool "VGA 8x16 font" if FONTS | 151 | bool "VGA 8x16 font" if FONTS |
152 | depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y || STI_CONSOLE || USB_SISUSBVGA_CON | 152 | depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y || STI_CONSOLE || USB_SISUSBVGA_CON |
153 | default y if !SPARC32 && !SPARC64 && !FONTS | 153 | default y if !SPARC && !FONTS |
154 | help | 154 | help |
155 | This is the "high resolution" font for the VGA frame buffer (the one | 155 | This is the "high resolution" font for the VGA frame buffer (the one |
156 | provided by the VGA text console 80x25 mode. | 156 | provided by the VGA text console 80x25 mode. |
@@ -160,7 +160,7 @@ config FONT_8x16 | |||
160 | config FONT_6x11 | 160 | config FONT_6x11 |
161 | bool "Mac console 6x11 font (not supported by all drivers)" if FONTS | 161 | bool "Mac console 6x11 font (not supported by all drivers)" if FONTS |
162 | depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE | 162 | depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE |
163 | default y if !SPARC32 && !SPARC64 && !FONTS && MAC | 163 | default y if !SPARC && !FONTS && MAC |
164 | help | 164 | help |
165 | Small console font with Macintosh-style high-half glyphs. Some Mac | 165 | Small console font with Macintosh-style high-half glyphs. Some Mac |
166 | framebuffer drivers don't support this one at all. | 166 | framebuffer drivers don't support this one at all. |
@@ -176,7 +176,7 @@ config FONT_7x14 | |||
176 | config FONT_PEARL_8x8 | 176 | config FONT_PEARL_8x8 |
177 | bool "Pearl (old m68k) console 8x8 font" if FONTS | 177 | bool "Pearl (old m68k) console 8x8 font" if FONTS |
178 | depends on FRAMEBUFFER_CONSOLE | 178 | depends on FRAMEBUFFER_CONSOLE |
179 | default y if !SPARC32 && !SPARC64 && !FONTS && AMIGA | 179 | default y if !SPARC && !FONTS && AMIGA |
180 | help | 180 | help |
181 | Small console font with PC-style control-character and high-half | 181 | Small console font with PC-style control-character and high-half |
182 | glyphs. | 182 | glyphs. |
@@ -184,24 +184,24 @@ config FONT_PEARL_8x8 | |||
184 | config FONT_ACORN_8x8 | 184 | config FONT_ACORN_8x8 |
185 | bool "Acorn console 8x8 font" if FONTS | 185 | bool "Acorn console 8x8 font" if FONTS |
186 | depends on FRAMEBUFFER_CONSOLE | 186 | depends on FRAMEBUFFER_CONSOLE |
187 | default y if !SPARC32 && !SPARC64 && !FONTS && ARM && ARCH_ACORN | 187 | default y if !SPARC && !FONTS && ARM && ARCH_ACORN |
188 | help | 188 | help |
189 | Small console font with PC-style control characters and high-half | 189 | Small console font with PC-style control characters and high-half |
190 | glyphs. | 190 | glyphs. |
191 | 191 | ||
192 | config FONT_MINI_4x6 | 192 | config FONT_MINI_4x6 |
193 | bool "Mini 4x6 font" | 193 | bool "Mini 4x6 font" |
194 | depends on !SPARC32 && !SPARC64 && FONTS | 194 | depends on !SPARC && FONTS |
195 | 195 | ||
196 | config FONT_SUN8x16 | 196 | config FONT_SUN8x16 |
197 | bool "Sparc console 8x16 font" | 197 | bool "Sparc console 8x16 font" |
198 | depends on FRAMEBUFFER_CONSOLE && (!SPARC32 && !SPARC64 && FONTS || SPARC32 || SPARC64) | 198 | depends on FRAMEBUFFER_CONSOLE && (!SPARC && FONTS || SPARC) |
199 | help | 199 | help |
200 | This is the high resolution console font for Sun machines. Say Y. | 200 | This is the high resolution console font for Sun machines. Say Y. |
201 | 201 | ||
202 | config FONT_SUN12x22 | 202 | config FONT_SUN12x22 |
203 | bool "Sparc console 12x22 font (not supported by all drivers)" | 203 | bool "Sparc console 12x22 font (not supported by all drivers)" |
204 | depends on FRAMEBUFFER_CONSOLE && (!SPARC32 && !SPARC64 && FONTS || SPARC32 || SPARC64) | 204 | depends on FRAMEBUFFER_CONSOLE && (!SPARC && FONTS || SPARC) |
205 | help | 205 | help |
206 | This is the high resolution console font for Sun machines with very | 206 | This is the high resolution console font for Sun machines with very |
207 | big letters (like the letters used in the SPARC PROM). If the | 207 | big letters (like the letters used in the SPARC PROM). If the |
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c index c4d7c89212b4..9dd059e8b645 100644 --- a/drivers/video/console/fbcon_ud.c +++ b/drivers/video/console/fbcon_ud.c | |||
@@ -420,13 +420,15 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, | |||
420 | int ud_update_start(struct fb_info *info) | 420 | int ud_update_start(struct fb_info *info) |
421 | { | 421 | { |
422 | struct fbcon_ops *ops = info->fbcon_par; | 422 | struct fbcon_ops *ops = info->fbcon_par; |
423 | u32 xoffset, yoffset; | 423 | int xoffset, yoffset; |
424 | u32 vyres = GETVYRES(ops->p->scrollmode, info); | 424 | u32 vyres = GETVYRES(ops->p->scrollmode, info); |
425 | u32 vxres = GETVXRES(ops->p->scrollmode, info); | 425 | u32 vxres = GETVXRES(ops->p->scrollmode, info); |
426 | int err; | 426 | int err; |
427 | 427 | ||
428 | xoffset = (vxres - info->var.xres) - ops->var.xoffset; | 428 | xoffset = vxres - info->var.xres - ops->var.xoffset; |
429 | yoffset = (vyres - info->var.yres) - ops->var.yoffset; | 429 | yoffset = vyres - info->var.yres - ops->var.yoffset; |
430 | if (yoffset < 0) | ||
431 | yoffset += vyres; | ||
430 | ops->var.xoffset = xoffset; | 432 | ops->var.xoffset = xoffset; |
431 | ops->var.yoffset = yoffset; | 433 | ops->var.yoffset = yoffset; |
432 | err = fb_pan_display(info, &ops->var); | 434 | err = fb_pan_display(info, &ops->var); |
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h index f077ca34faba..da29d007f215 100644 --- a/drivers/video/intelfb/intelfb.h +++ b/drivers/video/intelfb/intelfb.h | |||
@@ -41,6 +41,10 @@ | |||
41 | 41 | ||
42 | /*** hw-related values ***/ | 42 | /*** hw-related values ***/ |
43 | 43 | ||
44 | /* Resource Allocation */ | ||
45 | #define INTELFB_FB_ACQUIRED 1 | ||
46 | #define INTELFB_MMIO_ACQUIRED 2 | ||
47 | |||
44 | /* PCI ids for supported devices */ | 48 | /* PCI ids for supported devices */ |
45 | #define PCI_DEVICE_ID_INTEL_830M 0x3577 | 49 | #define PCI_DEVICE_ID_INTEL_830M 0x3577 |
46 | #define PCI_DEVICE_ID_INTEL_845G 0x2562 | 50 | #define PCI_DEVICE_ID_INTEL_845G 0x2562 |
@@ -257,6 +261,7 @@ struct intelfb_info { | |||
257 | int hwcursor; | 261 | int hwcursor; |
258 | int fixed_mode; | 262 | int fixed_mode; |
259 | int ring_active; | 263 | int ring_active; |
264 | int flag; | ||
260 | 265 | ||
261 | /* hw cursor */ | 266 | /* hw cursor */ |
262 | int cursor_on; | 267 | int cursor_on; |
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 427689e584da..0090544842f5 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c | |||
@@ -135,9 +135,6 @@ | |||
135 | static void __devinit get_initial_mode(struct intelfb_info *dinfo); | 135 | static void __devinit get_initial_mode(struct intelfb_info *dinfo); |
136 | static void update_dinfo(struct intelfb_info *dinfo, | 136 | static void update_dinfo(struct intelfb_info *dinfo, |
137 | struct fb_var_screeninfo *var); | 137 | struct fb_var_screeninfo *var); |
138 | static int intelfb_get_fix(struct fb_fix_screeninfo *fix, | ||
139 | struct fb_info *info); | ||
140 | |||
141 | static int intelfb_check_var(struct fb_var_screeninfo *var, | 138 | static int intelfb_check_var(struct fb_var_screeninfo *var, |
142 | struct fb_info *info); | 139 | struct fb_info *info); |
143 | static int intelfb_set_par(struct fb_info *info); | 140 | static int intelfb_set_par(struct fb_info *info); |
@@ -473,9 +470,9 @@ cleanup(struct intelfb_info *dinfo) | |||
473 | if (dinfo->aperture.virtual) | 470 | if (dinfo->aperture.virtual) |
474 | iounmap((void __iomem *)dinfo->aperture.virtual); | 471 | iounmap((void __iomem *)dinfo->aperture.virtual); |
475 | 472 | ||
476 | if (dinfo->mmio_base_phys) | 473 | if (dinfo->flag & INTELFB_MMIO_ACQUIRED) |
477 | release_mem_region(dinfo->mmio_base_phys, INTEL_REG_SIZE); | 474 | release_mem_region(dinfo->mmio_base_phys, INTEL_REG_SIZE); |
478 | if (dinfo->aperture.physical) | 475 | if (dinfo->flag & INTELFB_FB_ACQUIRED) |
479 | release_mem_region(dinfo->aperture.physical, | 476 | release_mem_region(dinfo->aperture.physical, |
480 | dinfo->aperture.size); | 477 | dinfo->aperture.size); |
481 | framebuffer_release(dinfo->info); | 478 | framebuffer_release(dinfo->info); |
@@ -572,6 +569,9 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
572 | cleanup(dinfo); | 569 | cleanup(dinfo); |
573 | return -ENODEV; | 570 | return -ENODEV; |
574 | } | 571 | } |
572 | |||
573 | dinfo->flag |= INTELFB_FB_ACQUIRED; | ||
574 | |||
575 | if (!request_mem_region(dinfo->mmio_base_phys, | 575 | if (!request_mem_region(dinfo->mmio_base_phys, |
576 | INTEL_REG_SIZE, | 576 | INTEL_REG_SIZE, |
577 | INTELFB_MODULE_NAME)) { | 577 | INTELFB_MODULE_NAME)) { |
@@ -580,6 +580,8 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
580 | return -ENODEV; | 580 | return -ENODEV; |
581 | } | 581 | } |
582 | 582 | ||
583 | dinfo->flag |= INTELFB_MMIO_ACQUIRED; | ||
584 | |||
583 | /* Get the chipset info. */ | 585 | /* Get the chipset info. */ |
584 | dinfo->pci_chipset = pdev->device; | 586 | dinfo->pci_chipset = pdev->device; |
585 | 587 | ||
@@ -1091,7 +1093,17 @@ intelfb_set_fbinfo(struct intelfb_info *dinfo) | |||
1091 | return 1; | 1093 | return 1; |
1092 | 1094 | ||
1093 | info->pixmap.scan_align = 1; | 1095 | info->pixmap.scan_align = 1; |
1094 | 1096 | strcpy(info->fix.id, dinfo->name); | |
1097 | info->fix.smem_start = dinfo->fb.physical; | ||
1098 | info->fix.smem_len = dinfo->fb.size; | ||
1099 | info->fix.type = FB_TYPE_PACKED_PIXELS; | ||
1100 | info->fix.type_aux = 0; | ||
1101 | info->fix.xpanstep = 8; | ||
1102 | info->fix.ypanstep = 1; | ||
1103 | info->fix.ywrapstep = 0; | ||
1104 | info->fix.mmio_start = dinfo->mmio_base_phys; | ||
1105 | info->fix.mmio_len = INTEL_REG_SIZE; | ||
1106 | info->fix.accel = FB_ACCEL_I830; | ||
1095 | update_dinfo(dinfo, &info->var); | 1107 | update_dinfo(dinfo, &info->var); |
1096 | 1108 | ||
1097 | return 0; | 1109 | return 0; |
@@ -1109,7 +1121,8 @@ update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var) | |||
1109 | dinfo->yres = var->xres; | 1121 | dinfo->yres = var->xres; |
1110 | dinfo->pixclock = var->pixclock; | 1122 | dinfo->pixclock = var->pixclock; |
1111 | 1123 | ||
1112 | intelfb_get_fix(&dinfo->info->fix, dinfo->info); | 1124 | dinfo->info->fix.visual = dinfo->visual; |
1125 | dinfo->info->fix.line_length = dinfo->pitch; | ||
1113 | 1126 | ||
1114 | switch (dinfo->bpp) { | 1127 | switch (dinfo->bpp) { |
1115 | case 8: | 1128 | case 8: |
@@ -1139,30 +1152,6 @@ update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var) | |||
1139 | 1152 | ||
1140 | /* fbops functions */ | 1153 | /* fbops functions */ |
1141 | 1154 | ||
1142 | static int | ||
1143 | intelfb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) | ||
1144 | { | ||
1145 | struct intelfb_info *dinfo = GET_DINFO(info); | ||
1146 | |||
1147 | DBG_MSG("intelfb_get_fix\n"); | ||
1148 | |||
1149 | memset(fix, 0, sizeof(*fix)); | ||
1150 | strcpy(fix->id, dinfo->name); | ||
1151 | fix->smem_start = dinfo->fb.physical; | ||
1152 | fix->smem_len = dinfo->fb.size; | ||
1153 | fix->type = FB_TYPE_PACKED_PIXELS; | ||
1154 | fix->type_aux = 0; | ||
1155 | fix->visual = dinfo->visual; | ||
1156 | fix->xpanstep = 8; | ||
1157 | fix->ypanstep = 1; | ||
1158 | fix->ywrapstep = 0; | ||
1159 | fix->line_length = dinfo->pitch; | ||
1160 | fix->mmio_start = dinfo->mmio_base_phys; | ||
1161 | fix->mmio_len = INTEL_REG_SIZE; | ||
1162 | fix->accel = FB_ACCEL_I830; | ||
1163 | return 0; | ||
1164 | } | ||
1165 | |||
1166 | /*************************************************************** | 1155 | /*************************************************************** |
1167 | * fbdev interface * | 1156 | * fbdev interface * |
1168 | ***************************************************************/ | 1157 | ***************************************************************/ |
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig index 8cb7fb4db441..f0e6512c87ff 100644 --- a/drivers/video/logo/Kconfig +++ b/drivers/video/logo/Kconfig | |||
@@ -47,7 +47,7 @@ config LOGO_SGI_CLUT224 | |||
47 | 47 | ||
48 | config LOGO_SUN_CLUT224 | 48 | config LOGO_SUN_CLUT224 |
49 | bool "224-color Sun Linux logo" | 49 | bool "224-color Sun Linux logo" |
50 | depends on LOGO && (SPARC32 || SPARC64) | 50 | depends on LOGO && SPARC |
51 | default y | 51 | default y |
52 | 52 | ||
53 | config LOGO_SUPERH_MONO | 53 | config LOGO_SUPERH_MONO |
diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c index 646c43f921c5..3a74a63dd4f2 100644 --- a/drivers/video/sbuslib.c +++ b/drivers/video/sbuslib.c | |||
@@ -46,6 +46,9 @@ int sbusfb_mmap_helper(struct sbus_mmap_map *map, | |||
46 | unsigned long off; | 46 | unsigned long off; |
47 | int i; | 47 | int i; |
48 | 48 | ||
49 | if (!(vma->vm_flags & (VM_SHARED | VM_MAYSHARE))) | ||
50 | return -EINVAL; | ||
51 | |||
49 | size = vma->vm_end - vma->vm_start; | 52 | size = vma->vm_end - vma->vm_start; |
50 | if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) | 53 | if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) |
51 | return -EINVAL; | 54 | return -EINVAL; |
diff --git a/drivers/w1/dscore.c b/drivers/w1/dscore.c index 15fb250451e5..b9146306df49 100644 --- a/drivers/w1/dscore.c +++ b/drivers/w1/dscore.c | |||
@@ -52,7 +52,6 @@ static int ds_send_control_cmd(struct ds_device *, u16, u16); | |||
52 | 52 | ||
53 | 53 | ||
54 | static struct usb_driver ds_driver = { | 54 | static struct usb_driver ds_driver = { |
55 | .owner = THIS_MODULE, | ||
56 | .name = "DS9490R", | 55 | .name = "DS9490R", |
57 | .probe = ds_probe, | 56 | .probe = ds_probe, |
58 | .disconnect = ds_disconnect, | 57 | .disconnect = ds_disconnect, |
diff --git a/fs/9p/trans_sock.c b/fs/9p/trans_sock.c index a93c2bf94c33..6a9a75d40f73 100644 --- a/fs/9p/trans_sock.c +++ b/fs/9p/trans_sock.c | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/config.h> | 28 | #include <linux/config.h> |
29 | #include <linux/in.h> | ||
29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
30 | #include <linux/net.h> | 31 | #include <linux/net.h> |
31 | #include <linux/ipv6.h> | 32 | #include <linux/ipv6.h> |
diff --git a/fs/compat.c b/fs/compat.c index 818634120b69..55ac0324aaf1 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -1170,7 +1170,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, | |||
1170 | } | 1170 | } |
1171 | 1171 | ||
1172 | ret = rw_verify_area(type, file, pos, tot_len); | 1172 | ret = rw_verify_area(type, file, pos, tot_len); |
1173 | if (ret) | 1173 | if (ret < 0) |
1174 | goto out; | 1174 | goto out; |
1175 | 1175 | ||
1176 | fnv = NULL; | 1176 | fnv = NULL; |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 4684eb7d48c6..b3ad0bd0312f 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -501,11 +501,16 @@ int hostfs_commit_write(struct file *file, struct page *page, unsigned from, | |||
501 | long long start; | 501 | long long start; |
502 | int err = 0; | 502 | int err = 0; |
503 | 503 | ||
504 | start = (long long) (page->index << PAGE_CACHE_SHIFT) + from; | 504 | start = (((long long) page->index) << PAGE_CACHE_SHIFT) + from; |
505 | buffer = kmap(page); | 505 | buffer = kmap(page); |
506 | err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from, | 506 | err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from, |
507 | to - from); | 507 | to - from); |
508 | if(err > 0) err = 0; | 508 | if(err > 0) err = 0; |
509 | |||
510 | /* Actually, if !err, write_file has added to-from to start, so, despite | ||
511 | * the appearance, we are comparing i_size against the _last_ written | ||
512 | * location, as we should. */ | ||
513 | |||
509 | if(!err && (start > inode->i_size)) | 514 | if(!err && (start > inode->i_size)) |
510 | inode->i_size = start; | 515 | inode->i_size = start; |
511 | 516 | ||
@@ -910,10 +915,8 @@ static struct inode_operations hostfs_dir_iops = { | |||
910 | int hostfs_link_readpage(struct file *file, struct page *page) | 915 | int hostfs_link_readpage(struct file *file, struct page *page) |
911 | { | 916 | { |
912 | char *buffer, *name; | 917 | char *buffer, *name; |
913 | long long start; | ||
914 | int err; | 918 | int err; |
915 | 919 | ||
916 | start = page->index << PAGE_CACHE_SHIFT; | ||
917 | buffer = kmap(page); | 920 | buffer = kmap(page); |
918 | name = inode_name(page->mapping->host, 0); | 921 | name = inode_name(page->mapping->host, 0); |
919 | if(name == NULL) return(-ENOMEM); | 922 | if(name == NULL) return(-ENOMEM); |
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 006bb9e14579..3eaf6e701087 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
@@ -157,6 +157,8 @@ void nlmclnt_mark_reclaim(struct nlm_host *host) | |||
157 | inode = fl->fl_file->f_dentry->d_inode; | 157 | inode = fl->fl_file->f_dentry->d_inode; |
158 | if (inode->i_sb->s_magic != NFS_SUPER_MAGIC) | 158 | if (inode->i_sb->s_magic != NFS_SUPER_MAGIC) |
159 | continue; | 159 | continue; |
160 | if (fl->fl_u.nfs_fl.owner == NULL) | ||
161 | continue; | ||
160 | if (fl->fl_u.nfs_fl.owner->host != host) | 162 | if (fl->fl_u.nfs_fl.owner->host != host) |
161 | continue; | 163 | continue; |
162 | if (!(fl->fl_u.nfs_fl.flags & NFS_LCK_GRANTED)) | 164 | if (!(fl->fl_u.nfs_fl.flags & NFS_LCK_GRANTED)) |
@@ -226,6 +228,8 @@ restart: | |||
226 | inode = fl->fl_file->f_dentry->d_inode; | 228 | inode = fl->fl_file->f_dentry->d_inode; |
227 | if (inode->i_sb->s_magic != NFS_SUPER_MAGIC) | 229 | if (inode->i_sb->s_magic != NFS_SUPER_MAGIC) |
228 | continue; | 230 | continue; |
231 | if (fl->fl_u.nfs_fl.owner == NULL) | ||
232 | continue; | ||
229 | if (fl->fl_u.nfs_fl.owner->host != host) | 233 | if (fl->fl_u.nfs_fl.owner->host != host) |
230 | continue; | 234 | continue; |
231 | if (!(fl->fl_u.nfs_fl.flags & NFS_LCK_RECLAIM)) | 235 | if (!(fl->fl_u.nfs_fl.flags & NFS_LCK_RECLAIM)) |
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index f2ca782aba33..30cae3602867 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -14,6 +14,9 @@ | |||
14 | #include <linux/sunrpc/svc.h> | 14 | #include <linux/sunrpc/svc.h> |
15 | #include <linux/sunrpc/svcsock.h> | 15 | #include <linux/sunrpc/svcsock.h> |
16 | #include <linux/nfs_fs.h> | 16 | #include <linux/nfs_fs.h> |
17 | |||
18 | #include <net/inet_sock.h> | ||
19 | |||
17 | #include "nfs4_fs.h" | 20 | #include "nfs4_fs.h" |
18 | #include "callback.h" | 21 | #include "callback.h" |
19 | 22 | ||
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index b497c71384e8..079228817603 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -678,15 +678,9 @@ nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t | |||
678 | if (!count) | 678 | if (!count) |
679 | goto out; | 679 | goto out; |
680 | 680 | ||
681 | if (mapping->nrpages) { | 681 | retval = nfs_sync_mapping(mapping); |
682 | retval = filemap_fdatawrite(mapping); | 682 | if (retval) |
683 | if (retval == 0) | 683 | goto out; |
684 | retval = nfs_wb_all(inode); | ||
685 | if (retval == 0) | ||
686 | retval = filemap_fdatawait(mapping); | ||
687 | if (retval) | ||
688 | goto out; | ||
689 | } | ||
690 | 684 | ||
691 | retval = nfs_direct_read(inode, ctx, &iov, pos, 1); | 685 | retval = nfs_direct_read(inode, ctx, &iov, pos, 1); |
692 | if (retval > 0) | 686 | if (retval > 0) |
@@ -764,15 +758,9 @@ nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count, | |||
764 | if (!count) | 758 | if (!count) |
765 | goto out; | 759 | goto out; |
766 | 760 | ||
767 | if (mapping->nrpages) { | 761 | retval = nfs_sync_mapping(mapping); |
768 | retval = filemap_fdatawrite(mapping); | 762 | if (retval) |
769 | if (retval == 0) | 763 | goto out; |
770 | retval = nfs_wb_all(inode); | ||
771 | if (retval == 0) | ||
772 | retval = filemap_fdatawait(mapping); | ||
773 | if (retval) | ||
774 | goto out; | ||
775 | } | ||
776 | 764 | ||
777 | retval = nfs_direct_write(inode, ctx, &iov, pos, 1); | 765 | retval = nfs_direct_write(inode, ctx, &iov, pos, 1); |
778 | if (mapping->nrpages) | 766 | if (mapping->nrpages) |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 57d3e77d97ee..7a79fbe9f539 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -433,11 +433,7 @@ static int do_unlk(struct file *filp, int cmd, struct file_lock *fl) | |||
433 | * Flush all pending writes before doing anything | 433 | * Flush all pending writes before doing anything |
434 | * with locks.. | 434 | * with locks.. |
435 | */ | 435 | */ |
436 | filemap_fdatawrite(filp->f_mapping); | 436 | nfs_sync_mapping(filp->f_mapping); |
437 | down(&inode->i_sem); | ||
438 | nfs_wb_all(inode); | ||
439 | up(&inode->i_sem); | ||
440 | filemap_fdatawait(filp->f_mapping); | ||
441 | 437 | ||
442 | /* NOTE: special case | 438 | /* NOTE: special case |
443 | * If we're signalled while cleaning up locks on process exit, we | 439 | * If we're signalled while cleaning up locks on process exit, we |
@@ -465,15 +461,8 @@ static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) | |||
465 | * Flush all pending writes before doing anything | 461 | * Flush all pending writes before doing anything |
466 | * with locks.. | 462 | * with locks.. |
467 | */ | 463 | */ |
468 | status = filemap_fdatawrite(filp->f_mapping); | 464 | status = nfs_sync_mapping(filp->f_mapping); |
469 | if (status == 0) { | 465 | if (status != 0) |
470 | down(&inode->i_sem); | ||
471 | status = nfs_wb_all(inode); | ||
472 | up(&inode->i_sem); | ||
473 | if (status == 0) | ||
474 | status = filemap_fdatawait(filp->f_mapping); | ||
475 | } | ||
476 | if (status < 0) | ||
477 | goto out; | 466 | goto out; |
478 | 467 | ||
479 | lock_kernel(); | 468 | lock_kernel(); |
@@ -497,11 +486,7 @@ static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) | |||
497 | * Make sure we clear the cache whenever we try to get the lock. | 486 | * Make sure we clear the cache whenever we try to get the lock. |
498 | * This makes locking act as a cache coherency point. | 487 | * This makes locking act as a cache coherency point. |
499 | */ | 488 | */ |
500 | filemap_fdatawrite(filp->f_mapping); | 489 | nfs_sync_mapping(filp->f_mapping); |
501 | down(&inode->i_sem); | ||
502 | nfs_wb_all(inode); /* we may have slept */ | ||
503 | up(&inode->i_sem); | ||
504 | filemap_fdatawait(filp->f_mapping); | ||
505 | nfs_zap_caches(inode); | 490 | nfs_zap_caches(inode); |
506 | out: | 491 | out: |
507 | rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset); | 492 | rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset); |
@@ -524,7 +509,8 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) | |||
524 | return -EINVAL; | 509 | return -EINVAL; |
525 | 510 | ||
526 | /* No mandatory locks over NFS */ | 511 | /* No mandatory locks over NFS */ |
527 | if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) | 512 | if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID && |
513 | fl->fl_type != F_UNLCK) | ||
528 | return -ENOLCK; | 514 | return -ENOLCK; |
529 | 515 | ||
530 | if (IS_GETLK(cmd)) | 516 | if (IS_GETLK(cmd)) |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index afd75d0463fd..432f41cd75e6 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -640,6 +640,27 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
640 | return 0; | 640 | return 0; |
641 | } | 641 | } |
642 | 642 | ||
643 | /** | ||
644 | * nfs_sync_mapping - helper to flush all mmapped dirty data to disk | ||
645 | */ | ||
646 | int nfs_sync_mapping(struct address_space *mapping) | ||
647 | { | ||
648 | int ret; | ||
649 | |||
650 | if (mapping->nrpages == 0) | ||
651 | return 0; | ||
652 | unmap_mapping_range(mapping, 0, 0, 0); | ||
653 | ret = filemap_fdatawrite(mapping); | ||
654 | if (ret != 0) | ||
655 | goto out; | ||
656 | ret = filemap_fdatawait(mapping); | ||
657 | if (ret != 0) | ||
658 | goto out; | ||
659 | ret = nfs_wb_all(mapping->host); | ||
660 | out: | ||
661 | return ret; | ||
662 | } | ||
663 | |||
643 | /* | 664 | /* |
644 | * Invalidate the local caches | 665 | * Invalidate the local caches |
645 | */ | 666 | */ |
@@ -1179,11 +1200,8 @@ void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) | |||
1179 | struct nfs_inode *nfsi = NFS_I(inode); | 1200 | struct nfs_inode *nfsi = NFS_I(inode); |
1180 | 1201 | ||
1181 | if (nfsi->cache_validity & NFS_INO_INVALID_DATA) { | 1202 | if (nfsi->cache_validity & NFS_INO_INVALID_DATA) { |
1182 | if (S_ISREG(inode->i_mode)) { | 1203 | if (S_ISREG(inode->i_mode)) |
1183 | if (filemap_fdatawrite(mapping) == 0) | 1204 | nfs_sync_mapping(mapping); |
1184 | filemap_fdatawait(mapping); | ||
1185 | nfs_wb_all(inode); | ||
1186 | } | ||
1187 | invalidate_inode_pages2(mapping); | 1205 | invalidate_inode_pages2(mapping); |
1188 | 1206 | ||
1189 | spin_lock(&inode->i_lock); | 1207 | spin_lock(&inode->i_lock); |
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c index 7cbf0682b2f0..fc95c4df6693 100644 --- a/fs/nfsd/nfs2acl.c +++ b/fs/nfsd/nfs2acl.c | |||
@@ -107,7 +107,7 @@ static int nfsacld_proc_setacl(struct svc_rqst * rqstp, | |||
107 | dprintk("nfsd: SETACL(2acl) %s\n", SVCFH_fmt(&argp->fh)); | 107 | dprintk("nfsd: SETACL(2acl) %s\n", SVCFH_fmt(&argp->fh)); |
108 | 108 | ||
109 | fh = fh_copy(&resp->fh, &argp->fh); | 109 | fh = fh_copy(&resp->fh, &argp->fh); |
110 | nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP); | 110 | nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_SATTR); |
111 | 111 | ||
112 | if (!nfserr) { | 112 | if (!nfserr) { |
113 | nfserr = nfserrno( nfsd_set_posix_acl( | 113 | nfserr = nfserrno( nfsd_set_posix_acl( |
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c index 64ba40572fea..16e10c170aed 100644 --- a/fs/nfsd/nfs3acl.c +++ b/fs/nfsd/nfs3acl.c | |||
@@ -101,7 +101,7 @@ static int nfsd3_proc_setacl(struct svc_rqst * rqstp, | |||
101 | int nfserr = 0; | 101 | int nfserr = 0; |
102 | 102 | ||
103 | fh = fh_copy(&resp->fh, &argp->fh); | 103 | fh = fh_copy(&resp->fh, &argp->fh); |
104 | nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP); | 104 | nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_SATTR); |
105 | 105 | ||
106 | if (!nfserr) { | 106 | if (!nfserr) { |
107 | nfserr = nfserrno( nfsd_set_posix_acl( | 107 | nfserr = nfserrno( nfsd_set_posix_acl( |
diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig index deb25b661f04..656bc43431b9 100644 --- a/fs/partitions/Kconfig +++ b/fs/partitions/Kconfig | |||
@@ -203,7 +203,7 @@ config ULTRIX_PARTITION | |||
203 | 203 | ||
204 | config SUN_PARTITION | 204 | config SUN_PARTITION |
205 | bool "Sun partition tables support" if PARTITION_ADVANCED | 205 | bool "Sun partition tables support" if PARTITION_ADVANCED |
206 | default y if (SPARC32 || SPARC64 || SUN3 || SUN3X) | 206 | default y if (SPARC || SUN3 || SUN3X) |
207 | ---help--- | 207 | ---help--- |
208 | Like most systems, SunOS uses its own hard disk partition table | 208 | Like most systems, SunOS uses its own hard disk partition table |
209 | format, incompatible with all others. Saying Y here allows you to | 209 | format, incompatible with all others. Saying Y here allows you to |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index b638fb500743..72b431d0a0a4 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -54,6 +54,18 @@ proc_file_read(struct file *file, char __user *buf, size_t nbytes, | |||
54 | ssize_t n, count; | 54 | ssize_t n, count; |
55 | char *start; | 55 | char *start; |
56 | struct proc_dir_entry * dp; | 56 | struct proc_dir_entry * dp; |
57 | unsigned long long pos; | ||
58 | |||
59 | /* | ||
60 | * Gaah, please just use "seq_file" instead. The legacy /proc | ||
61 | * interfaces cut loff_t down to off_t for reads, and ignore | ||
62 | * the offset entirely for writes.. | ||
63 | */ | ||
64 | pos = *ppos; | ||
65 | if (pos > MAX_NON_LFS) | ||
66 | return 0; | ||
67 | if (nbytes > MAX_NON_LFS - pos) | ||
68 | nbytes = MAX_NON_LFS - pos; | ||
57 | 69 | ||
58 | dp = PDE(inode); | 70 | dp = PDE(inode); |
59 | if (!(page = (char*) __get_free_page(GFP_KERNEL))) | 71 | if (!(page = (char*) __get_free_page(GFP_KERNEL))) |
@@ -202,30 +214,17 @@ proc_file_write(struct file *file, const char __user *buffer, | |||
202 | static loff_t | 214 | static loff_t |
203 | proc_file_lseek(struct file *file, loff_t offset, int orig) | 215 | proc_file_lseek(struct file *file, loff_t offset, int orig) |
204 | { | 216 | { |
205 | lock_kernel(); | 217 | loff_t retval = -EINVAL; |
206 | 218 | switch (orig) { | |
207 | switch (orig) { | 219 | case 1: |
208 | case 0: | 220 | offset += file->f_pos; |
209 | if (offset < 0) | 221 | /* fallthrough */ |
210 | goto out; | 222 | case 0: |
211 | file->f_pos = offset; | 223 | if (offset < 0 || offset > MAX_NON_LFS) |
212 | unlock_kernel(); | 224 | break; |
213 | return(file->f_pos); | 225 | file->f_pos = retval = offset; |
214 | case 1: | 226 | } |
215 | if (offset + file->f_pos < 0) | 227 | return retval; |
216 | goto out; | ||
217 | file->f_pos += offset; | ||
218 | unlock_kernel(); | ||
219 | return(file->f_pos); | ||
220 | case 2: | ||
221 | goto out; | ||
222 | default: | ||
223 | goto out; | ||
224 | } | ||
225 | |||
226 | out: | ||
227 | unlock_kernel(); | ||
228 | return -EINVAL; | ||
229 | } | 228 | } |
230 | 229 | ||
231 | static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) | 230 | static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) |
diff --git a/fs/read_write.c b/fs/read_write.c index a091ee4f430d..df3468a22fea 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/security.h> | 14 | #include <linux/security.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/syscalls.h> | 16 | #include <linux/syscalls.h> |
17 | #include <linux/pagemap.h> | ||
17 | 18 | ||
18 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
19 | #include <asm/unistd.h> | 20 | #include <asm/unistd.h> |
@@ -182,22 +183,33 @@ bad: | |||
182 | } | 183 | } |
183 | #endif | 184 | #endif |
184 | 185 | ||
186 | /* | ||
187 | * rw_verify_area doesn't like huge counts. We limit | ||
188 | * them to something that fits in "int" so that others | ||
189 | * won't have to do range checks all the time. | ||
190 | */ | ||
191 | #define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK) | ||
185 | 192 | ||
186 | int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count) | 193 | int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count) |
187 | { | 194 | { |
188 | struct inode *inode; | 195 | struct inode *inode; |
189 | loff_t pos; | 196 | loff_t pos; |
190 | 197 | ||
191 | if (unlikely(count > INT_MAX)) | 198 | if (unlikely((ssize_t) count < 0)) |
192 | goto Einval; | 199 | goto Einval; |
193 | pos = *ppos; | 200 | pos = *ppos; |
194 | if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) | 201 | if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) |
195 | goto Einval; | 202 | goto Einval; |
196 | 203 | ||
197 | inode = file->f_dentry->d_inode; | 204 | inode = file->f_dentry->d_inode; |
198 | if (inode->i_flock && MANDATORY_LOCK(inode)) | 205 | if (inode->i_flock && MANDATORY_LOCK(inode)) { |
199 | return locks_mandatory_area(read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, pos, count); | 206 | int retval = locks_mandatory_area( |
200 | return 0; | 207 | read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, |
208 | inode, file, pos, count); | ||
209 | if (retval < 0) | ||
210 | return retval; | ||
211 | } | ||
212 | return count > MAX_RW_COUNT ? MAX_RW_COUNT : count; | ||
201 | 213 | ||
202 | Einval: | 214 | Einval: |
203 | return -EINVAL; | 215 | return -EINVAL; |
@@ -244,7 +256,8 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) | |||
244 | return -EFAULT; | 256 | return -EFAULT; |
245 | 257 | ||
246 | ret = rw_verify_area(READ, file, pos, count); | 258 | ret = rw_verify_area(READ, file, pos, count); |
247 | if (!ret) { | 259 | if (ret >= 0) { |
260 | count = ret; | ||
248 | ret = security_file_permission (file, MAY_READ); | 261 | ret = security_file_permission (file, MAY_READ); |
249 | if (!ret) { | 262 | if (!ret) { |
250 | if (file->f_op->read) | 263 | if (file->f_op->read) |
@@ -295,7 +308,8 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ | |||
295 | return -EFAULT; | 308 | return -EFAULT; |
296 | 309 | ||
297 | ret = rw_verify_area(WRITE, file, pos, count); | 310 | ret = rw_verify_area(WRITE, file, pos, count); |
298 | if (!ret) { | 311 | if (ret >= 0) { |
312 | count = ret; | ||
299 | ret = security_file_permission (file, MAY_WRITE); | 313 | ret = security_file_permission (file, MAY_WRITE); |
300 | if (!ret) { | 314 | if (!ret) { |
301 | if (file->f_op->write) | 315 | if (file->f_op->write) |
@@ -497,7 +511,7 @@ static ssize_t do_readv_writev(int type, struct file *file, | |||
497 | } | 511 | } |
498 | 512 | ||
499 | ret = rw_verify_area(type, file, pos, tot_len); | 513 | ret = rw_verify_area(type, file, pos, tot_len); |
500 | if (ret) | 514 | if (ret < 0) |
501 | goto out; | 515 | goto out; |
502 | ret = security_file_permission(file, type == READ ? MAY_READ : MAY_WRITE); | 516 | ret = security_file_permission(file, type == READ ? MAY_READ : MAY_WRITE); |
503 | if (ret) | 517 | if (ret) |
@@ -653,8 +667,9 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
653 | if (!(in_file->f_mode & FMODE_PREAD)) | 667 | if (!(in_file->f_mode & FMODE_PREAD)) |
654 | goto fput_in; | 668 | goto fput_in; |
655 | retval = rw_verify_area(READ, in_file, ppos, count); | 669 | retval = rw_verify_area(READ, in_file, ppos, count); |
656 | if (retval) | 670 | if (retval < 0) |
657 | goto fput_in; | 671 | goto fput_in; |
672 | count = retval; | ||
658 | 673 | ||
659 | retval = security_file_permission (in_file, MAY_READ); | 674 | retval = security_file_permission (in_file, MAY_READ); |
660 | if (retval) | 675 | if (retval) |
@@ -674,8 +689,9 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
674 | goto fput_out; | 689 | goto fput_out; |
675 | out_inode = out_file->f_dentry->d_inode; | 690 | out_inode = out_file->f_dentry->d_inode; |
676 | retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); | 691 | retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); |
677 | if (retval) | 692 | if (retval < 0) |
678 | goto fput_out; | 693 | goto fput_out; |
694 | count = retval; | ||
679 | 695 | ||
680 | retval = security_file_permission (out_file, MAY_WRITE); | 696 | retval = security_file_permission (out_file, MAY_WRITE); |
681 | if (retval) | 697 | if (retval) |
diff --git a/fs/relayfs/relay.c b/fs/relayfs/relay.c index 16446a15c96d..2a6f7f12b7f9 100644 --- a/fs/relayfs/relay.c +++ b/fs/relayfs/relay.c | |||
@@ -333,8 +333,7 @@ size_t relay_switch_subbuf(struct rchan_buf *buf, size_t length) | |||
333 | return length; | 333 | return length; |
334 | 334 | ||
335 | toobig: | 335 | toobig: |
336 | printk(KERN_WARNING "relayfs: event too large (%Zd)\n", length); | 336 | buf->chan->last_toobig = length; |
337 | WARN_ON(1); | ||
338 | return 0; | 337 | return 0; |
339 | } | 338 | } |
340 | 339 | ||
@@ -399,6 +398,11 @@ void relay_close(struct rchan *chan) | |||
399 | relay_close_buf(chan->buf[i]); | 398 | relay_close_buf(chan->buf[i]); |
400 | } | 399 | } |
401 | 400 | ||
401 | if (chan->last_toobig) | ||
402 | printk(KERN_WARNING "relayfs: one or more items not logged " | ||
403 | "[item size (%Zd) > sub-buffer size (%Zd)]\n", | ||
404 | chan->last_toobig, chan->subbuf_size); | ||
405 | |||
402 | kref_put(&chan->kref, relay_destroy_channel); | 406 | kref_put(&chan->kref, relay_destroy_channel); |
403 | } | 407 | } |
404 | 408 | ||
diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h index e9c2790139ec..4ab2ca18b8df 100644 --- a/include/acpi/acglobal.h +++ b/include/acpi/acglobal.h | |||
@@ -211,7 +211,7 @@ ACPI_EXTERN u32 acpi_gbl_original_mode; | |||
211 | ACPI_EXTERN u32 acpi_gbl_rsdp_original_location; | 211 | ACPI_EXTERN u32 acpi_gbl_rsdp_original_location; |
212 | ACPI_EXTERN u32 acpi_gbl_ns_lookup_count; | 212 | ACPI_EXTERN u32 acpi_gbl_ns_lookup_count; |
213 | ACPI_EXTERN u32 acpi_gbl_ps_find_count; | 213 | ACPI_EXTERN u32 acpi_gbl_ps_find_count; |
214 | ACPI_EXTERN u32 acpi_gbl_owner_id_mask; | 214 | ACPI_EXTERN u64 acpi_gbl_owner_id_mask; |
215 | ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save; | 215 | ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save; |
216 | ACPI_EXTERN u16 acpi_gbl_global_lock_handle; | 216 | ACPI_EXTERN u16 acpi_gbl_global_lock_handle; |
217 | ACPI_EXTERN u8 acpi_gbl_debugger_configuration; | 217 | ACPI_EXTERN u8 acpi_gbl_debugger_configuration; |
diff --git a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h index 578ed3f1a607..302201f1a097 100644 --- a/include/asm-alpha/bitops.h +++ b/include/asm-alpha/bitops.h | |||
@@ -321,6 +321,7 @@ static inline int fls(int word) | |||
321 | #else | 321 | #else |
322 | #define fls generic_fls | 322 | #define fls generic_fls |
323 | #endif | 323 | #endif |
324 | #define fls64 generic_fls64 | ||
324 | 325 | ||
325 | /* Compute powers of two for the given integer. */ | 326 | /* Compute powers of two for the given integer. */ |
326 | static inline long floor_log2(unsigned long word) | 327 | static inline long floor_log2(unsigned long word) |
diff --git a/include/asm-arm/arch-pxa/ohci.h b/include/asm-arm/arch-pxa/ohci.h new file mode 100644 index 000000000000..7da89569061e --- /dev/null +++ b/include/asm-arm/arch-pxa/ohci.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #ifndef ASMARM_ARCH_OHCI_H | ||
2 | #define ASMARM_ARCH_OHCI_H | ||
3 | |||
4 | struct device; | ||
5 | |||
6 | struct pxaohci_platform_data { | ||
7 | int (*init)(struct device *); | ||
8 | void (*exit)(struct device *); | ||
9 | |||
10 | int port_mode; | ||
11 | #define PMM_NPS_MODE 1 | ||
12 | #define PMM_GLOBAL_MODE 2 | ||
13 | #define PMM_PERPORT_MODE 3 | ||
14 | }; | ||
15 | |||
16 | extern void pxa_set_ohci_info(struct pxaohci_platform_data *info); | ||
17 | |||
18 | #endif | ||
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h index 7399d431edfe..d02de721ecc1 100644 --- a/include/asm-arm/bitops.h +++ b/include/asm-arm/bitops.h | |||
@@ -332,6 +332,7 @@ static inline unsigned long __ffs(unsigned long word) | |||
332 | */ | 332 | */ |
333 | 333 | ||
334 | #define fls(x) generic_fls(x) | 334 | #define fls(x) generic_fls(x) |
335 | #define fls64(x) generic_fls64(x) | ||
335 | 336 | ||
336 | /* | 337 | /* |
337 | * ffs: find first bit set. This is defined the same way as | 338 | * ffs: find first bit set. This is defined the same way as |
@@ -351,6 +352,7 @@ static inline unsigned long __ffs(unsigned long word) | |||
351 | #define fls(x) \ | 352 | #define fls(x) \ |
352 | ( __builtin_constant_p(x) ? generic_fls(x) : \ | 353 | ( __builtin_constant_p(x) ? generic_fls(x) : \ |
353 | ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) ) | 354 | ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) ) |
355 | #define fls64(x) generic_fls64(x) | ||
354 | #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) | 356 | #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) |
355 | #define __ffs(x) (ffs(x) - 1) | 357 | #define __ffs(x) (ffs(x) - 1) |
356 | #define ffz(x) __ffs( ~(x) ) | 358 | #define ffz(x) __ffs( ~(x) ) |
diff --git a/include/asm-arm26/bitops.h b/include/asm-arm26/bitops.h index 7d062fb2e343..15cc6f2da792 100644 --- a/include/asm-arm26/bitops.h +++ b/include/asm-arm26/bitops.h | |||
@@ -259,6 +259,7 @@ static inline unsigned long __ffs(unsigned long word) | |||
259 | */ | 259 | */ |
260 | 260 | ||
261 | #define fls(x) generic_fls(x) | 261 | #define fls(x) generic_fls(x) |
262 | #define fls64(x) generic_fls64(x) | ||
262 | 263 | ||
263 | /* | 264 | /* |
264 | * ffs: find first bit set. This is defined the same way as | 265 | * ffs: find first bit set. This is defined the same way as |
diff --git a/include/asm-cris/bitops.h b/include/asm-cris/bitops.h index 1bddb3f3a289..d3eb0f1e4208 100644 --- a/include/asm-cris/bitops.h +++ b/include/asm-cris/bitops.h | |||
@@ -240,6 +240,7 @@ static inline int test_bit(int nr, const volatile unsigned long *addr) | |||
240 | */ | 240 | */ |
241 | 241 | ||
242 | #define fls(x) generic_fls(x) | 242 | #define fls(x) generic_fls(x) |
243 | #define fls64(x) generic_fls64(x) | ||
243 | 244 | ||
244 | /* | 245 | /* |
245 | * hweightN - returns the hamming weight of a N-bit word | 246 | * hweightN - returns the hamming weight of a N-bit word |
diff --git a/include/asm-frv/bitops.h b/include/asm-frv/bitops.h index b664bd5b6663..02be7b3a8a83 100644 --- a/include/asm-frv/bitops.h +++ b/include/asm-frv/bitops.h | |||
@@ -228,6 +228,7 @@ found_middle: | |||
228 | \ | 228 | \ |
229 | bit ? 33 - bit : bit; \ | 229 | bit ? 33 - bit : bit; \ |
230 | }) | 230 | }) |
231 | #define fls64(x) generic_fls64(x) | ||
231 | 232 | ||
232 | /* | 233 | /* |
233 | * Every architecture must define this function. It's the fastest | 234 | * Every architecture must define this function. It's the fastest |
diff --git a/include/asm-generic/bitops.h b/include/asm-generic/bitops.h index ce31b739fd80..0e6d9852008c 100644 --- a/include/asm-generic/bitops.h +++ b/include/asm-generic/bitops.h | |||
@@ -56,6 +56,7 @@ extern __inline__ int test_bit(int nr, const unsigned long * addr) | |||
56 | */ | 56 | */ |
57 | 57 | ||
58 | #define fls(x) generic_fls(x) | 58 | #define fls(x) generic_fls(x) |
59 | #define fls64(x) generic_fls64(x) | ||
59 | 60 | ||
60 | #ifdef __KERNEL__ | 61 | #ifdef __KERNEL__ |
61 | 62 | ||
diff --git a/include/asm-h8300/bitops.h b/include/asm-h8300/bitops.h index 5036f595f8c9..c0411ec9d651 100644 --- a/include/asm-h8300/bitops.h +++ b/include/asm-h8300/bitops.h | |||
@@ -406,5 +406,6 @@ found_middle: | |||
406 | #endif /* __KERNEL__ */ | 406 | #endif /* __KERNEL__ */ |
407 | 407 | ||
408 | #define fls(x) generic_fls(x) | 408 | #define fls(x) generic_fls(x) |
409 | #define fls64(x) generic_fls64(x) | ||
409 | 410 | ||
410 | #endif /* _H8300_BITOPS_H */ | 411 | #endif /* _H8300_BITOPS_H */ |
diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h index ddf1739dc7fd..4807aa1d2e3d 100644 --- a/include/asm-i386/bitops.h +++ b/include/asm-i386/bitops.h | |||
@@ -372,6 +372,7 @@ static inline unsigned long ffz(unsigned long word) | |||
372 | */ | 372 | */ |
373 | 373 | ||
374 | #define fls(x) generic_fls(x) | 374 | #define fls(x) generic_fls(x) |
375 | #define fls64(x) generic_fls64(x) | ||
375 | 376 | ||
376 | #ifdef __KERNEL__ | 377 | #ifdef __KERNEL__ |
377 | 378 | ||
diff --git a/include/asm-i386/param.h b/include/asm-i386/param.h index fa02e67ea86b..095580f3a45c 100644 --- a/include/asm-i386/param.h +++ b/include/asm-i386/param.h | |||
@@ -1,9 +1,8 @@ | |||
1 | #include <linux/config.h> | ||
2 | |||
3 | #ifndef _ASMi386_PARAM_H | 1 | #ifndef _ASMi386_PARAM_H |
4 | #define _ASMi386_PARAM_H | 2 | #define _ASMi386_PARAM_H |
5 | 3 | ||
6 | #ifdef __KERNEL__ | 4 | #ifdef __KERNEL__ |
5 | # include <linux/config.h> | ||
7 | # define HZ CONFIG_HZ /* Internal kernel timer frequency */ | 6 | # define HZ CONFIG_HZ /* Internal kernel timer frequency */ |
8 | # define USER_HZ 100 /* .. some user interfaces are in "ticks" */ | 7 | # define USER_HZ 100 /* .. some user interfaces are in "ticks" */ |
9 | # define CLOCKS_PER_SEC (USER_HZ) /* like times() */ | 8 | # define CLOCKS_PER_SEC (USER_HZ) /* like times() */ |
diff --git a/include/asm-ia64/bitops.h b/include/asm-ia64/bitops.h index 7232528e2d0c..36d0fb95ea89 100644 --- a/include/asm-ia64/bitops.h +++ b/include/asm-ia64/bitops.h | |||
@@ -345,6 +345,7 @@ fls (int t) | |||
345 | x |= x >> 16; | 345 | x |= x >> 16; |
346 | return ia64_popcnt(x); | 346 | return ia64_popcnt(x); |
347 | } | 347 | } |
348 | #define fls64(x) generic_fls64(x) | ||
348 | 349 | ||
349 | /* | 350 | /* |
350 | * ffs: find first bit set. This is defined the same way as the libc and compiler builtin | 351 | * ffs: find first bit set. This is defined the same way as the libc and compiler builtin |
diff --git a/include/asm-ia64/delay.h b/include/asm-ia64/delay.h index 57182d6f2b9a..bba702076391 100644 --- a/include/asm-ia64/delay.h +++ b/include/asm-ia64/delay.h | |||
@@ -84,14 +84,6 @@ __delay (unsigned long loops) | |||
84 | ia64_delay_loop (loops - 1); | 84 | ia64_delay_loop (loops - 1); |
85 | } | 85 | } |
86 | 86 | ||
87 | static __inline__ void | 87 | extern void udelay (unsigned long usecs); |
88 | udelay (unsigned long usecs) | ||
89 | { | ||
90 | unsigned long start = ia64_get_itc(); | ||
91 | unsigned long cycles = usecs*local_cpu_data->cyc_per_usec; | ||
92 | |||
93 | while (ia64_get_itc() - start < cycles) | ||
94 | cpu_relax(); | ||
95 | } | ||
96 | 88 | ||
97 | #endif /* _ASM_IA64_DELAY_H */ | 89 | #endif /* _ASM_IA64_DELAY_H */ |
diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h index a9f738bf18a7..f7c330467e7e 100644 --- a/include/asm-ia64/topology.h +++ b/include/asm-ia64/topology.h | |||
@@ -38,7 +38,7 @@ | |||
38 | /* | 38 | /* |
39 | * Returns the number of the first CPU on Node 'node'. | 39 | * Returns the number of the first CPU on Node 'node'. |
40 | */ | 40 | */ |
41 | #define node_to_first_cpu(node) (__ffs(node_to_cpumask(node))) | 41 | #define node_to_first_cpu(node) (first_cpu(node_to_cpumask(node))) |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * Determines the node for a given pci bus | 44 | * Determines the node for a given pci bus |
diff --git a/include/asm-m32r/bitops.h b/include/asm-m32r/bitops.h index e78443981349..abea2fdd8689 100644 --- a/include/asm-m32r/bitops.h +++ b/include/asm-m32r/bitops.h | |||
@@ -465,6 +465,7 @@ static __inline__ unsigned long __ffs(unsigned long word) | |||
465 | * fls: find last bit set. | 465 | * fls: find last bit set. |
466 | */ | 466 | */ |
467 | #define fls(x) generic_fls(x) | 467 | #define fls(x) generic_fls(x) |
468 | #define fls64(x) generic_fls64(x) | ||
468 | 469 | ||
469 | #ifdef __KERNEL__ | 470 | #ifdef __KERNEL__ |
470 | 471 | ||
diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h index b1bcf7c66516..13f4c0048463 100644 --- a/include/asm-m68k/bitops.h +++ b/include/asm-m68k/bitops.h | |||
@@ -310,6 +310,7 @@ static inline int fls(int x) | |||
310 | 310 | ||
311 | return 32 - cnt; | 311 | return 32 - cnt; |
312 | } | 312 | } |
313 | #define fls64(x) generic_fls64(x) | ||
313 | 314 | ||
314 | /* | 315 | /* |
315 | * Every architecture must define this function. It's the fastest | 316 | * Every architecture must define this function. It's the fastest |
diff --git a/include/asm-m68knommu/bitops.h b/include/asm-m68knommu/bitops.h index c42f88a9b9f9..4058dd086a02 100644 --- a/include/asm-m68knommu/bitops.h +++ b/include/asm-m68knommu/bitops.h | |||
@@ -499,5 +499,6 @@ found_middle: | |||
499 | * fls: find last bit set. | 499 | * fls: find last bit set. |
500 | */ | 500 | */ |
501 | #define fls(x) generic_fls(x) | 501 | #define fls(x) generic_fls(x) |
502 | #define fls64(x) generic_fls64(x) | ||
502 | 503 | ||
503 | #endif /* _M68KNOMMU_BITOPS_H */ | 504 | #endif /* _M68KNOMMU_BITOPS_H */ |
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index 5496f9064a6a..3b0c8aaf6e8b 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h | |||
@@ -695,7 +695,7 @@ static inline unsigned long fls(unsigned long word) | |||
695 | 695 | ||
696 | return flz(~word) + 1; | 696 | return flz(~word) + 1; |
697 | } | 697 | } |
698 | 698 | #define fls64(x) generic_fls64(x) | |
699 | 699 | ||
700 | /* | 700 | /* |
701 | * find_next_zero_bit - find the first zero bit in a memory region | 701 | * find_next_zero_bit - find the first zero bit in a memory region |
diff --git a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h index 55b98c67fd82..15d8c2b51584 100644 --- a/include/asm-parisc/bitops.h +++ b/include/asm-parisc/bitops.h | |||
@@ -263,6 +263,7 @@ static __inline__ int fls(int x) | |||
263 | 263 | ||
264 | return ret; | 264 | return ret; |
265 | } | 265 | } |
266 | #define fls64(x) generic_fls64(x) | ||
266 | 267 | ||
267 | /* | 268 | /* |
268 | * hweightN: returns the hamming weight (i.e. the number | 269 | * hweightN: returns the hamming weight (i.e. the number |
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h index 5727229b0444..1996eaa8aeae 100644 --- a/include/asm-powerpc/bitops.h +++ b/include/asm-powerpc/bitops.h | |||
@@ -310,6 +310,7 @@ static __inline__ int fls(unsigned int x) | |||
310 | asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x)); | 310 | asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x)); |
311 | return 32 - lz; | 311 | return 32 - lz; |
312 | } | 312 | } |
313 | #define fls64(x) generic_fls64(x) | ||
313 | 314 | ||
314 | /* | 315 | /* |
315 | * hweightN: returns the hamming weight (i.e. the number | 316 | * hweightN: returns the hamming weight (i.e. the number |
diff --git a/include/asm-ppc/ppc4xx_dma.h b/include/asm-ppc/ppc4xx_dma.h index a415001165fa..46a086fff816 100644 --- a/include/asm-ppc/ppc4xx_dma.h +++ b/include/asm-ppc/ppc4xx_dma.h | |||
@@ -33,9 +33,6 @@ | |||
33 | 33 | ||
34 | #define MAX_PPC4xx_DMA_CHANNELS 4 | 34 | #define MAX_PPC4xx_DMA_CHANNELS 4 |
35 | 35 | ||
36 | /* in arch/ppc/kernel/setup.c -- Cort */ | ||
37 | extern unsigned long DMA_MODE_WRITE, DMA_MODE_READ; | ||
38 | |||
39 | /* | 36 | /* |
40 | * Function return status codes | 37 | * Function return status codes |
41 | * These values are used to indicate whether or not the function | 38 | * These values are used to indicate whether or not the function |
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h index b07c578b22ea..61232760cc3b 100644 --- a/include/asm-s390/bitops.h +++ b/include/asm-s390/bitops.h | |||
@@ -839,6 +839,7 @@ static inline int sched_find_first_bit(unsigned long *b) | |||
839 | * fls: find last bit set. | 839 | * fls: find last bit set. |
840 | */ | 840 | */ |
841 | #define fls(x) generic_fls(x) | 841 | #define fls(x) generic_fls(x) |
842 | #define fls64(x) generic_fls64(x) | ||
842 | 843 | ||
843 | /* | 844 | /* |
844 | * hweightN: returns the hamming weight (i.e. the number | 845 | * hweightN: returns the hamming weight (i.e. the number |
diff --git a/include/asm-sh/bitops.h b/include/asm-sh/bitops.h index 5163d1ff2f1b..1c5260860045 100644 --- a/include/asm-sh/bitops.h +++ b/include/asm-sh/bitops.h | |||
@@ -470,6 +470,7 @@ found_middle: | |||
470 | */ | 470 | */ |
471 | 471 | ||
472 | #define fls(x) generic_fls(x) | 472 | #define fls(x) generic_fls(x) |
473 | #define fls64(x) generic_fls64(x) | ||
473 | 474 | ||
474 | #endif /* __KERNEL__ */ | 475 | #endif /* __KERNEL__ */ |
475 | 476 | ||
diff --git a/include/asm-sh64/bitops.h b/include/asm-sh64/bitops.h index e1ff63e09227..ce9c3ad45fe0 100644 --- a/include/asm-sh64/bitops.h +++ b/include/asm-sh64/bitops.h | |||
@@ -510,6 +510,7 @@ found_middle: | |||
510 | 510 | ||
511 | #define ffs(x) generic_ffs(x) | 511 | #define ffs(x) generic_ffs(x) |
512 | #define fls(x) generic_fls(x) | 512 | #define fls(x) generic_fls(x) |
513 | #define fls64(x) generic_fls64(x) | ||
513 | 514 | ||
514 | #endif /* __KERNEL__ */ | 515 | #endif /* __KERNEL__ */ |
515 | 516 | ||
diff --git a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h index bfbd795a0a80..41722b5e45ef 100644 --- a/include/asm-sparc/bitops.h +++ b/include/asm-sparc/bitops.h | |||
@@ -298,6 +298,7 @@ static inline int ffs(int x) | |||
298 | * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. | 298 | * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. |
299 | */ | 299 | */ |
300 | #define fls(x) generic_fls(x) | 300 | #define fls(x) generic_fls(x) |
301 | #define fls64(x) generic_fls64(x) | ||
301 | 302 | ||
302 | /* | 303 | /* |
303 | * hweightN: returns the hamming weight (i.e. the number | 304 | * hweightN: returns the hamming weight (i.e. the number |
diff --git a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h index 6388b8376c50..6efc0162fb09 100644 --- a/include/asm-sparc64/bitops.h +++ b/include/asm-sparc64/bitops.h | |||
@@ -119,6 +119,7 @@ static inline unsigned long __ffs(unsigned long word) | |||
119 | */ | 119 | */ |
120 | 120 | ||
121 | #define fls(x) generic_fls(x) | 121 | #define fls(x) generic_fls(x) |
122 | #define fls64(x) generic_fls64(x) | ||
122 | 123 | ||
123 | #ifdef __KERNEL__ | 124 | #ifdef __KERNEL__ |
124 | 125 | ||
diff --git a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h index b91e799763fd..8955d2376ac8 100644 --- a/include/asm-v850/bitops.h +++ b/include/asm-v850/bitops.h | |||
@@ -276,6 +276,7 @@ found_middle: | |||
276 | 276 | ||
277 | #define ffs(x) generic_ffs (x) | 277 | #define ffs(x) generic_ffs (x) |
278 | #define fls(x) generic_fls (x) | 278 | #define fls(x) generic_fls (x) |
279 | #define fls64(x) generic_fls64(x) | ||
279 | #define __ffs(x) ffs(x) | 280 | #define __ffs(x) ffs(x) |
280 | 281 | ||
281 | 282 | ||
diff --git a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h index 05a0d374404b..a4d5d0909453 100644 --- a/include/asm-x86_64/bitops.h +++ b/include/asm-x86_64/bitops.h | |||
@@ -340,6 +340,20 @@ static __inline__ unsigned long __ffs(unsigned long word) | |||
340 | return word; | 340 | return word; |
341 | } | 341 | } |
342 | 342 | ||
343 | /* | ||
344 | * __fls: find last bit set. | ||
345 | * @word: The word to search | ||
346 | * | ||
347 | * Undefined if no zero exists, so code should check against ~0UL first. | ||
348 | */ | ||
349 | static __inline__ unsigned long __fls(unsigned long word) | ||
350 | { | ||
351 | __asm__("bsrq %1,%0" | ||
352 | :"=r" (word) | ||
353 | :"rm" (word)); | ||
354 | return word; | ||
355 | } | ||
356 | |||
343 | #ifdef __KERNEL__ | 357 | #ifdef __KERNEL__ |
344 | 358 | ||
345 | static inline int sched_find_first_bit(const unsigned long *b) | 359 | static inline int sched_find_first_bit(const unsigned long *b) |
@@ -370,6 +384,19 @@ static __inline__ int ffs(int x) | |||
370 | } | 384 | } |
371 | 385 | ||
372 | /** | 386 | /** |
387 | * fls64 - find last bit set in 64 bit word | ||
388 | * @x: the word to search | ||
389 | * | ||
390 | * This is defined the same way as fls. | ||
391 | */ | ||
392 | static __inline__ int fls64(__u64 x) | ||
393 | { | ||
394 | if (x == 0) | ||
395 | return 0; | ||
396 | return __fls(x) + 1; | ||
397 | } | ||
398 | |||
399 | /** | ||
373 | * hweightN - returns the hamming weight of a N-bit word | 400 | * hweightN - returns the hamming weight of a N-bit word |
374 | * @x: the word to weigh | 401 | * @x: the word to weigh |
375 | * | 402 | * |
diff --git a/include/asm-x86_64/param.h b/include/asm-x86_64/param.h index 40b11937180d..5956b23b57c2 100644 --- a/include/asm-x86_64/param.h +++ b/include/asm-x86_64/param.h | |||
@@ -1,9 +1,8 @@ | |||
1 | #include <linux/config.h> | ||
2 | |||
3 | #ifndef _ASMx86_64_PARAM_H | 1 | #ifndef _ASMx86_64_PARAM_H |
4 | #define _ASMx86_64_PARAM_H | 2 | #define _ASMx86_64_PARAM_H |
5 | 3 | ||
6 | #ifdef __KERNEL__ | 4 | #ifdef __KERNEL__ |
5 | # include <linux/config.h> | ||
7 | # define HZ CONFIG_HZ /* Internal kernel timer frequency */ | 6 | # define HZ CONFIG_HZ /* Internal kernel timer frequency */ |
8 | # define USER_HZ 100 /* .. some user interfaces are in "ticks */ | 7 | # define USER_HZ 100 /* .. some user interfaces are in "ticks */ |
9 | #define CLOCKS_PER_SEC (USER_HZ) /* like times() */ | 8 | #define CLOCKS_PER_SEC (USER_HZ) /* like times() */ |
diff --git a/include/asm-x86_64/rwlock.h b/include/asm-x86_64/rwlock.h index 8a78a4ace53c..9942cc393064 100644 --- a/include/asm-x86_64/rwlock.h +++ b/include/asm-x86_64/rwlock.h | |||
@@ -64,7 +64,7 @@ | |||
64 | ::"a" (rw) : "memory") | 64 | ::"a" (rw) : "memory") |
65 | 65 | ||
66 | #define __build_write_lock_const(rw, helper) \ | 66 | #define __build_write_lock_const(rw, helper) \ |
67 | asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \ | 67 | asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \ |
68 | "jnz 2f\n" \ | 68 | "jnz 2f\n" \ |
69 | "1:\n" \ | 69 | "1:\n" \ |
70 | LOCK_SECTION_START("") \ | 70 | LOCK_SECTION_START("") \ |
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h index d39ebd5263ed..7d82bc56b9fa 100644 --- a/include/asm-x86_64/topology.h +++ b/include/asm-x86_64/topology.h | |||
@@ -23,7 +23,7 @@ extern int __node_distance(int, int); | |||
23 | 23 | ||
24 | #define cpu_to_node(cpu) (cpu_to_node[cpu]) | 24 | #define cpu_to_node(cpu) (cpu_to_node[cpu]) |
25 | #define parent_node(node) (node) | 25 | #define parent_node(node) (node) |
26 | #define node_to_first_cpu(node) (__ffs(node_to_cpumask[node])) | 26 | #define node_to_first_cpu(node) (first_cpu(node_to_cpumask[node])) |
27 | #define node_to_cpumask(node) (node_to_cpumask[node]) | 27 | #define node_to_cpumask(node) (node_to_cpumask[node]) |
28 | #define pcibus_to_node(bus) ((long)(bus->sysdata)) | 28 | #define pcibus_to_node(bus) ((long)(bus->sysdata)) |
29 | #define pcibus_to_cpumask(bus) node_to_cpumask(pcibus_to_node(bus)); | 29 | #define pcibus_to_cpumask(bus) node_to_cpumask(pcibus_to_node(bus)); |
diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h index e76ee889e21d..0a2065f1a372 100644 --- a/include/asm-xtensa/bitops.h +++ b/include/asm-xtensa/bitops.h | |||
@@ -245,6 +245,7 @@ static __inline__ int fls (unsigned int x) | |||
245 | { | 245 | { |
246 | return __cntlz(x); | 246 | return __cntlz(x); |
247 | } | 247 | } |
248 | #define fls64(x) generic_fls64(x) | ||
248 | 249 | ||
249 | static __inline__ int | 250 | static __inline__ int |
250 | find_next_bit(const unsigned long *addr, int size, int offset) | 251 | find_next_bit(const unsigned long *addr, int size, int offset) |
diff --git a/include/linux/bitops.h b/include/linux/bitops.h index 38c2fb7ebe09..6a2a19f14bb2 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h | |||
@@ -76,6 +76,15 @@ static __inline__ int generic_fls(int x) | |||
76 | */ | 76 | */ |
77 | #include <asm/bitops.h> | 77 | #include <asm/bitops.h> |
78 | 78 | ||
79 | |||
80 | static inline int generic_fls64(__u64 x) | ||
81 | { | ||
82 | __u32 h = x >> 32; | ||
83 | if (h) | ||
84 | return fls(x) + 32; | ||
85 | return fls(x); | ||
86 | } | ||
87 | |||
79 | static __inline__ int get_bitmask_order(unsigned int count) | 88 | static __inline__ int get_bitmask_order(unsigned int count) |
80 | { | 89 | { |
81 | int order; | 90 | int order; |
diff --git a/include/linux/cache.h b/include/linux/cache.h index f6b5a46c5f82..0b7ecf3af78a 100644 --- a/include/linux/cache.h +++ b/include/linux/cache.h | |||
@@ -13,7 +13,7 @@ | |||
13 | #define SMP_CACHE_BYTES L1_CACHE_BYTES | 13 | #define SMP_CACHE_BYTES L1_CACHE_BYTES |
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | #if defined(CONFIG_X86) || defined(CONFIG_SPARC64) | 16 | #if defined(CONFIG_X86) || defined(CONFIG_SPARC64) || defined(CONFIG_IA64) |
17 | #define __read_mostly __attribute__((__section__(".data.read_mostly"))) | 17 | #define __read_mostly __attribute__((__section__(".data.read_mostly"))) |
18 | #else | 18 | #else |
19 | #define __read_mostly | 19 | #define __read_mostly |
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index d068176b7ad7..c31650df9241 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
@@ -256,6 +256,16 @@ int cpufreq_update_policy(unsigned int cpu); | |||
256 | /* query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it */ | 256 | /* query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it */ |
257 | unsigned int cpufreq_get(unsigned int cpu); | 257 | unsigned int cpufreq_get(unsigned int cpu); |
258 | 258 | ||
259 | /* query the last known CPU freq (in kHz). If zero, cpufreq couldn't detect it */ | ||
260 | #ifdef CONFIG_CPU_FREQ | ||
261 | unsigned int cpufreq_quick_get(unsigned int cpu); | ||
262 | #else | ||
263 | static inline unsigned int cpufreq_quick_get(unsigned int cpu) | ||
264 | { | ||
265 | return 0; | ||
266 | } | ||
267 | #endif | ||
268 | |||
259 | 269 | ||
260 | /********************************************************************* | 270 | /********************************************************************* |
261 | * CPUFREQ DEFAULT GOVERNOR * | 271 | * CPUFREQ DEFAULT GOVERNOR * |
diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 71fab4311e92..088529f54965 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h | |||
@@ -192,10 +192,9 @@ enum { | |||
192 | #include <linux/workqueue.h> | 192 | #include <linux/workqueue.h> |
193 | 193 | ||
194 | #include <net/inet_connection_sock.h> | 194 | #include <net/inet_connection_sock.h> |
195 | #include <net/inet_sock.h> | ||
195 | #include <net/inet_timewait_sock.h> | 196 | #include <net/inet_timewait_sock.h> |
196 | #include <net/sock.h> | ||
197 | #include <net/tcp_states.h> | 197 | #include <net/tcp_states.h> |
198 | #include <net/tcp.h> | ||
199 | 198 | ||
200 | enum dccp_state { | 199 | enum dccp_state { |
201 | DCCP_OPEN = TCP_ESTABLISHED, | 200 | DCCP_OPEN = TCP_ESTABLISHED, |
@@ -408,8 +407,6 @@ struct dccp_ackvec; | |||
408 | * @dccps_gar - greatest valid ack number received on a non-Sync; initialized to %dccps_iss | 407 | * @dccps_gar - greatest valid ack number received on a non-Sync; initialized to %dccps_iss |
409 | * @dccps_timestamp_time - time of latest TIMESTAMP option | 408 | * @dccps_timestamp_time - time of latest TIMESTAMP option |
410 | * @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option | 409 | * @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option |
411 | * @dccps_ext_header_len - network protocol overhead (IP/IPv6 options) | ||
412 | * @dccps_pmtu_cookie - Last pmtu seen by socket | ||
413 | * @dccps_packet_size - Set thru setsockopt | 410 | * @dccps_packet_size - Set thru setsockopt |
414 | * @dccps_role - Role of this sock, one of %dccp_role | 411 | * @dccps_role - Role of this sock, one of %dccp_role |
415 | * @dccps_ndp_count - number of Non Data Packets since last data packet | 412 | * @dccps_ndp_count - number of Non Data Packets since last data packet |
@@ -434,8 +431,6 @@ struct dccp_sock { | |||
434 | __u32 dccps_timestamp_echo; | 431 | __u32 dccps_timestamp_echo; |
435 | __u32 dccps_packet_size; | 432 | __u32 dccps_packet_size; |
436 | unsigned long dccps_ndp_count; | 433 | unsigned long dccps_ndp_count; |
437 | __u16 dccps_ext_header_len; | ||
438 | __u32 dccps_pmtu_cookie; | ||
439 | __u32 dccps_mss_cache; | 434 | __u32 dccps_mss_cache; |
440 | struct dccp_options dccps_options; | 435 | struct dccp_options dccps_options; |
441 | struct dccp_ackvec *dccps_hc_rx_ackvec; | 436 | struct dccp_ackvec *dccps_hc_rx_ackvec; |
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 5f49a30eb6f2..745c988359c0 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h | |||
@@ -63,10 +63,11 @@ static inline int is_zero_ether_addr(const u8 *addr) | |||
63 | * @addr: Pointer to a six-byte array containing the Ethernet address | 63 | * @addr: Pointer to a six-byte array containing the Ethernet address |
64 | * | 64 | * |
65 | * Return true if the address is a multicast address. | 65 | * Return true if the address is a multicast address. |
66 | * By definition the broadcast address is also a multicast address. | ||
66 | */ | 67 | */ |
67 | static inline int is_multicast_ether_addr(const u8 *addr) | 68 | static inline int is_multicast_ether_addr(const u8 *addr) |
68 | { | 69 | { |
69 | return ((addr[0] != 0xff) && (0x01 & addr[0])); | 70 | return (0x01 & addr[0]); |
70 | } | 71 | } |
71 | 72 | ||
72 | /** | 73 | /** |
diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h index e677f73f13dd..4fab3d0a4bce 100644 --- a/include/linux/if_pppox.h +++ b/include/linux/if_pppox.h | |||
@@ -157,8 +157,7 @@ struct pppox_proto { | |||
157 | extern int register_pppox_proto(int proto_num, struct pppox_proto *pp); | 157 | extern int register_pppox_proto(int proto_num, struct pppox_proto *pp); |
158 | extern void unregister_pppox_proto(int proto_num); | 158 | extern void unregister_pppox_proto(int proto_num); |
159 | extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */ | 159 | extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */ |
160 | extern int pppox_channel_ioctl(struct ppp_channel *pc, unsigned int cmd, | 160 | extern int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); |
161 | unsigned long arg); | ||
162 | 161 | ||
163 | /* PPPoX socket states */ | 162 | /* PPPoX socket states */ |
164 | enum { | 163 | enum { |
diff --git a/include/linux/ip.h b/include/linux/ip.h index 33e8a19a1a0f..9e2eb9a602eb 100644 --- a/include/linux/ip.h +++ b/include/linux/ip.h | |||
@@ -16,6 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | #ifndef _LINUX_IP_H | 17 | #ifndef _LINUX_IP_H |
18 | #define _LINUX_IP_H | 18 | #define _LINUX_IP_H |
19 | #include <linux/types.h> | ||
19 | #include <asm/byteorder.h> | 20 | #include <asm/byteorder.h> |
20 | 21 | ||
21 | #define IPTOS_TOS_MASK 0x1E | 22 | #define IPTOS_TOS_MASK 0x1E |
@@ -78,126 +79,6 @@ | |||
78 | #define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ | 79 | #define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ |
79 | #define IPOPT_TS_PRESPEC 3 /* specified modules only */ | 80 | #define IPOPT_TS_PRESPEC 3 /* specified modules only */ |
80 | 81 | ||
81 | #ifdef __KERNEL__ | ||
82 | #include <linux/config.h> | ||
83 | #include <linux/types.h> | ||
84 | #include <net/request_sock.h> | ||
85 | #include <net/sock.h> | ||
86 | #include <linux/igmp.h> | ||
87 | #include <net/flow.h> | ||
88 | |||
89 | struct ip_options { | ||
90 | __u32 faddr; /* Saved first hop address */ | ||
91 | unsigned char optlen; | ||
92 | unsigned char srr; | ||
93 | unsigned char rr; | ||
94 | unsigned char ts; | ||
95 | unsigned char is_setbyuser:1, /* Set by setsockopt? */ | ||
96 | is_data:1, /* Options in __data, rather than skb */ | ||
97 | is_strictroute:1, /* Strict source route */ | ||
98 | srr_is_hit:1, /* Packet destination addr was our one */ | ||
99 | is_changed:1, /* IP checksum more not valid */ | ||
100 | rr_needaddr:1, /* Need to record addr of outgoing dev */ | ||
101 | ts_needtime:1, /* Need to record timestamp */ | ||
102 | ts_needaddr:1; /* Need to record addr of outgoing dev */ | ||
103 | unsigned char router_alert; | ||
104 | unsigned char __pad1; | ||
105 | unsigned char __pad2; | ||
106 | unsigned char __data[0]; | ||
107 | }; | ||
108 | |||
109 | #define optlength(opt) (sizeof(struct ip_options) + opt->optlen) | ||
110 | |||
111 | struct inet_request_sock { | ||
112 | struct request_sock req; | ||
113 | u32 loc_addr; | ||
114 | u32 rmt_addr; | ||
115 | u16 rmt_port; | ||
116 | u16 snd_wscale : 4, | ||
117 | rcv_wscale : 4, | ||
118 | tstamp_ok : 1, | ||
119 | sack_ok : 1, | ||
120 | wscale_ok : 1, | ||
121 | ecn_ok : 1, | ||
122 | acked : 1; | ||
123 | struct ip_options *opt; | ||
124 | }; | ||
125 | |||
126 | static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk) | ||
127 | { | ||
128 | return (struct inet_request_sock *)sk; | ||
129 | } | ||
130 | |||
131 | struct ipv6_pinfo; | ||
132 | |||
133 | struct inet_sock { | ||
134 | /* sk and pinet6 has to be the first two members of inet_sock */ | ||
135 | struct sock sk; | ||
136 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
137 | struct ipv6_pinfo *pinet6; | ||
138 | #endif | ||
139 | /* Socket demultiplex comparisons on incoming packets. */ | ||
140 | __u32 daddr; /* Foreign IPv4 addr */ | ||
141 | __u32 rcv_saddr; /* Bound local IPv4 addr */ | ||
142 | __u16 dport; /* Destination port */ | ||
143 | __u16 num; /* Local port */ | ||
144 | __u32 saddr; /* Sending source */ | ||
145 | __s16 uc_ttl; /* Unicast TTL */ | ||
146 | __u16 cmsg_flags; | ||
147 | struct ip_options *opt; | ||
148 | __u16 sport; /* Source port */ | ||
149 | __u16 id; /* ID counter for DF pkts */ | ||
150 | __u8 tos; /* TOS */ | ||
151 | __u8 mc_ttl; /* Multicasting TTL */ | ||
152 | __u8 pmtudisc; | ||
153 | unsigned recverr : 1, | ||
154 | freebind : 1, | ||
155 | hdrincl : 1, | ||
156 | mc_loop : 1; | ||
157 | int mc_index; /* Multicast device index */ | ||
158 | __u32 mc_addr; | ||
159 | struct ip_mc_socklist *mc_list; /* Group array */ | ||
160 | /* | ||
161 | * Following members are used to retain the infomation to build | ||
162 | * an ip header on each ip fragmentation while the socket is corked. | ||
163 | */ | ||
164 | struct { | ||
165 | unsigned int flags; | ||
166 | unsigned int fragsize; | ||
167 | struct ip_options *opt; | ||
168 | struct rtable *rt; | ||
169 | int length; /* Total length of all frames */ | ||
170 | u32 addr; | ||
171 | struct flowi fl; | ||
172 | } cork; | ||
173 | }; | ||
174 | |||
175 | #define IPCORK_OPT 1 /* ip-options has been held in ipcork.opt */ | ||
176 | #define IPCORK_ALLFRAG 2 /* always fragment (for ipv6 for now) */ | ||
177 | |||
178 | static inline struct inet_sock *inet_sk(const struct sock *sk) | ||
179 | { | ||
180 | return (struct inet_sock *)sk; | ||
181 | } | ||
182 | |||
183 | static inline void __inet_sk_copy_descendant(struct sock *sk_to, | ||
184 | const struct sock *sk_from, | ||
185 | const int ancestor_size) | ||
186 | { | ||
187 | memcpy(inet_sk(sk_to) + 1, inet_sk(sk_from) + 1, | ||
188 | sk_from->sk_prot->obj_size - ancestor_size); | ||
189 | } | ||
190 | #if !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)) | ||
191 | static inline void inet_sk_copy_descendant(struct sock *sk_to, | ||
192 | const struct sock *sk_from) | ||
193 | { | ||
194 | __inet_sk_copy_descendant(sk_to, sk_from, sizeof(struct inet_sock)); | ||
195 | } | ||
196 | #endif | ||
197 | #endif | ||
198 | |||
199 | extern int inet_sk_rebuild_header(struct sock *sk); | ||
200 | |||
201 | struct iphdr { | 82 | struct iphdr { |
202 | #if defined(__LITTLE_ENDIAN_BITFIELD) | 83 | #if defined(__LITTLE_ENDIAN_BITFIELD) |
203 | __u8 ihl:4, | 84 | __u8 ihl:4, |
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index e0b922785d98..93bbed5c6cf4 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h | |||
@@ -171,12 +171,13 @@ enum { | |||
171 | }; | 171 | }; |
172 | 172 | ||
173 | #ifdef __KERNEL__ | 173 | #ifdef __KERNEL__ |
174 | #include <linux/in6.h> /* struct sockaddr_in6 */ | ||
175 | #include <linux/icmpv6.h> | 174 | #include <linux/icmpv6.h> |
176 | #include <net/if_inet6.h> /* struct ipv6_mc_socklist */ | ||
177 | #include <linux/tcp.h> | 175 | #include <linux/tcp.h> |
178 | #include <linux/udp.h> | 176 | #include <linux/udp.h> |
179 | 177 | ||
178 | #include <net/if_inet6.h> /* struct ipv6_mc_socklist */ | ||
179 | #include <net/inet_sock.h> | ||
180 | |||
180 | /* | 181 | /* |
181 | This structure contains results of exthdrs parsing | 182 | This structure contains results of exthdrs parsing |
182 | as offsets from skb->nh. | 183 | as offsets from skb->nh. |
@@ -199,18 +200,17 @@ static inline int inet6_iif(const struct sk_buff *skb) | |||
199 | return IP6CB(skb)->iif; | 200 | return IP6CB(skb)->iif; |
200 | } | 201 | } |
201 | 202 | ||
202 | struct tcp6_request_sock { | 203 | struct inet6_request_sock { |
203 | struct tcp_request_sock req; | ||
204 | struct in6_addr loc_addr; | 204 | struct in6_addr loc_addr; |
205 | struct in6_addr rmt_addr; | 205 | struct in6_addr rmt_addr; |
206 | struct sk_buff *pktopts; | 206 | struct sk_buff *pktopts; |
207 | int iif; | 207 | int iif; |
208 | }; | 208 | }; |
209 | 209 | ||
210 | static inline struct tcp6_request_sock *tcp6_rsk(const struct request_sock *sk) | 210 | struct tcp6_request_sock { |
211 | { | 211 | struct tcp_request_sock tcp6rsk_tcp; |
212 | return (struct tcp6_request_sock *)sk; | 212 | struct inet6_request_sock tcp6rsk_inet6; |
213 | } | 213 | }; |
214 | 214 | ||
215 | /** | 215 | /** |
216 | * struct ipv6_pinfo - ipv6 private area | 216 | * struct ipv6_pinfo - ipv6 private area |
@@ -298,12 +298,36 @@ struct tcp6_sock { | |||
298 | struct ipv6_pinfo inet6; | 298 | struct ipv6_pinfo inet6; |
299 | }; | 299 | }; |
300 | 300 | ||
301 | extern int inet6_sk_rebuild_header(struct sock *sk); | ||
302 | |||
301 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 303 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
302 | static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk) | 304 | static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk) |
303 | { | 305 | { |
304 | return inet_sk(__sk)->pinet6; | 306 | return inet_sk(__sk)->pinet6; |
305 | } | 307 | } |
306 | 308 | ||
309 | static inline struct inet6_request_sock * | ||
310 | inet6_rsk(const struct request_sock *rsk) | ||
311 | { | ||
312 | return (struct inet6_request_sock *)(((u8 *)rsk) + | ||
313 | inet_rsk(rsk)->inet6_rsk_offset); | ||
314 | } | ||
315 | |||
316 | static inline u32 inet6_rsk_offset(struct request_sock *rsk) | ||
317 | { | ||
318 | return rsk->rsk_ops->obj_size - sizeof(struct inet6_request_sock); | ||
319 | } | ||
320 | |||
321 | static inline struct request_sock *inet6_reqsk_alloc(struct request_sock_ops *ops) | ||
322 | { | ||
323 | struct request_sock *req = reqsk_alloc(ops); | ||
324 | |||
325 | if (req != NULL) | ||
326 | inet_rsk(req)->inet6_rsk_offset = inet6_rsk_offset(req); | ||
327 | |||
328 | return req; | ||
329 | } | ||
330 | |||
307 | static inline struct raw6_sock *raw6_sk(const struct sock *sk) | 331 | static inline struct raw6_sock *raw6_sk(const struct sock *sk) |
308 | { | 332 | { |
309 | return (struct raw6_sock *)sk; | 333 | return (struct raw6_sock *)sk; |
@@ -323,28 +347,37 @@ static inline void inet_sk_copy_descendant(struct sock *sk_to, | |||
323 | #define __ipv6_only_sock(sk) (inet6_sk(sk)->ipv6only) | 347 | #define __ipv6_only_sock(sk) (inet6_sk(sk)->ipv6only) |
324 | #define ipv6_only_sock(sk) ((sk)->sk_family == PF_INET6 && __ipv6_only_sock(sk)) | 348 | #define ipv6_only_sock(sk) ((sk)->sk_family == PF_INET6 && __ipv6_only_sock(sk)) |
325 | 349 | ||
326 | #include <linux/tcp.h> | 350 | struct inet6_timewait_sock { |
351 | struct in6_addr tw_v6_daddr; | ||
352 | struct in6_addr tw_v6_rcv_saddr; | ||
353 | }; | ||
327 | 354 | ||
328 | struct tcp6_timewait_sock { | 355 | struct tcp6_timewait_sock { |
329 | struct tcp_timewait_sock tw_v6_sk; | 356 | struct tcp_timewait_sock tcp6tw_tcp; |
330 | struct in6_addr tw_v6_daddr; | 357 | struct inet6_timewait_sock tcp6tw_inet6; |
331 | struct in6_addr tw_v6_rcv_saddr; | ||
332 | }; | 358 | }; |
333 | 359 | ||
334 | static inline struct tcp6_timewait_sock *tcp6_twsk(const struct sock *sk) | 360 | static inline u16 inet6_tw_offset(const struct proto *prot) |
335 | { | 361 | { |
336 | return (struct tcp6_timewait_sock *)sk; | 362 | return prot->twsk_prot->twsk_obj_size - |
363 | sizeof(struct inet6_timewait_sock); | ||
337 | } | 364 | } |
338 | 365 | ||
339 | static inline struct in6_addr *__tcp_v6_rcv_saddr(const struct sock *sk) | 366 | static inline struct inet6_timewait_sock *inet6_twsk(const struct sock *sk) |
367 | { | ||
368 | return (struct inet6_timewait_sock *)(((u8 *)sk) + | ||
369 | inet_twsk(sk)->tw_ipv6_offset); | ||
370 | } | ||
371 | |||
372 | static inline struct in6_addr *__inet6_rcv_saddr(const struct sock *sk) | ||
340 | { | 373 | { |
341 | return likely(sk->sk_state != TCP_TIME_WAIT) ? | 374 | return likely(sk->sk_state != TCP_TIME_WAIT) ? |
342 | &inet6_sk(sk)->rcv_saddr : &tcp6_twsk(sk)->tw_v6_rcv_saddr; | 375 | &inet6_sk(sk)->rcv_saddr : &inet6_twsk(sk)->tw_v6_rcv_saddr; |
343 | } | 376 | } |
344 | 377 | ||
345 | static inline struct in6_addr *tcp_v6_rcv_saddr(const struct sock *sk) | 378 | static inline struct in6_addr *inet6_rcv_saddr(const struct sock *sk) |
346 | { | 379 | { |
347 | return sk->sk_family == AF_INET6 ? __tcp_v6_rcv_saddr(sk) : NULL; | 380 | return sk->sk_family == AF_INET6 ? __inet6_rcv_saddr(sk) : NULL; |
348 | } | 381 | } |
349 | 382 | ||
350 | static inline int inet_v6_ipv6only(const struct sock *sk) | 383 | static inline int inet_v6_ipv6only(const struct sock *sk) |
@@ -361,13 +394,19 @@ static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk) | |||
361 | return NULL; | 394 | return NULL; |
362 | } | 395 | } |
363 | 396 | ||
397 | static inline struct inet6_request_sock * | ||
398 | inet6_rsk(const struct request_sock *rsk) | ||
399 | { | ||
400 | return NULL; | ||
401 | } | ||
402 | |||
364 | static inline struct raw6_sock *raw6_sk(const struct sock *sk) | 403 | static inline struct raw6_sock *raw6_sk(const struct sock *sk) |
365 | { | 404 | { |
366 | return NULL; | 405 | return NULL; |
367 | } | 406 | } |
368 | 407 | ||
369 | #define __tcp_v6_rcv_saddr(__sk) NULL | 408 | #define __inet6_rcv_saddr(__sk) NULL |
370 | #define tcp_v6_rcv_saddr(__sk) NULL | 409 | #define inet6_rcv_saddr(__sk) NULL |
371 | #define tcp_twsk_ipv6only(__sk) 0 | 410 | #define tcp_twsk_ipv6only(__sk) 0 |
372 | #define inet_v6_ipv6only(__sk) 0 | 411 | #define inet_v6_ipv6only(__sk) 0 |
373 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ | 412 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ |
diff --git a/include/linux/ipv6_route.h b/include/linux/ipv6_route.h index e2f935038013..d7c41d1d706a 100644 --- a/include/linux/ipv6_route.h +++ b/include/linux/ipv6_route.h | |||
@@ -18,6 +18,7 @@ | |||
18 | fallback, no routers on link */ | 18 | fallback, no routers on link */ |
19 | #define RTF_ADDRCONF 0x00040000 /* addrconf route - RA */ | 19 | #define RTF_ADDRCONF 0x00040000 /* addrconf route - RA */ |
20 | #define RTF_PREFIX_RT 0x00080000 /* A prefix only route - RA */ | 20 | #define RTF_PREFIX_RT 0x00080000 /* A prefix only route - RA */ |
21 | #define RTF_ANYCAST 0x00100000 /* Anycast */ | ||
21 | 22 | ||
22 | #define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */ | 23 | #define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */ |
23 | #define RTF_EXPIRES 0x00400000 | 24 | #define RTF_EXPIRES 0x00400000 |
diff --git a/include/linux/irq.h b/include/linux/irq.h index c516382fbec2..f04ba20712a2 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -10,7 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
13 | #include <asm/smp.h> /* cpu_online_map */ | 13 | #include <linux/smp.h> |
14 | 14 | ||
15 | #if !defined(CONFIG_ARCH_S390) | 15 | #if !defined(CONFIG_ARCH_S390) |
16 | 16 | ||
diff --git a/include/linux/mm.h b/include/linux/mm.h index e5677f456742..a06a84d347fb 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -163,6 +163,7 @@ extern unsigned int kobjsize(const void *objp); | |||
163 | #define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */ | 163 | #define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */ |
164 | #define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */ | 164 | #define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */ |
165 | #define VM_MAPPED_COPY 0x01000000 /* T if mapped copy of data (nommu mmap) */ | 165 | #define VM_MAPPED_COPY 0x01000000 /* T if mapped copy of data (nommu mmap) */ |
166 | #define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */ | ||
166 | 167 | ||
167 | #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ | 168 | #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ |
168 | #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS | 169 | #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS |
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index f1fd4215686a..7419b5fab133 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/mtd/bbm.h> | 17 | #include <linux/mtd/bbm.h> |
18 | 18 | ||
19 | #define MAX_BUFFERRAM 2 | 19 | #define MAX_BUFFERRAM 2 |
20 | #define MAX_ONENAND_PAGESIZE (2048 + 64) | ||
21 | 20 | ||
22 | /* Scan and identify a OneNAND device */ | 21 | /* Scan and identify a OneNAND device */ |
23 | extern int onenand_scan(struct mtd_info *mtd, int max_chips); | 22 | extern int onenand_scan(struct mtd_info *mtd, int max_chips); |
@@ -110,6 +109,7 @@ struct onenand_chip { | |||
110 | spinlock_t chip_lock; | 109 | spinlock_t chip_lock; |
111 | wait_queue_head_t wq; | 110 | wait_queue_head_t wq; |
112 | onenand_state_t state; | 111 | onenand_state_t state; |
112 | unsigned char *page_buf; | ||
113 | 113 | ||
114 | struct nand_oobinfo *autooob; | 114 | struct nand_oobinfo *autooob; |
115 | 115 | ||
@@ -134,13 +134,12 @@ struct onenand_chip { | |||
134 | * Options bits | 134 | * Options bits |
135 | */ | 135 | */ |
136 | #define ONENAND_CONT_LOCK (0x0001) | 136 | #define ONENAND_CONT_LOCK (0x0001) |
137 | 137 | #define ONENAND_PAGEBUF_ALLOC (0x1000) | |
138 | 138 | ||
139 | /* | 139 | /* |
140 | * OneNAND Flash Manufacturer ID Codes | 140 | * OneNAND Flash Manufacturer ID Codes |
141 | */ | 141 | */ |
142 | #define ONENAND_MFR_SAMSUNG 0xec | 142 | #define ONENAND_MFR_SAMSUNG 0xec |
143 | #define ONENAND_MFR_UNKNOWN 0x00 | ||
144 | 143 | ||
145 | /** | 144 | /** |
146 | * struct nand_manufacturers - NAND Flash Manufacturer ID Structure | 145 | * struct nand_manufacturers - NAND Flash Manufacturer ID Structure |
diff --git a/include/linux/n_r3964.h b/include/linux/n_r3964.h index 2352bcd31a06..db4f3776978a 100644 --- a/include/linux/n_r3964.h +++ b/include/linux/n_r3964.h | |||
@@ -13,6 +13,10 @@ | |||
13 | * L. Haag | 13 | * L. Haag |
14 | * | 14 | * |
15 | * $Log: r3964.h,v $ | 15 | * $Log: r3964.h,v $ |
16 | * Revision 1.4 2005/12/21 19:54:24 Kurt Huwig <kurt huwig de> | ||
17 | * Fixed HZ usage on 2.6 kernels | ||
18 | * Removed unnecessary include | ||
19 | * | ||
16 | * Revision 1.3 2001/03/18 13:02:24 dwmw2 | 20 | * Revision 1.3 2001/03/18 13:02:24 dwmw2 |
17 | * Fix timer usage, use spinlocks properly. | 21 | * Fix timer usage, use spinlocks properly. |
18 | * | 22 | * |
@@ -45,9 +49,11 @@ | |||
45 | #define __LINUX_N_R3964_H__ | 49 | #define __LINUX_N_R3964_H__ |
46 | 50 | ||
47 | /* line disciplines for r3964 protocol */ | 51 | /* line disciplines for r3964 protocol */ |
48 | #include <asm/termios.h> | ||
49 | 52 | ||
50 | #ifdef __KERNEL__ | 53 | #ifdef __KERNEL__ |
54 | |||
55 | #include <linux/param.h> | ||
56 | |||
51 | /* | 57 | /* |
52 | * Common ascii handshake characters: | 58 | * Common ascii handshake characters: |
53 | */ | 59 | */ |
@@ -58,14 +64,14 @@ | |||
58 | #define NAK 0x15 | 64 | #define NAK 0x15 |
59 | 65 | ||
60 | /* | 66 | /* |
61 | * Timeouts (msecs/10 msecs per timer interrupt): | 67 | * Timeouts (from milliseconds to jiffies) |
62 | */ | 68 | */ |
63 | 69 | ||
64 | #define R3964_TO_QVZ 550/10 | 70 | #define R3964_TO_QVZ ((550)*HZ/1000) |
65 | #define R3964_TO_ZVZ 220/10 | 71 | #define R3964_TO_ZVZ ((220)*HZ/1000) |
66 | #define R3964_TO_NO_BUF 400/10 | 72 | #define R3964_TO_NO_BUF ((400)*HZ/1000) |
67 | #define R3964_NO_TX_ROOM 100/10 | 73 | #define R3964_NO_TX_ROOM ((100)*HZ/1000) |
68 | #define R3964_TO_RX_PANIC 4000/10 | 74 | #define R3964_TO_RX_PANIC ((4000)*HZ/1000) |
69 | #define R3964_MAX_RETRIES 5 | 75 | #define R3964_MAX_RETRIES 5 |
70 | 76 | ||
71 | #endif | 77 | #endif |
diff --git a/include/linux/net.h b/include/linux/net.h index d6a41e6577f6..28195a2d8ff0 100644 --- a/include/linux/net.h +++ b/include/linux/net.h | |||
@@ -107,7 +107,7 @@ enum sock_type { | |||
107 | struct socket { | 107 | struct socket { |
108 | socket_state state; | 108 | socket_state state; |
109 | unsigned long flags; | 109 | unsigned long flags; |
110 | struct proto_ops *ops; | 110 | const struct proto_ops *ops; |
111 | struct fasync_struct *fasync_list; | 111 | struct fasync_struct *fasync_list; |
112 | struct file *file; | 112 | struct file *file; |
113 | struct sock *sk; | 113 | struct sock *sk; |
@@ -260,7 +260,7 @@ SOCKCALL_WRAP(name, recvmsg, (struct kiocb *iocb, struct socket *sock, struct ms | |||
260 | SOCKCALL_WRAP(name, mmap, (struct file *file, struct socket *sock, struct vm_area_struct *vma), \ | 260 | SOCKCALL_WRAP(name, mmap, (struct file *file, struct socket *sock, struct vm_area_struct *vma), \ |
261 | (file, sock, vma)) \ | 261 | (file, sock, vma)) \ |
262 | \ | 262 | \ |
263 | static struct proto_ops name##_ops = { \ | 263 | static const struct proto_ops name##_ops = { \ |
264 | .family = fam, \ | 264 | .family = fam, \ |
265 | .owner = THIS_MODULE, \ | 265 | .owner = THIS_MODULE, \ |
266 | .release = __lock_##name##_release, \ | 266 | .release = __lock_##name##_release, \ |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 12787a9b0259..2516adeccecf 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
@@ -291,6 +291,7 @@ static inline int nfs_verify_change_attribute(struct inode *inode, unsigned long | |||
291 | /* | 291 | /* |
292 | * linux/fs/nfs/inode.c | 292 | * linux/fs/nfs/inode.c |
293 | */ | 293 | */ |
294 | extern int nfs_sync_mapping(struct address_space *mapping); | ||
294 | extern void nfs_zap_caches(struct inode *); | 295 | extern void nfs_zap_caches(struct inode *); |
295 | extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *, | 296 | extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *, |
296 | struct nfs_fattr *); | 297 | struct nfs_fattr *); |
diff --git a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h index 724066778aff..6351c4055ace 100644 --- a/include/linux/pfkeyv2.h +++ b/include/linux/pfkeyv2.h | |||
@@ -216,6 +216,16 @@ struct sadb_x_nat_t_port { | |||
216 | } __attribute__((packed)); | 216 | } __attribute__((packed)); |
217 | /* sizeof(struct sadb_x_nat_t_port) == 8 */ | 217 | /* sizeof(struct sadb_x_nat_t_port) == 8 */ |
218 | 218 | ||
219 | /* Generic LSM security context */ | ||
220 | struct sadb_x_sec_ctx { | ||
221 | uint16_t sadb_x_sec_len; | ||
222 | uint16_t sadb_x_sec_exttype; | ||
223 | uint8_t sadb_x_ctx_alg; /* LSMs: e.g., selinux == 1 */ | ||
224 | uint8_t sadb_x_ctx_doi; | ||
225 | uint16_t sadb_x_ctx_len; | ||
226 | } __attribute__((packed)); | ||
227 | /* sizeof(struct sadb_sec_ctx) = 8 */ | ||
228 | |||
219 | /* Message types */ | 229 | /* Message types */ |
220 | #define SADB_RESERVED 0 | 230 | #define SADB_RESERVED 0 |
221 | #define SADB_GETSPI 1 | 231 | #define SADB_GETSPI 1 |
@@ -325,7 +335,8 @@ struct sadb_x_nat_t_port { | |||
325 | #define SADB_X_EXT_NAT_T_SPORT 21 | 335 | #define SADB_X_EXT_NAT_T_SPORT 21 |
326 | #define SADB_X_EXT_NAT_T_DPORT 22 | 336 | #define SADB_X_EXT_NAT_T_DPORT 22 |
327 | #define SADB_X_EXT_NAT_T_OA 23 | 337 | #define SADB_X_EXT_NAT_T_OA 23 |
328 | #define SADB_EXT_MAX 23 | 338 | #define SADB_X_EXT_SEC_CTX 24 |
339 | #define SADB_EXT_MAX 24 | ||
329 | 340 | ||
330 | /* Identity Extension values */ | 341 | /* Identity Extension values */ |
331 | #define SADB_IDENTTYPE_RESERVED 0 | 342 | #define SADB_IDENTTYPE_RESERVED 0 |
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index e87b233615b3..d10f35338507 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h | |||
@@ -429,6 +429,7 @@ enum | |||
429 | TCA_NETEM_CORR, | 429 | TCA_NETEM_CORR, |
430 | TCA_NETEM_DELAY_DIST, | 430 | TCA_NETEM_DELAY_DIST, |
431 | TCA_NETEM_REORDER, | 431 | TCA_NETEM_REORDER, |
432 | TCA_NETEM_CORRUPT, | ||
432 | __TCA_NETEM_MAX, | 433 | __TCA_NETEM_MAX, |
433 | }; | 434 | }; |
434 | 435 | ||
@@ -457,6 +458,12 @@ struct tc_netem_reorder | |||
457 | __u32 correlation; | 458 | __u32 correlation; |
458 | }; | 459 | }; |
459 | 460 | ||
461 | struct tc_netem_corrupt | ||
462 | { | ||
463 | __u32 probability; | ||
464 | __u32 correlation; | ||
465 | }; | ||
466 | |||
460 | #define NETEM_DIST_SCALE 8192 | 467 | #define NETEM_DIST_SCALE 8192 |
461 | 468 | ||
462 | #endif | 469 | #endif |
diff --git a/include/linux/preempt.h b/include/linux/preempt.h index d9a2f5254a51..5769d14d1e6a 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h | |||
@@ -48,6 +48,7 @@ do { \ | |||
48 | #define preempt_enable() \ | 48 | #define preempt_enable() \ |
49 | do { \ | 49 | do { \ |
50 | preempt_enable_no_resched(); \ | 50 | preempt_enable_no_resched(); \ |
51 | barrier(); \ | ||
51 | preempt_check_resched(); \ | 52 | preempt_check_resched(); \ |
52 | } while (0) | 53 | } while (0) |
53 | 54 | ||
diff --git a/include/linux/random.h b/include/linux/random.h index 7b2adb3322d5..5d6456bcdeba 100644 --- a/include/linux/random.h +++ b/include/linux/random.h | |||
@@ -52,9 +52,9 @@ extern void get_random_bytes(void *buf, int nbytes); | |||
52 | void generate_random_uuid(unsigned char uuid_out[16]); | 52 | void generate_random_uuid(unsigned char uuid_out[16]); |
53 | 53 | ||
54 | extern __u32 secure_ip_id(__u32 daddr); | 54 | extern __u32 secure_ip_id(__u32 daddr); |
55 | extern u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport); | 55 | extern u32 secure_ipv4_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport); |
56 | extern u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, | 56 | extern u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, |
57 | __u16 dport); | 57 | __u16 dport); |
58 | extern __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr, | 58 | extern __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr, |
59 | __u16 sport, __u16 dport); | 59 | __u16 sport, __u16 dport); |
60 | extern __u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr, | 60 | extern __u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr, |
diff --git a/include/linux/relayfs_fs.h b/include/linux/relayfs_fs.h index cfafc3e76bc2..fb7e80737325 100644 --- a/include/linux/relayfs_fs.h +++ b/include/linux/relayfs_fs.h | |||
@@ -20,9 +20,9 @@ | |||
20 | #include <linux/kref.h> | 20 | #include <linux/kref.h> |
21 | 21 | ||
22 | /* | 22 | /* |
23 | * Tracks changes to rchan_buf struct | 23 | * Tracks changes to rchan/rchan_buf structs |
24 | */ | 24 | */ |
25 | #define RELAYFS_CHANNEL_VERSION 5 | 25 | #define RELAYFS_CHANNEL_VERSION 6 |
26 | 26 | ||
27 | /* | 27 | /* |
28 | * Per-cpu relay channel buffer | 28 | * Per-cpu relay channel buffer |
@@ -60,6 +60,7 @@ struct rchan | |||
60 | struct rchan_callbacks *cb; /* client callbacks */ | 60 | struct rchan_callbacks *cb; /* client callbacks */ |
61 | struct kref kref; /* channel refcount */ | 61 | struct kref kref; /* channel refcount */ |
62 | void *private_data; /* for user-defined data */ | 62 | void *private_data; /* for user-defined data */ |
63 | size_t last_toobig; /* tried to log event > subbuf size */ | ||
63 | struct rchan_buf *buf[NR_CPUS]; /* per-cpu channel buffers */ | 64 | struct rchan_buf *buf[NR_CPUS]; /* per-cpu channel buffers */ |
64 | }; | 65 | }; |
65 | 66 | ||
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index c231e9a08f0b..d50482ba27fe 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h | |||
@@ -866,6 +866,7 @@ enum rtnetlink_groups { | |||
866 | #define RTNLGRP_IPV4_MROUTE RTNLGRP_IPV4_MROUTE | 866 | #define RTNLGRP_IPV4_MROUTE RTNLGRP_IPV4_MROUTE |
867 | RTNLGRP_IPV4_ROUTE, | 867 | RTNLGRP_IPV4_ROUTE, |
868 | #define RTNLGRP_IPV4_ROUTE RTNLGRP_IPV4_ROUTE | 868 | #define RTNLGRP_IPV4_ROUTE RTNLGRP_IPV4_ROUTE |
869 | RTNLGRP_NOP1, | ||
869 | RTNLGRP_IPV6_IFADDR, | 870 | RTNLGRP_IPV6_IFADDR, |
870 | #define RTNLGRP_IPV6_IFADDR RTNLGRP_IPV6_IFADDR | 871 | #define RTNLGRP_IPV6_IFADDR RTNLGRP_IPV6_IFADDR |
871 | RTNLGRP_IPV6_MROUTE, | 872 | RTNLGRP_IPV6_MROUTE, |
@@ -876,8 +877,11 @@ enum rtnetlink_groups { | |||
876 | #define RTNLGRP_IPV6_IFINFO RTNLGRP_IPV6_IFINFO | 877 | #define RTNLGRP_IPV6_IFINFO RTNLGRP_IPV6_IFINFO |
877 | RTNLGRP_DECnet_IFADDR, | 878 | RTNLGRP_DECnet_IFADDR, |
878 | #define RTNLGRP_DECnet_IFADDR RTNLGRP_DECnet_IFADDR | 879 | #define RTNLGRP_DECnet_IFADDR RTNLGRP_DECnet_IFADDR |
880 | RTNLGRP_NOP2, | ||
879 | RTNLGRP_DECnet_ROUTE, | 881 | RTNLGRP_DECnet_ROUTE, |
880 | #define RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_ROUTE | 882 | #define RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_ROUTE |
883 | RTNLGRP_NOP3, | ||
884 | RTNLGRP_NOP4, | ||
881 | RTNLGRP_IPV6_PREFIX, | 885 | RTNLGRP_IPV6_PREFIX, |
882 | #define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX | 886 | #define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX |
883 | __RTNLGRP_MAX | 887 | __RTNLGRP_MAX |
diff --git a/include/linux/security.h b/include/linux/security.h index f7e0ae018712..ef753654daa5 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -59,6 +59,12 @@ struct sk_buff; | |||
59 | struct sock; | 59 | struct sock; |
60 | struct sockaddr; | 60 | struct sockaddr; |
61 | struct socket; | 61 | struct socket; |
62 | struct flowi; | ||
63 | struct dst_entry; | ||
64 | struct xfrm_selector; | ||
65 | struct xfrm_policy; | ||
66 | struct xfrm_state; | ||
67 | struct xfrm_user_sec_ctx; | ||
62 | 68 | ||
63 | extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); | 69 | extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb); |
64 | extern int cap_netlink_recv(struct sk_buff *skb); | 70 | extern int cap_netlink_recv(struct sk_buff *skb); |
@@ -788,6 +794,52 @@ struct swap_info_struct; | |||
788 | * which is used to copy security attributes between local stream sockets. | 794 | * which is used to copy security attributes between local stream sockets. |
789 | * @sk_free_security: | 795 | * @sk_free_security: |
790 | * Deallocate security structure. | 796 | * Deallocate security structure. |
797 | * @sk_getsid: | ||
798 | * Retrieve the LSM-specific sid for the sock to enable caching of network | ||
799 | * authorizations. | ||
800 | * | ||
801 | * Security hooks for XFRM operations. | ||
802 | * | ||
803 | * @xfrm_policy_alloc_security: | ||
804 | * @xp contains the xfrm_policy being added to Security Policy Database | ||
805 | * used by the XFRM system. | ||
806 | * @sec_ctx contains the security context information being provided by | ||
807 | * the user-level policy update program (e.g., setkey). | ||
808 | * Allocate a security structure to the xp->selector.security field. | ||
809 | * The security field is initialized to NULL when the xfrm_policy is | ||
810 | * allocated. | ||
811 | * Return 0 if operation was successful (memory to allocate, legal context) | ||
812 | * @xfrm_policy_clone_security: | ||
813 | * @old contains an existing xfrm_policy in the SPD. | ||
814 | * @new contains a new xfrm_policy being cloned from old. | ||
815 | * Allocate a security structure to the new->selector.security field | ||
816 | * that contains the information from the old->selector.security field. | ||
817 | * Return 0 if operation was successful (memory to allocate). | ||
818 | * @xfrm_policy_free_security: | ||
819 | * @xp contains the xfrm_policy | ||
820 | * Deallocate xp->selector.security. | ||
821 | * @xfrm_state_alloc_security: | ||
822 | * @x contains the xfrm_state being added to the Security Association | ||
823 | * Database by the XFRM system. | ||
824 | * @sec_ctx contains the security context information being provided by | ||
825 | * the user-level SA generation program (e.g., setkey or racoon). | ||
826 | * Allocate a security structure to the x->sel.security field. The | ||
827 | * security field is initialized to NULL when the xfrm_state is | ||
828 | * allocated. | ||
829 | * Return 0 if operation was successful (memory to allocate, legal context). | ||
830 | * @xfrm_state_free_security: | ||
831 | * @x contains the xfrm_state. | ||
832 | * Deallocate x>sel.security. | ||
833 | * @xfrm_policy_lookup: | ||
834 | * @xp contains the xfrm_policy for which the access control is being | ||
835 | * checked. | ||
836 | * @sk_sid contains the sock security label that is used to authorize | ||
837 | * access to the policy xp. | ||
838 | * @dir contains the direction of the flow (input or output). | ||
839 | * Check permission when a sock selects a xfrm_policy for processing | ||
840 | * XFRMs on a packet. The hook is called when selecting either a | ||
841 | * per-socket policy or a generic xfrm policy. | ||
842 | * Return 0 if permission is granted. | ||
791 | * | 843 | * |
792 | * Security hooks affecting all Key Management operations | 844 | * Security hooks affecting all Key Management operations |
793 | * | 845 | * |
@@ -1237,8 +1289,18 @@ struct security_operations { | |||
1237 | int (*socket_getpeersec) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len); | 1289 | int (*socket_getpeersec) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len); |
1238 | int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority); | 1290 | int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority); |
1239 | void (*sk_free_security) (struct sock *sk); | 1291 | void (*sk_free_security) (struct sock *sk); |
1292 | unsigned int (*sk_getsid) (struct sock *sk, struct flowi *fl, u8 dir); | ||
1240 | #endif /* CONFIG_SECURITY_NETWORK */ | 1293 | #endif /* CONFIG_SECURITY_NETWORK */ |
1241 | 1294 | ||
1295 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | ||
1296 | int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx); | ||
1297 | int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new); | ||
1298 | void (*xfrm_policy_free_security) (struct xfrm_policy *xp); | ||
1299 | int (*xfrm_state_alloc_security) (struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx); | ||
1300 | void (*xfrm_state_free_security) (struct xfrm_state *x); | ||
1301 | int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 sk_sid, u8 dir); | ||
1302 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ | ||
1303 | |||
1242 | /* key management security hooks */ | 1304 | /* key management security hooks */ |
1243 | #ifdef CONFIG_KEYS | 1305 | #ifdef CONFIG_KEYS |
1244 | int (*key_alloc)(struct key *key); | 1306 | int (*key_alloc)(struct key *key); |
@@ -2679,6 +2741,11 @@ static inline void security_sk_free(struct sock *sk) | |||
2679 | { | 2741 | { |
2680 | return security_ops->sk_free_security(sk); | 2742 | return security_ops->sk_free_security(sk); |
2681 | } | 2743 | } |
2744 | |||
2745 | static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir) | ||
2746 | { | ||
2747 | return security_ops->sk_getsid(sk, fl, dir); | ||
2748 | } | ||
2682 | #else /* CONFIG_SECURITY_NETWORK */ | 2749 | #else /* CONFIG_SECURITY_NETWORK */ |
2683 | static inline int security_unix_stream_connect(struct socket * sock, | 2750 | static inline int security_unix_stream_connect(struct socket * sock, |
2684 | struct socket * other, | 2751 | struct socket * other, |
@@ -2795,8 +2862,73 @@ static inline int security_sk_alloc(struct sock *sk, int family, gfp_t priority) | |||
2795 | static inline void security_sk_free(struct sock *sk) | 2862 | static inline void security_sk_free(struct sock *sk) |
2796 | { | 2863 | { |
2797 | } | 2864 | } |
2865 | |||
2866 | static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir) | ||
2867 | { | ||
2868 | return 0; | ||
2869 | } | ||
2798 | #endif /* CONFIG_SECURITY_NETWORK */ | 2870 | #endif /* CONFIG_SECURITY_NETWORK */ |
2799 | 2871 | ||
2872 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | ||
2873 | static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) | ||
2874 | { | ||
2875 | return security_ops->xfrm_policy_alloc_security(xp, sec_ctx); | ||
2876 | } | ||
2877 | |||
2878 | static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) | ||
2879 | { | ||
2880 | return security_ops->xfrm_policy_clone_security(old, new); | ||
2881 | } | ||
2882 | |||
2883 | static inline void security_xfrm_policy_free(struct xfrm_policy *xp) | ||
2884 | { | ||
2885 | security_ops->xfrm_policy_free_security(xp); | ||
2886 | } | ||
2887 | |||
2888 | static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) | ||
2889 | { | ||
2890 | return security_ops->xfrm_state_alloc_security(x, sec_ctx); | ||
2891 | } | ||
2892 | |||
2893 | static inline void security_xfrm_state_free(struct xfrm_state *x) | ||
2894 | { | ||
2895 | security_ops->xfrm_state_free_security(x); | ||
2896 | } | ||
2897 | |||
2898 | static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) | ||
2899 | { | ||
2900 | return security_ops->xfrm_policy_lookup(xp, sk_sid, dir); | ||
2901 | } | ||
2902 | #else /* CONFIG_SECURITY_NETWORK_XFRM */ | ||
2903 | static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) | ||
2904 | { | ||
2905 | return 0; | ||
2906 | } | ||
2907 | |||
2908 | static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) | ||
2909 | { | ||
2910 | return 0; | ||
2911 | } | ||
2912 | |||
2913 | static inline void security_xfrm_policy_free(struct xfrm_policy *xp) | ||
2914 | { | ||
2915 | } | ||
2916 | |||
2917 | static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) | ||
2918 | { | ||
2919 | return 0; | ||
2920 | } | ||
2921 | |||
2922 | static inline void security_xfrm_state_free(struct xfrm_state *x) | ||
2923 | { | ||
2924 | } | ||
2925 | |||
2926 | static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) | ||
2927 | { | ||
2928 | return 0; | ||
2929 | } | ||
2930 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ | ||
2931 | |||
2800 | #ifdef CONFIG_KEYS | 2932 | #ifdef CONFIG_KEYS |
2801 | #ifdef CONFIG_SECURITY | 2933 | #ifdef CONFIG_SECURITY |
2802 | static inline int security_key_alloc(struct key *key) | 2934 | static inline int security_key_alloc(struct key *key) |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 8c5d6001a923..483cfc47ec34 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -32,7 +32,6 @@ | |||
32 | 32 | ||
33 | #define HAVE_ALLOC_SKB /* For the drivers to know */ | 33 | #define HAVE_ALLOC_SKB /* For the drivers to know */ |
34 | #define HAVE_ALIGNABLE_SKB /* Ditto 8) */ | 34 | #define HAVE_ALIGNABLE_SKB /* Ditto 8) */ |
35 | #define SLAB_SKB /* Slabified skbuffs */ | ||
36 | 35 | ||
37 | #define CHECKSUM_NONE 0 | 36 | #define CHECKSUM_NONE 0 |
38 | #define CHECKSUM_HW 1 | 37 | #define CHECKSUM_HW 1 |
@@ -134,7 +133,7 @@ struct skb_frag_struct { | |||
134 | */ | 133 | */ |
135 | struct skb_shared_info { | 134 | struct skb_shared_info { |
136 | atomic_t dataref; | 135 | atomic_t dataref; |
137 | unsigned int nr_frags; | 136 | unsigned short nr_frags; |
138 | unsigned short tso_size; | 137 | unsigned short tso_size; |
139 | unsigned short tso_segs; | 138 | unsigned short tso_segs; |
140 | unsigned short ufo_size; | 139 | unsigned short ufo_size; |
@@ -1239,6 +1238,8 @@ extern int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, | |||
1239 | int hlen, | 1238 | int hlen, |
1240 | struct iovec *iov); | 1239 | struct iovec *iov); |
1241 | extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb); | 1240 | extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb); |
1241 | extern void skb_kill_datagram(struct sock *sk, struct sk_buff *skb, | ||
1242 | unsigned int flags); | ||
1242 | extern unsigned int skb_checksum(const struct sk_buff *skb, int offset, | 1243 | extern unsigned int skb_checksum(const struct sk_buff *skb, int offset, |
1243 | int len, unsigned int csum); | 1244 | int len, unsigned int csum); |
1244 | extern int skb_copy_bits(const struct sk_buff *skb, int offset, | 1245 | extern int skb_copy_bits(const struct sk_buff *skb, int offset, |
diff --git a/include/linux/socket.h b/include/linux/socket.h index 1739c2d5b95b..9f4019156fd8 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h | |||
@@ -27,7 +27,6 @@ struct __kernel_sockaddr_storage { | |||
27 | #include <linux/compiler.h> /* __user */ | 27 | #include <linux/compiler.h> /* __user */ |
28 | 28 | ||
29 | extern int sysctl_somaxconn; | 29 | extern int sysctl_somaxconn; |
30 | extern void sock_init(void); | ||
31 | #ifdef CONFIG_PROC_FS | 30 | #ifdef CONFIG_PROC_FS |
32 | struct seq_file; | 31 | struct seq_file; |
33 | extern void socket_seq_show(struct seq_file *seq); | 32 | extern void socket_seq_show(struct seq_file *seq); |
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 4be34ef8c2f7..93fa765e47d3 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h | |||
@@ -390,6 +390,7 @@ enum | |||
390 | NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109, | 390 | NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109, |
391 | NET_TCP_CONG_CONTROL=110, | 391 | NET_TCP_CONG_CONTROL=110, |
392 | NET_TCP_ABC=111, | 392 | NET_TCP_ABC=111, |
393 | NET_IPV4_IPFRAG_MAX_DIST=112, | ||
393 | }; | 394 | }; |
394 | 395 | ||
395 | enum { | 396 | enum { |
diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 0e1da6602e05..f2bb2396853f 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h | |||
@@ -55,22 +55,6 @@ struct tcphdr { | |||
55 | __u16 urg_ptr; | 55 | __u16 urg_ptr; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | #define TCP_ACTION_FIN (1 << 7) | ||
59 | |||
60 | enum { | ||
61 | TCPF_ESTABLISHED = (1 << 1), | ||
62 | TCPF_SYN_SENT = (1 << 2), | ||
63 | TCPF_SYN_RECV = (1 << 3), | ||
64 | TCPF_FIN_WAIT1 = (1 << 4), | ||
65 | TCPF_FIN_WAIT2 = (1 << 5), | ||
66 | TCPF_TIME_WAIT = (1 << 6), | ||
67 | TCPF_CLOSE = (1 << 7), | ||
68 | TCPF_CLOSE_WAIT = (1 << 8), | ||
69 | TCPF_LAST_ACK = (1 << 9), | ||
70 | TCPF_LISTEN = (1 << 10), | ||
71 | TCPF_CLOSING = (1 << 11) | ||
72 | }; | ||
73 | |||
74 | /* | 58 | /* |
75 | * The union cast uses a gcc extension to avoid aliasing problems | 59 | * The union cast uses a gcc extension to avoid aliasing problems |
76 | * (union is compatible to any of its members) | 60 | * (union is compatible to any of its members) |
@@ -254,10 +238,9 @@ struct tcp_sock { | |||
254 | __u32 snd_wl1; /* Sequence for window update */ | 238 | __u32 snd_wl1; /* Sequence for window update */ |
255 | __u32 snd_wnd; /* The window we expect to receive */ | 239 | __u32 snd_wnd; /* The window we expect to receive */ |
256 | __u32 max_window; /* Maximal window ever seen from peer */ | 240 | __u32 max_window; /* Maximal window ever seen from peer */ |
257 | __u32 pmtu_cookie; /* Last pmtu seen by socket */ | ||
258 | __u32 mss_cache; /* Cached effective mss, not including SACKS */ | 241 | __u32 mss_cache; /* Cached effective mss, not including SACKS */ |
259 | __u16 xmit_size_goal; /* Goal for segmenting output packets */ | 242 | __u16 xmit_size_goal; /* Goal for segmenting output packets */ |
260 | __u16 ext_header_len; /* Network protocol overhead (IP/IPv6 options) */ | 243 | /* XXX Two bytes hole, try to pack */ |
261 | 244 | ||
262 | __u32 window_clamp; /* Maximal window to advertise */ | 245 | __u32 window_clamp; /* Maximal window to advertise */ |
263 | __u32 rcv_ssthresh; /* Current window clamp */ | 246 | __u32 rcv_ssthresh; /* Current window clamp */ |
@@ -295,8 +278,6 @@ struct tcp_sock { | |||
295 | 278 | ||
296 | struct sk_buff_head out_of_order_queue; /* Out of order segments go here */ | 279 | struct sk_buff_head out_of_order_queue; /* Out of order segments go here */ |
297 | 280 | ||
298 | struct tcp_func *af_specific; /* Operations which are AF_INET{4,6} specific */ | ||
299 | |||
300 | __u32 rcv_wnd; /* Current receiver window */ | 281 | __u32 rcv_wnd; /* Current receiver window */ |
301 | __u32 rcv_wup; /* rcv_nxt on last window update sent */ | 282 | __u32 rcv_wup; /* rcv_nxt on last window update sent */ |
302 | __u32 write_seq; /* Tail(+1) of data held in tcp send buffer */ | 283 | __u32 write_seq; /* Tail(+1) of data held in tcp send buffer */ |
diff --git a/include/linux/udp.h b/include/linux/udp.h index b60e0b4a25c4..85a55658831c 100644 --- a/include/linux/udp.h +++ b/include/linux/udp.h | |||
@@ -35,10 +35,10 @@ struct udphdr { | |||
35 | #define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */ | 35 | #define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */ |
36 | 36 | ||
37 | #ifdef __KERNEL__ | 37 | #ifdef __KERNEL__ |
38 | |||
39 | #include <linux/config.h> | 38 | #include <linux/config.h> |
40 | #include <net/sock.h> | 39 | #include <linux/types.h> |
41 | #include <linux/ip.h> | 40 | |
41 | #include <net/inet_sock.h> | ||
42 | 42 | ||
43 | struct udp_sock { | 43 | struct udp_sock { |
44 | /* inet_sock has to be the first member */ | 44 | /* inet_sock has to be the first member */ |
diff --git a/include/linux/usb.h b/include/linux/usb.h index d81b050e5955..e59d1bd52d4f 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -329,8 +329,6 @@ struct usb_device { | |||
329 | struct usb_tt *tt; /* low/full speed dev, highspeed hub */ | 329 | struct usb_tt *tt; /* low/full speed dev, highspeed hub */ |
330 | int ttport; /* device port on that tt hub */ | 330 | int ttport; /* device port on that tt hub */ |
331 | 331 | ||
332 | struct semaphore serialize; | ||
333 | |||
334 | unsigned int toggle[2]; /* one bit for each endpoint | 332 | unsigned int toggle[2]; /* one bit for each endpoint |
335 | * ([0] = IN, [1] = OUT) */ | 333 | * ([0] = IN, [1] = OUT) */ |
336 | 334 | ||
@@ -349,6 +347,9 @@ struct usb_device { | |||
349 | 347 | ||
350 | char **rawdescriptors; /* Raw descriptors for each config */ | 348 | char **rawdescriptors; /* Raw descriptors for each config */ |
351 | 349 | ||
350 | unsigned short bus_mA; /* Current available from the bus */ | ||
351 | u8 portnum; /* Parent port number (origin 1) */ | ||
352 | |||
352 | int have_langid; /* whether string_langid is valid */ | 353 | int have_langid; /* whether string_langid is valid */ |
353 | int string_langid; /* language ID for strings */ | 354 | int string_langid; /* language ID for strings */ |
354 | 355 | ||
@@ -377,11 +378,12 @@ struct usb_device { | |||
377 | extern struct usb_device *usb_get_dev(struct usb_device *dev); | 378 | extern struct usb_device *usb_get_dev(struct usb_device *dev); |
378 | extern void usb_put_dev(struct usb_device *dev); | 379 | extern void usb_put_dev(struct usb_device *dev); |
379 | 380 | ||
380 | extern void usb_lock_device(struct usb_device *udev); | 381 | /* USB device locking */ |
381 | extern int usb_trylock_device(struct usb_device *udev); | 382 | #define usb_lock_device(udev) down(&(udev)->dev.sem) |
383 | #define usb_unlock_device(udev) up(&(udev)->dev.sem) | ||
384 | #define usb_trylock_device(udev) down_trylock(&(udev)->dev.sem) | ||
382 | extern int usb_lock_device_for_reset(struct usb_device *udev, | 385 | extern int usb_lock_device_for_reset(struct usb_device *udev, |
383 | struct usb_interface *iface); | 386 | struct usb_interface *iface); |
384 | extern void usb_unlock_device(struct usb_device *udev); | ||
385 | 387 | ||
386 | /* USB port reset for device reinitialization */ | 388 | /* USB port reset for device reinitialization */ |
387 | extern int usb_reset_device(struct usb_device *dev); | 389 | extern int usb_reset_device(struct usb_device *dev); |
@@ -529,10 +531,13 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, | |||
529 | 531 | ||
530 | /* ----------------------------------------------------------------------- */ | 532 | /* ----------------------------------------------------------------------- */ |
531 | 533 | ||
534 | struct usb_dynids { | ||
535 | spinlock_t lock; | ||
536 | struct list_head list; | ||
537 | }; | ||
538 | |||
532 | /** | 539 | /** |
533 | * struct usb_driver - identifies USB driver to usbcore | 540 | * struct usb_driver - identifies USB driver to usbcore |
534 | * @owner: Pointer to the module owner of this driver; initialize | ||
535 | * it using THIS_MODULE. | ||
536 | * @name: The driver name should be unique among USB drivers, | 541 | * @name: The driver name should be unique among USB drivers, |
537 | * and should normally be the same as the module name. | 542 | * and should normally be the same as the module name. |
538 | * @probe: Called to see if the driver is willing to manage a particular | 543 | * @probe: Called to see if the driver is willing to manage a particular |
@@ -553,7 +558,11 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, | |||
553 | * @id_table: USB drivers use ID table to support hotplugging. | 558 | * @id_table: USB drivers use ID table to support hotplugging. |
554 | * Export this with MODULE_DEVICE_TABLE(usb,...). This must be set | 559 | * Export this with MODULE_DEVICE_TABLE(usb,...). This must be set |
555 | * or your driver's probe function will never get called. | 560 | * or your driver's probe function will never get called. |
561 | * @dynids: used internally to hold the list of dynamically added device | ||
562 | * ids for this driver. | ||
556 | * @driver: the driver model core driver structure. | 563 | * @driver: the driver model core driver structure. |
564 | * @no_dynamic_id: if set to 1, the USB core will not allow dynamic ids to be | ||
565 | * added to this driver by preventing the sysfs file from being created. | ||
557 | * | 566 | * |
558 | * USB drivers must provide a name, probe() and disconnect() methods, | 567 | * USB drivers must provide a name, probe() and disconnect() methods, |
559 | * and an id_table. Other driver fields are optional. | 568 | * and an id_table. Other driver fields are optional. |
@@ -571,8 +580,6 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, | |||
571 | * them as necessary, and blocking until the unlinks complete). | 580 | * them as necessary, and blocking until the unlinks complete). |
572 | */ | 581 | */ |
573 | struct usb_driver { | 582 | struct usb_driver { |
574 | struct module *owner; | ||
575 | |||
576 | const char *name; | 583 | const char *name; |
577 | 584 | ||
578 | int (*probe) (struct usb_interface *intf, | 585 | int (*probe) (struct usb_interface *intf, |
@@ -588,7 +595,9 @@ struct usb_driver { | |||
588 | 595 | ||
589 | const struct usb_device_id *id_table; | 596 | const struct usb_device_id *id_table; |
590 | 597 | ||
598 | struct usb_dynids dynids; | ||
591 | struct device_driver driver; | 599 | struct device_driver driver; |
600 | unsigned int no_dynamic_id:1; | ||
592 | }; | 601 | }; |
593 | #define to_usb_driver(d) container_of(d, struct usb_driver, driver) | 602 | #define to_usb_driver(d) container_of(d, struct usb_driver, driver) |
594 | 603 | ||
@@ -614,7 +623,11 @@ struct usb_class_driver { | |||
614 | * use these in module_init()/module_exit() | 623 | * use these in module_init()/module_exit() |
615 | * and don't forget MODULE_DEVICE_TABLE(usb, ...) | 624 | * and don't forget MODULE_DEVICE_TABLE(usb, ...) |
616 | */ | 625 | */ |
617 | extern int usb_register(struct usb_driver *); | 626 | int usb_register_driver(struct usb_driver *, struct module *); |
627 | static inline int usb_register(struct usb_driver *driver) | ||
628 | { | ||
629 | return usb_register_driver(driver, THIS_MODULE); | ||
630 | } | ||
618 | extern void usb_deregister(struct usb_driver *); | 631 | extern void usb_deregister(struct usb_driver *); |
619 | 632 | ||
620 | extern int usb_register_dev(struct usb_interface *intf, | 633 | extern int usb_register_dev(struct usb_interface *intf, |
diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h new file mode 100644 index 000000000000..b2d08984a9f7 --- /dev/null +++ b/include/linux/usb_usual.h | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * Interface to the libusual. | ||
3 | * | ||
4 | * Copyright (c) 2005 Pete Zaitcev <zaitcev@redhat.com> | ||
5 | * Copyright (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net) | ||
6 | * Copyright (c) 1999 Michael Gee (michael@linuxspecific.com) | ||
7 | */ | ||
8 | |||
9 | #ifndef __LINUX_USB_USUAL_H | ||
10 | #define __LINUX_USB_USUAL_H | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | |||
14 | /* We should do this for cleanliness... But other usb_foo.h do not do this. */ | ||
15 | /* #include <linux/usb.h> */ | ||
16 | |||
17 | /* | ||
18 | * The flags field, which we store in usb_device_id.driver_info. | ||
19 | * It is compatible with the old usb-storage flags in lower 24 bits. | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * Static flag definitions. We use this roundabout technique so that the | ||
24 | * proc_info() routine can automatically display a message for each flag. | ||
25 | */ | ||
26 | #define US_DO_ALL_FLAGS \ | ||
27 | US_FLAG(SINGLE_LUN, 0x00000001) \ | ||
28 | /* allow access to only LUN 0 */ \ | ||
29 | US_FLAG(NEED_OVERRIDE, 0x00000002) \ | ||
30 | /* unusual_devs entry is necessary */ \ | ||
31 | US_FLAG(SCM_MULT_TARG, 0x00000004) \ | ||
32 | /* supports multiple targets */ \ | ||
33 | US_FLAG(FIX_INQUIRY, 0x00000008) \ | ||
34 | /* INQUIRY response needs faking */ \ | ||
35 | US_FLAG(FIX_CAPACITY, 0x00000010) \ | ||
36 | /* READ CAPACITY response too big */ \ | ||
37 | US_FLAG(IGNORE_RESIDUE, 0x00000020) \ | ||
38 | /* reported residue is wrong */ \ | ||
39 | US_FLAG(BULK32, 0x00000040) \ | ||
40 | /* Uses 32-byte CBW length */ \ | ||
41 | US_FLAG(NOT_LOCKABLE, 0x00000080) \ | ||
42 | /* PREVENT/ALLOW not supported */ \ | ||
43 | US_FLAG(GO_SLOW, 0x00000100) \ | ||
44 | /* Need delay after Command phase */ \ | ||
45 | US_FLAG(NO_WP_DETECT, 0x00000200) \ | ||
46 | /* Don't check for write-protect */ \ | ||
47 | |||
48 | #define US_FLAG(name, value) US_FL_##name = value , | ||
49 | enum { US_DO_ALL_FLAGS }; | ||
50 | #undef US_FLAG | ||
51 | |||
52 | /* | ||
53 | * The bias field for libusual and friends. | ||
54 | */ | ||
55 | #define USB_US_TYPE_NONE 0 | ||
56 | #define USB_US_TYPE_STOR 1 /* usb-storage */ | ||
57 | #define USB_US_TYPE_UB 2 /* ub */ | ||
58 | |||
59 | #define USB_US_TYPE(flags) (((flags) >> 24) & 0xFF) | ||
60 | #define USB_US_ORIG_FLAGS(flags) ((flags) & 0x00FFFFFF) | ||
61 | |||
62 | /* | ||
63 | * This is probably not the best place to keep these constants, conceptually. | ||
64 | * But it's the only header included into all places which need them. | ||
65 | */ | ||
66 | |||
67 | /* Sub Classes */ | ||
68 | |||
69 | #define US_SC_RBC 0x01 /* Typically, flash devices */ | ||
70 | #define US_SC_8020 0x02 /* CD-ROM */ | ||
71 | #define US_SC_QIC 0x03 /* QIC-157 Tapes */ | ||
72 | #define US_SC_UFI 0x04 /* Floppy */ | ||
73 | #define US_SC_8070 0x05 /* Removable media */ | ||
74 | #define US_SC_SCSI 0x06 /* Transparent */ | ||
75 | #define US_SC_ISD200 0x07 /* ISD200 ATA */ | ||
76 | #define US_SC_MIN US_SC_RBC | ||
77 | #define US_SC_MAX US_SC_ISD200 | ||
78 | |||
79 | #define US_SC_DEVICE 0xff /* Use device's value */ | ||
80 | |||
81 | /* Protocols */ | ||
82 | |||
83 | #define US_PR_CBI 0x00 /* Control/Bulk/Interrupt */ | ||
84 | #define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */ | ||
85 | #define US_PR_BULK 0x50 /* bulk only */ | ||
86 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
87 | #define US_PR_USBAT 0x80 /* SCM-ATAPI bridge */ | ||
88 | #endif | ||
89 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
90 | #define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */ | ||
91 | #endif | ||
92 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
93 | #define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */ | ||
94 | #endif | ||
95 | #define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */ | ||
96 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
97 | #define US_PR_FREECOM 0xf1 /* Freecom */ | ||
98 | #endif | ||
99 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
100 | #define US_PR_DATAFAB 0xf2 /* Datafab chipsets */ | ||
101 | #endif | ||
102 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | ||
103 | #define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */ | ||
104 | #endif | ||
105 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
106 | #define US_PR_ALAUDA 0xf4 /* Alauda chipsets */ | ||
107 | #endif | ||
108 | |||
109 | #define US_PR_DEVICE 0xff /* Use device's value */ | ||
110 | |||
111 | /* | ||
112 | */ | ||
113 | #ifdef CONFIG_USB_LIBUSUAL | ||
114 | |||
115 | extern struct usb_device_id storage_usb_ids[]; | ||
116 | extern void usb_usual_set_present(int type); | ||
117 | extern void usb_usual_clear_present(int type); | ||
118 | extern int usb_usual_check_type(const struct usb_device_id *, int type); | ||
119 | #else | ||
120 | |||
121 | #define usb_usual_set_present(t) do { } while(0) | ||
122 | #define usb_usual_clear_present(t) do { } while(0) | ||
123 | #define usb_usual_check_type(id, t) (0) | ||
124 | #endif /* CONFIG_USB_LIBUSUAL */ | ||
125 | |||
126 | #endif /* __LINUX_USB_USUAL_H */ | ||
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 0fb077d68441..82fbb758e28f 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h | |||
@@ -27,6 +27,22 @@ struct xfrm_id | |||
27 | __u8 proto; | 27 | __u8 proto; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | struct xfrm_sec_ctx { | ||
31 | __u8 ctx_doi; | ||
32 | __u8 ctx_alg; | ||
33 | __u16 ctx_len; | ||
34 | __u32 ctx_sid; | ||
35 | char ctx_str[0]; | ||
36 | }; | ||
37 | |||
38 | /* Security Context Domains of Interpretation */ | ||
39 | #define XFRM_SC_DOI_RESERVED 0 | ||
40 | #define XFRM_SC_DOI_LSM 1 | ||
41 | |||
42 | /* Security Context Algorithms */ | ||
43 | #define XFRM_SC_ALG_RESERVED 0 | ||
44 | #define XFRM_SC_ALG_SELINUX 1 | ||
45 | |||
30 | /* Selector, used as selector both on policy rules (SPD) and SAs. */ | 46 | /* Selector, used as selector both on policy rules (SPD) and SAs. */ |
31 | 47 | ||
32 | struct xfrm_selector | 48 | struct xfrm_selector |
@@ -146,6 +162,18 @@ enum { | |||
146 | 162 | ||
147 | #define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE) | 163 | #define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE) |
148 | 164 | ||
165 | /* | ||
166 | * Generic LSM security context for comunicating to user space | ||
167 | * NOTE: Same format as sadb_x_sec_ctx | ||
168 | */ | ||
169 | struct xfrm_user_sec_ctx { | ||
170 | __u16 len; | ||
171 | __u16 exttype; | ||
172 | __u8 ctx_alg; /* LSMs: e.g., selinux == 1 */ | ||
173 | __u8 ctx_doi; | ||
174 | __u16 ctx_len; | ||
175 | }; | ||
176 | |||
149 | struct xfrm_user_tmpl { | 177 | struct xfrm_user_tmpl { |
150 | struct xfrm_id id; | 178 | struct xfrm_id id; |
151 | __u16 family; | 179 | __u16 family; |
@@ -176,6 +204,7 @@ enum xfrm_attr_type_t { | |||
176 | XFRMA_TMPL, /* 1 or more struct xfrm_user_tmpl */ | 204 | XFRMA_TMPL, /* 1 or more struct xfrm_user_tmpl */ |
177 | XFRMA_SA, | 205 | XFRMA_SA, |
178 | XFRMA_POLICY, | 206 | XFRMA_POLICY, |
207 | XFRMA_SEC_CTX, /* struct xfrm_sec_ctx */ | ||
179 | __XFRMA_MAX | 208 | __XFRMA_MAX |
180 | 209 | ||
181 | #define XFRMA_MAX (__XFRMA_MAX - 1) | 210 | #define XFRMA_MAX (__XFRMA_MAX - 1) |
diff --git a/include/net/af_unix.h b/include/net/af_unix.h index b5d785ab4a0e..bfc1779fc753 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h | |||
@@ -13,7 +13,7 @@ extern void unix_gc(void); | |||
13 | #define UNIX_HASH_SIZE 256 | 13 | #define UNIX_HASH_SIZE 256 |
14 | 14 | ||
15 | extern struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; | 15 | extern struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; |
16 | extern rwlock_t unix_table_lock; | 16 | extern spinlock_t unix_table_lock; |
17 | 17 | ||
18 | extern atomic_t unix_tot_inflight; | 18 | extern atomic_t unix_tot_inflight; |
19 | 19 | ||
@@ -58,10 +58,10 @@ struct unix_skb_parms { | |||
58 | #define UNIXCB(skb) (*(struct unix_skb_parms*)&((skb)->cb)) | 58 | #define UNIXCB(skb) (*(struct unix_skb_parms*)&((skb)->cb)) |
59 | #define UNIXCREDS(skb) (&UNIXCB((skb)).creds) | 59 | #define UNIXCREDS(skb) (&UNIXCB((skb)).creds) |
60 | 60 | ||
61 | #define unix_state_rlock(s) read_lock(&unix_sk(s)->lock) | 61 | #define unix_state_rlock(s) spin_lock(&unix_sk(s)->lock) |
62 | #define unix_state_runlock(s) read_unlock(&unix_sk(s)->lock) | 62 | #define unix_state_runlock(s) spin_unlock(&unix_sk(s)->lock) |
63 | #define unix_state_wlock(s) write_lock(&unix_sk(s)->lock) | 63 | #define unix_state_wlock(s) spin_lock(&unix_sk(s)->lock) |
64 | #define unix_state_wunlock(s) write_unlock(&unix_sk(s)->lock) | 64 | #define unix_state_wunlock(s) spin_unlock(&unix_sk(s)->lock) |
65 | 65 | ||
66 | #ifdef __KERNEL__ | 66 | #ifdef __KERNEL__ |
67 | /* The AF_UNIX socket */ | 67 | /* The AF_UNIX socket */ |
@@ -76,7 +76,7 @@ struct unix_sock { | |||
76 | struct sock *other; | 76 | struct sock *other; |
77 | struct sock *gc_tree; | 77 | struct sock *gc_tree; |
78 | atomic_t inflight; | 78 | atomic_t inflight; |
79 | rwlock_t lock; | 79 | spinlock_t lock; |
80 | wait_queue_head_t peer_wait; | 80 | wait_queue_head_t peer_wait; |
81 | }; | 81 | }; |
82 | #define unix_sk(__sk) ((struct unix_sock *)__sk) | 82 | #define unix_sk(__sk) ((struct unix_sock *)__sk) |
diff --git a/include/net/atmclip.h b/include/net/atmclip.h index 47048b1d179a..90fcc98e676f 100644 --- a/include/net/atmclip.h +++ b/include/net/atmclip.h | |||
@@ -7,7 +7,6 @@ | |||
7 | #define _ATMCLIP_H | 7 | #define _ATMCLIP_H |
8 | 8 | ||
9 | #include <linux/netdevice.h> | 9 | #include <linux/netdevice.h> |
10 | #include <linux/skbuff.h> | ||
11 | #include <linux/atm.h> | 10 | #include <linux/atm.h> |
12 | #include <linux/atmdev.h> | 11 | #include <linux/atmdev.h> |
13 | #include <linux/atmarp.h> | 12 | #include <linux/atmarp.h> |
@@ -18,6 +17,7 @@ | |||
18 | #define CLIP_VCC(vcc) ((struct clip_vcc *) ((vcc)->user_back)) | 17 | #define CLIP_VCC(vcc) ((struct clip_vcc *) ((vcc)->user_back)) |
19 | #define NEIGH2ENTRY(neigh) ((struct atmarp_entry *) (neigh)->primary_key) | 18 | #define NEIGH2ENTRY(neigh) ((struct atmarp_entry *) (neigh)->primary_key) |
20 | 19 | ||
20 | struct sk_buff; | ||
21 | 21 | ||
22 | struct clip_vcc { | 22 | struct clip_vcc { |
23 | struct atm_vcc *vcc; /* VCC descriptor */ | 23 | struct atm_vcc *vcc; /* VCC descriptor */ |
diff --git a/include/net/dst.h b/include/net/dst.h index 6c196a5baf24..bee8b84d329d 100644 --- a/include/net/dst.h +++ b/include/net/dst.h | |||
@@ -9,6 +9,7 @@ | |||
9 | #define _NET_DST_H | 9 | #define _NET_DST_H |
10 | 10 | ||
11 | #include <linux/config.h> | 11 | #include <linux/config.h> |
12 | #include <linux/netdevice.h> | ||
12 | #include <linux/rtnetlink.h> | 13 | #include <linux/rtnetlink.h> |
13 | #include <linux/rcupdate.h> | 14 | #include <linux/rcupdate.h> |
14 | #include <linux/jiffies.h> | 15 | #include <linux/jiffies.h> |
diff --git a/include/net/flow.h b/include/net/flow.h index 9a5c94b1a0ec..ec7eb86eb203 100644 --- a/include/net/flow.h +++ b/include/net/flow.h | |||
@@ -84,11 +84,12 @@ struct flowi { | |||
84 | #define FLOW_DIR_OUT 1 | 84 | #define FLOW_DIR_OUT 1 |
85 | #define FLOW_DIR_FWD 2 | 85 | #define FLOW_DIR_FWD 2 |
86 | 86 | ||
87 | typedef void (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir, | 87 | struct sock; |
88 | typedef void (*flow_resolve_t)(struct flowi *key, u32 sk_sid, u16 family, u8 dir, | ||
88 | void **objp, atomic_t **obj_refp); | 89 | void **objp, atomic_t **obj_refp); |
89 | 90 | ||
90 | extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, | 91 | extern void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir, |
91 | flow_resolve_t resolver); | 92 | flow_resolve_t resolver); |
92 | extern void flow_cache_flush(void); | 93 | extern void flow_cache_flush(void); |
93 | extern atomic_t flow_cache_genid; | 94 | extern atomic_t flow_cache_genid; |
94 | 95 | ||
diff --git a/include/net/genetlink.h b/include/net/genetlink.h index 52d8b1a73d52..c5b96b2b8155 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h | |||
@@ -60,7 +60,7 @@ struct genl_info | |||
60 | */ | 60 | */ |
61 | struct genl_ops | 61 | struct genl_ops |
62 | { | 62 | { |
63 | unsigned int cmd; | 63 | u8 cmd; |
64 | unsigned int flags; | 64 | unsigned int flags; |
65 | struct nla_policy *policy; | 65 | struct nla_policy *policy; |
66 | int (*doit)(struct sk_buff *skb, | 66 | int (*doit)(struct sk_buff *skb, |
diff --git a/include/net/icmp.h b/include/net/icmp.h index 6cdebeee5f96..e7c3f20fbafc 100644 --- a/include/net/icmp.h +++ b/include/net/icmp.h | |||
@@ -20,12 +20,9 @@ | |||
20 | 20 | ||
21 | #include <linux/config.h> | 21 | #include <linux/config.h> |
22 | #include <linux/icmp.h> | 22 | #include <linux/icmp.h> |
23 | #include <linux/skbuff.h> | ||
24 | 23 | ||
25 | #include <net/sock.h> | 24 | #include <net/inet_sock.h> |
26 | #include <net/protocol.h> | ||
27 | #include <net/snmp.h> | 25 | #include <net/snmp.h> |
28 | #include <linux/ip.h> | ||
29 | 26 | ||
30 | struct icmp_err { | 27 | struct icmp_err { |
31 | int errno; | 28 | int errno; |
@@ -38,6 +35,10 @@ DECLARE_SNMP_STAT(struct icmp_mib, icmp_statistics); | |||
38 | #define ICMP_INC_STATS_BH(field) SNMP_INC_STATS_BH(icmp_statistics, field) | 35 | #define ICMP_INC_STATS_BH(field) SNMP_INC_STATS_BH(icmp_statistics, field) |
39 | #define ICMP_INC_STATS_USER(field) SNMP_INC_STATS_USER(icmp_statistics, field) | 36 | #define ICMP_INC_STATS_USER(field) SNMP_INC_STATS_USER(icmp_statistics, field) |
40 | 37 | ||
38 | struct dst_entry; | ||
39 | struct net_proto_family; | ||
40 | struct sk_buff; | ||
41 | |||
41 | extern void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info); | 42 | extern void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info); |
42 | extern int icmp_rcv(struct sk_buff *skb); | 43 | extern int icmp_rcv(struct sk_buff *skb); |
43 | extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg); | 44 | extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg); |
diff --git a/include/net/ieee80211_crypt.h b/include/net/ieee80211_crypt.h index 225fc751d464..03b766afdc39 100644 --- a/include/net/ieee80211_crypt.h +++ b/include/net/ieee80211_crypt.h | |||
@@ -23,12 +23,17 @@ | |||
23 | #ifndef IEEE80211_CRYPT_H | 23 | #ifndef IEEE80211_CRYPT_H |
24 | #define IEEE80211_CRYPT_H | 24 | #define IEEE80211_CRYPT_H |
25 | 25 | ||
26 | #include <linux/skbuff.h> | 26 | #include <linux/types.h> |
27 | #include <linux/list.h> | ||
28 | #include <asm/atomic.h> | ||
27 | 29 | ||
28 | enum { | 30 | enum { |
29 | IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0), | 31 | IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0), |
30 | }; | 32 | }; |
31 | 33 | ||
34 | struct sk_buff; | ||
35 | struct module; | ||
36 | |||
32 | struct ieee80211_crypto_ops { | 37 | struct ieee80211_crypto_ops { |
33 | const char *name; | 38 | const char *name; |
34 | struct list_head list; | 39 | struct list_head list; |
@@ -87,6 +92,8 @@ struct ieee80211_crypt_data { | |||
87 | atomic_t refcnt; | 92 | atomic_t refcnt; |
88 | }; | 93 | }; |
89 | 94 | ||
95 | struct ieee80211_device; | ||
96 | |||
90 | int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops); | 97 | int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops); |
91 | int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops); | 98 | int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops); |
92 | struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name); | 99 | struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name); |
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index e97a9accb71d..eb8afe3499a9 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define IF_RA_MANAGED 0x40 | 24 | #define IF_RA_MANAGED 0x40 |
25 | #define IF_RA_RCVD 0x20 | 25 | #define IF_RA_RCVD 0x20 |
26 | #define IF_RS_SENT 0x10 | 26 | #define IF_RS_SENT 0x10 |
27 | #define IF_READY 0x80000000 | ||
27 | 28 | ||
28 | /* prefix flags */ | 29 | /* prefix flags */ |
29 | #define IF_PREFIX_ONLINK 0x01 | 30 | #define IF_PREFIX_ONLINK 0x01 |
@@ -82,6 +83,7 @@ struct ipv6_mc_socklist | |||
82 | struct in6_addr addr; | 83 | struct in6_addr addr; |
83 | int ifindex; | 84 | int ifindex; |
84 | struct ipv6_mc_socklist *next; | 85 | struct ipv6_mc_socklist *next; |
86 | rwlock_t sflock; | ||
85 | unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */ | 87 | unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */ |
86 | struct ip6_sf_socklist *sflist; | 88 | struct ip6_sf_socklist *sflist; |
87 | }; | 89 | }; |
diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h new file mode 100644 index 000000000000..b33b438bffcc --- /dev/null +++ b/include/net/inet6_connection_sock.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * NET Generic infrastructure for INET6 connection oriented protocols. | ||
3 | * | ||
4 | * Authors: Many people, see the TCPv6 sources | ||
5 | * | ||
6 | * From code originally in TCPv6 | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | */ | ||
13 | #ifndef _INET6_CONNECTION_SOCK_H | ||
14 | #define _INET6_CONNECTION_SOCK_H | ||
15 | |||
16 | #include <linux/types.h> | ||
17 | |||
18 | struct in6_addr; | ||
19 | struct inet_bind_bucket; | ||
20 | struct request_sock; | ||
21 | struct sk_buff; | ||
22 | struct sock; | ||
23 | struct sockaddr; | ||
24 | |||
25 | extern int inet6_csk_bind_conflict(const struct sock *sk, | ||
26 | const struct inet_bind_bucket *tb); | ||
27 | |||
28 | extern struct request_sock *inet6_csk_search_req(const struct sock *sk, | ||
29 | struct request_sock ***prevp, | ||
30 | const __u16 rport, | ||
31 | const struct in6_addr *raddr, | ||
32 | const struct in6_addr *laddr, | ||
33 | const int iif); | ||
34 | |||
35 | extern void inet6_csk_reqsk_queue_hash_add(struct sock *sk, | ||
36 | struct request_sock *req, | ||
37 | const unsigned long timeout); | ||
38 | |||
39 | extern void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr); | ||
40 | |||
41 | extern int inet6_csk_xmit(struct sk_buff *skb, int ipfragok); | ||
42 | #endif /* _INET6_CONNECTION_SOCK_H */ | ||
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h index 5a2beed5a770..25f708ff020e 100644 --- a/include/net/inet6_hashtables.h +++ b/include/net/inet6_hashtables.h | |||
@@ -48,6 +48,32 @@ static inline int inet6_sk_ehashfn(const struct sock *sk) | |||
48 | return inet6_ehashfn(laddr, lport, faddr, fport); | 48 | return inet6_ehashfn(laddr, lport, faddr, fport); |
49 | } | 49 | } |
50 | 50 | ||
51 | static inline void __inet6_hash(struct inet_hashinfo *hashinfo, | ||
52 | struct sock *sk) | ||
53 | { | ||
54 | struct hlist_head *list; | ||
55 | rwlock_t *lock; | ||
56 | |||
57 | BUG_TRAP(sk_unhashed(sk)); | ||
58 | |||
59 | if (sk->sk_state == TCP_LISTEN) { | ||
60 | list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; | ||
61 | lock = &hashinfo->lhash_lock; | ||
62 | inet_listen_wlock(hashinfo); | ||
63 | } else { | ||
64 | unsigned int hash; | ||
65 | sk->sk_hash = hash = inet6_sk_ehashfn(sk); | ||
66 | hash &= (hashinfo->ehash_size - 1); | ||
67 | list = &hashinfo->ehash[hash].chain; | ||
68 | lock = &hashinfo->ehash[hash].lock; | ||
69 | write_lock(lock); | ||
70 | } | ||
71 | |||
72 | __sk_add_node(sk, list); | ||
73 | sock_prot_inc_use(sk->sk_prot); | ||
74 | write_unlock(lock); | ||
75 | } | ||
76 | |||
51 | /* | 77 | /* |
52 | * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so | 78 | * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so |
53 | * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM | 79 | * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM |
@@ -84,10 +110,10 @@ static inline struct sock * | |||
84 | 110 | ||
85 | if(*((__u32 *)&(tw->tw_dport)) == ports && | 111 | if(*((__u32 *)&(tw->tw_dport)) == ports && |
86 | sk->sk_family == PF_INET6) { | 112 | sk->sk_family == PF_INET6) { |
87 | const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk); | 113 | const struct inet6_timewait_sock *tw6 = inet6_twsk(sk); |
88 | 114 | ||
89 | if (ipv6_addr_equal(&tcp6tw->tw_v6_daddr, saddr) && | 115 | if (ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) && |
90 | ipv6_addr_equal(&tcp6tw->tw_v6_rcv_saddr, daddr) && | 116 | ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) && |
91 | (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dif)) | 117 | (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dif)) |
92 | goto hit; | 118 | goto hit; |
93 | } | 119 | } |
diff --git a/include/net/inet_common.h b/include/net/inet_common.h index f943306ce5ff..227adcbdfec8 100644 --- a/include/net/inet_common.h +++ b/include/net/inet_common.h | |||
@@ -1,8 +1,8 @@ | |||
1 | #ifndef _INET_COMMON_H | 1 | #ifndef _INET_COMMON_H |
2 | #define _INET_COMMON_H | 2 | #define _INET_COMMON_H |
3 | 3 | ||
4 | extern struct proto_ops inet_stream_ops; | 4 | extern const struct proto_ops inet_stream_ops; |
5 | extern struct proto_ops inet_dgram_ops; | 5 | extern const struct proto_ops inet_dgram_ops; |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * INET4 prototypes used by INET6 | 8 | * INET4 prototypes used by INET6 |
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index b0c99060b78d..50234fa56a68 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h | |||
@@ -15,9 +15,11 @@ | |||
15 | #ifndef _INET_CONNECTION_SOCK_H | 15 | #ifndef _INET_CONNECTION_SOCK_H |
16 | #define _INET_CONNECTION_SOCK_H | 16 | #define _INET_CONNECTION_SOCK_H |
17 | 17 | ||
18 | #include <linux/ip.h> | 18 | #include <linux/compiler.h> |
19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
20 | #include <linux/timer.h> | 20 | #include <linux/timer.h> |
21 | |||
22 | #include <net/inet_sock.h> | ||
21 | #include <net/request_sock.h> | 23 | #include <net/request_sock.h> |
22 | 24 | ||
23 | #define INET_CSK_DEBUG 1 | 25 | #define INET_CSK_DEBUG 1 |
@@ -29,6 +31,29 @@ struct inet_bind_bucket; | |||
29 | struct inet_hashinfo; | 31 | struct inet_hashinfo; |
30 | struct tcp_congestion_ops; | 32 | struct tcp_congestion_ops; |
31 | 33 | ||
34 | /* | ||
35 | * Pointers to address related TCP functions | ||
36 | * (i.e. things that depend on the address family) | ||
37 | */ | ||
38 | struct inet_connection_sock_af_ops { | ||
39 | int (*queue_xmit)(struct sk_buff *skb, int ipfragok); | ||
40 | void (*send_check)(struct sock *sk, int len, | ||
41 | struct sk_buff *skb); | ||
42 | int (*rebuild_header)(struct sock *sk); | ||
43 | int (*conn_request)(struct sock *sk, struct sk_buff *skb); | ||
44 | struct sock *(*syn_recv_sock)(struct sock *sk, struct sk_buff *skb, | ||
45 | struct request_sock *req, | ||
46 | struct dst_entry *dst); | ||
47 | int (*remember_stamp)(struct sock *sk); | ||
48 | __u16 net_header_len; | ||
49 | int (*setsockopt)(struct sock *sk, int level, int optname, | ||
50 | char __user *optval, int optlen); | ||
51 | int (*getsockopt)(struct sock *sk, int level, int optname, | ||
52 | char __user *optval, int __user *optlen); | ||
53 | void (*addr2sockaddr)(struct sock *sk, struct sockaddr *); | ||
54 | int sockaddr_len; | ||
55 | }; | ||
56 | |||
32 | /** inet_connection_sock - INET connection oriented sock | 57 | /** inet_connection_sock - INET connection oriented sock |
33 | * | 58 | * |
34 | * @icsk_accept_queue: FIFO of established children | 59 | * @icsk_accept_queue: FIFO of established children |
@@ -36,13 +61,16 @@ struct tcp_congestion_ops; | |||
36 | * @icsk_timeout: Timeout | 61 | * @icsk_timeout: Timeout |
37 | * @icsk_retransmit_timer: Resend (no ack) | 62 | * @icsk_retransmit_timer: Resend (no ack) |
38 | * @icsk_rto: Retransmit timeout | 63 | * @icsk_rto: Retransmit timeout |
64 | * @icsk_pmtu_cookie Last pmtu seen by socket | ||
39 | * @icsk_ca_ops Pluggable congestion control hook | 65 | * @icsk_ca_ops Pluggable congestion control hook |
66 | * @icsk_af_ops Operations which are AF_INET{4,6} specific | ||
40 | * @icsk_ca_state: Congestion control state | 67 | * @icsk_ca_state: Congestion control state |
41 | * @icsk_retransmits: Number of unrecovered [RTO] timeouts | 68 | * @icsk_retransmits: Number of unrecovered [RTO] timeouts |
42 | * @icsk_pending: Scheduled timer event | 69 | * @icsk_pending: Scheduled timer event |
43 | * @icsk_backoff: Backoff | 70 | * @icsk_backoff: Backoff |
44 | * @icsk_syn_retries: Number of allowed SYN (or equivalent) retries | 71 | * @icsk_syn_retries: Number of allowed SYN (or equivalent) retries |
45 | * @icsk_probes_out: unanswered 0 window probes | 72 | * @icsk_probes_out: unanswered 0 window probes |
73 | * @icsk_ext_hdr_len: Network protocol overhead (IP/IPv6 options) | ||
46 | * @icsk_ack: Delayed ACK control data | 74 | * @icsk_ack: Delayed ACK control data |
47 | */ | 75 | */ |
48 | struct inet_connection_sock { | 76 | struct inet_connection_sock { |
@@ -54,14 +82,17 @@ struct inet_connection_sock { | |||
54 | struct timer_list icsk_retransmit_timer; | 82 | struct timer_list icsk_retransmit_timer; |
55 | struct timer_list icsk_delack_timer; | 83 | struct timer_list icsk_delack_timer; |
56 | __u32 icsk_rto; | 84 | __u32 icsk_rto; |
85 | __u32 icsk_pmtu_cookie; | ||
57 | struct tcp_congestion_ops *icsk_ca_ops; | 86 | struct tcp_congestion_ops *icsk_ca_ops; |
87 | struct inet_connection_sock_af_ops *icsk_af_ops; | ||
88 | unsigned int (*icsk_sync_mss)(struct sock *sk, u32 pmtu); | ||
58 | __u8 icsk_ca_state; | 89 | __u8 icsk_ca_state; |
59 | __u8 icsk_retransmits; | 90 | __u8 icsk_retransmits; |
60 | __u8 icsk_pending; | 91 | __u8 icsk_pending; |
61 | __u8 icsk_backoff; | 92 | __u8 icsk_backoff; |
62 | __u8 icsk_syn_retries; | 93 | __u8 icsk_syn_retries; |
63 | __u8 icsk_probes_out; | 94 | __u8 icsk_probes_out; |
64 | /* 2 BYTES HOLE, TRY TO PACK! */ | 95 | __u16 icsk_ext_hdr_len; |
65 | struct { | 96 | struct { |
66 | __u8 pending; /* ACK is pending */ | 97 | __u8 pending; /* ACK is pending */ |
67 | __u8 quick; /* Scheduled number of quick acks */ | 98 | __u8 quick; /* Scheduled number of quick acks */ |
@@ -192,8 +223,12 @@ extern struct request_sock *inet_csk_search_req(const struct sock *sk, | |||
192 | const __u16 rport, | 223 | const __u16 rport, |
193 | const __u32 raddr, | 224 | const __u32 raddr, |
194 | const __u32 laddr); | 225 | const __u32 laddr); |
226 | extern int inet_csk_bind_conflict(const struct sock *sk, | ||
227 | const struct inet_bind_bucket *tb); | ||
195 | extern int inet_csk_get_port(struct inet_hashinfo *hashinfo, | 228 | extern int inet_csk_get_port(struct inet_hashinfo *hashinfo, |
196 | struct sock *sk, unsigned short snum); | 229 | struct sock *sk, unsigned short snum, |
230 | int (*bind_conflict)(const struct sock *sk, | ||
231 | const struct inet_bind_bucket *tb)); | ||
197 | 232 | ||
198 | extern struct dst_entry* inet_csk_route_req(struct sock *sk, | 233 | extern struct dst_entry* inet_csk_route_req(struct sock *sk, |
199 | const struct request_sock *req); | 234 | const struct request_sock *req); |
@@ -207,7 +242,7 @@ static inline void inet_csk_reqsk_queue_add(struct sock *sk, | |||
207 | 242 | ||
208 | extern void inet_csk_reqsk_queue_hash_add(struct sock *sk, | 243 | extern void inet_csk_reqsk_queue_hash_add(struct sock *sk, |
209 | struct request_sock *req, | 244 | struct request_sock *req, |
210 | const unsigned timeout); | 245 | unsigned long timeout); |
211 | 246 | ||
212 | static inline void inet_csk_reqsk_queue_removed(struct sock *sk, | 247 | static inline void inet_csk_reqsk_queue_removed(struct sock *sk, |
213 | struct request_sock *req) | 248 | struct request_sock *req) |
@@ -273,4 +308,6 @@ static inline unsigned int inet_csk_listen_poll(const struct sock *sk) | |||
273 | extern int inet_csk_listen_start(struct sock *sk, const int nr_table_entries); | 308 | extern int inet_csk_listen_start(struct sock *sk, const int nr_table_entries); |
274 | extern void inet_csk_listen_stop(struct sock *sk); | 309 | extern void inet_csk_listen_stop(struct sock *sk); |
275 | 310 | ||
311 | extern void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr); | ||
312 | |||
276 | #endif /* _INET_CONNECTION_SOCK_H */ | 313 | #endif /* _INET_CONNECTION_SOCK_H */ |
diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h index b0c47e2eccf1..d599c6bfbb86 100644 --- a/include/net/inet_ecn.h +++ b/include/net/inet_ecn.h | |||
@@ -3,6 +3,8 @@ | |||
3 | 3 | ||
4 | #include <linux/ip.h> | 4 | #include <linux/ip.h> |
5 | #include <linux/skbuff.h> | 5 | #include <linux/skbuff.h> |
6 | |||
7 | #include <net/inet_sock.h> | ||
6 | #include <net/dsfield.h> | 8 | #include <net/dsfield.h> |
7 | 9 | ||
8 | enum { | 10 | enum { |
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 07840baa9341..135d80fd658e 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/wait.h> | 26 | #include <linux/wait.h> |
27 | 27 | ||
28 | #include <net/inet_connection_sock.h> | 28 | #include <net/inet_connection_sock.h> |
29 | #include <net/inet_sock.h> | ||
29 | #include <net/route.h> | 30 | #include <net/route.h> |
30 | #include <net/sock.h> | 31 | #include <net/sock.h> |
31 | #include <net/tcp_states.h> | 32 | #include <net/tcp_states.h> |
@@ -128,26 +129,6 @@ struct inet_hashinfo { | |||
128 | kmem_cache_t *bind_bucket_cachep; | 129 | kmem_cache_t *bind_bucket_cachep; |
129 | }; | 130 | }; |
130 | 131 | ||
131 | static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport, | ||
132 | const __u32 faddr, const __u16 fport) | ||
133 | { | ||
134 | unsigned int h = (laddr ^ lport) ^ (faddr ^ fport); | ||
135 | h ^= h >> 16; | ||
136 | h ^= h >> 8; | ||
137 | return h; | ||
138 | } | ||
139 | |||
140 | static inline int inet_sk_ehashfn(const struct sock *sk) | ||
141 | { | ||
142 | const struct inet_sock *inet = inet_sk(sk); | ||
143 | const __u32 laddr = inet->rcv_saddr; | ||
144 | const __u16 lport = inet->num; | ||
145 | const __u32 faddr = inet->daddr; | ||
146 | const __u16 fport = inet->dport; | ||
147 | |||
148 | return inet_ehashfn(laddr, lport, faddr, fport); | ||
149 | } | ||
150 | |||
151 | static inline struct inet_ehash_bucket *inet_ehash_bucket( | 132 | static inline struct inet_ehash_bucket *inet_ehash_bucket( |
152 | struct inet_hashinfo *hashinfo, | 133 | struct inet_hashinfo *hashinfo, |
153 | unsigned int hash) | 134 | unsigned int hash) |
@@ -434,4 +415,7 @@ static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo, | |||
434 | 415 | ||
435 | return sk; | 416 | return sk; |
436 | } | 417 | } |
418 | |||
419 | extern int inet_hash_connect(struct inet_timewait_death_row *death_row, | ||
420 | struct sock *sk); | ||
437 | #endif /* _INET_HASHTABLES_H */ | 421 | #endif /* _INET_HASHTABLES_H */ |
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h new file mode 100644 index 000000000000..883eb529ef8e --- /dev/null +++ b/include/net/inet_sock.h | |||
@@ -0,0 +1,193 @@ | |||
1 | /* | ||
2 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
3 | * operating system. INET is implemented using the BSD Socket | ||
4 | * interface as the means of communication with the user level. | ||
5 | * | ||
6 | * Definitions for inet_sock | ||
7 | * | ||
8 | * Authors: Many, reorganised here by | ||
9 | * Arnaldo Carvalho de Melo <acme@mandriva.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version | ||
14 | * 2 of the License, or (at your option) any later version. | ||
15 | */ | ||
16 | #ifndef _INET_SOCK_H | ||
17 | #define _INET_SOCK_H | ||
18 | |||
19 | #include <linux/config.h> | ||
20 | |||
21 | #include <linux/string.h> | ||
22 | #include <linux/types.h> | ||
23 | |||
24 | #include <net/flow.h> | ||
25 | #include <net/sock.h> | ||
26 | #include <net/request_sock.h> | ||
27 | |||
28 | /** struct ip_options - IP Options | ||
29 | * | ||
30 | * @faddr - Saved first hop address | ||
31 | * @is_setbyuser - Set by setsockopt? | ||
32 | * @is_data - Options in __data, rather than skb | ||
33 | * @is_strictroute - Strict source route | ||
34 | * @srr_is_hit - Packet destination addr was our one | ||
35 | * @is_changed - IP checksum more not valid | ||
36 | * @rr_needaddr - Need to record addr of outgoing dev | ||
37 | * @ts_needtime - Need to record timestamp | ||
38 | * @ts_needaddr - Need to record addr of outgoing dev | ||
39 | */ | ||
40 | struct ip_options { | ||
41 | __u32 faddr; | ||
42 | unsigned char optlen; | ||
43 | unsigned char srr; | ||
44 | unsigned char rr; | ||
45 | unsigned char ts; | ||
46 | unsigned char is_setbyuser:1, | ||
47 | is_data:1, | ||
48 | is_strictroute:1, | ||
49 | srr_is_hit:1, | ||
50 | is_changed:1, | ||
51 | rr_needaddr:1, | ||
52 | ts_needtime:1, | ||
53 | ts_needaddr:1; | ||
54 | unsigned char router_alert; | ||
55 | unsigned char __pad1; | ||
56 | unsigned char __pad2; | ||
57 | unsigned char __data[0]; | ||
58 | }; | ||
59 | |||
60 | #define optlength(opt) (sizeof(struct ip_options) + opt->optlen) | ||
61 | |||
62 | struct inet_request_sock { | ||
63 | struct request_sock req; | ||
64 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
65 | u16 inet6_rsk_offset; | ||
66 | /* 2 bytes hole, try to pack */ | ||
67 | #endif | ||
68 | u32 loc_addr; | ||
69 | u32 rmt_addr; | ||
70 | u16 rmt_port; | ||
71 | u16 snd_wscale : 4, | ||
72 | rcv_wscale : 4, | ||
73 | tstamp_ok : 1, | ||
74 | sack_ok : 1, | ||
75 | wscale_ok : 1, | ||
76 | ecn_ok : 1, | ||
77 | acked : 1; | ||
78 | struct ip_options *opt; | ||
79 | }; | ||
80 | |||
81 | static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk) | ||
82 | { | ||
83 | return (struct inet_request_sock *)sk; | ||
84 | } | ||
85 | |||
86 | struct ip_mc_socklist; | ||
87 | struct ipv6_pinfo; | ||
88 | struct rtable; | ||
89 | |||
90 | /** struct inet_sock - representation of INET sockets | ||
91 | * | ||
92 | * @sk - ancestor class | ||
93 | * @pinet6 - pointer to IPv6 control block | ||
94 | * @daddr - Foreign IPv4 addr | ||
95 | * @rcv_saddr - Bound local IPv4 addr | ||
96 | * @dport - Destination port | ||
97 | * @num - Local port | ||
98 | * @saddr - Sending source | ||
99 | * @uc_ttl - Unicast TTL | ||
100 | * @sport - Source port | ||
101 | * @id - ID counter for DF pkts | ||
102 | * @tos - TOS | ||
103 | * @mc_ttl - Multicasting TTL | ||
104 | * @is_icsk - is this an inet_connection_sock? | ||
105 | * @mc_index - Multicast device index | ||
106 | * @mc_list - Group array | ||
107 | * @cork - info to build ip hdr on each ip frag while socket is corked | ||
108 | */ | ||
109 | struct inet_sock { | ||
110 | /* sk and pinet6 has to be the first two members of inet_sock */ | ||
111 | struct sock sk; | ||
112 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
113 | struct ipv6_pinfo *pinet6; | ||
114 | #endif | ||
115 | /* Socket demultiplex comparisons on incoming packets. */ | ||
116 | __u32 daddr; | ||
117 | __u32 rcv_saddr; | ||
118 | __u16 dport; | ||
119 | __u16 num; | ||
120 | __u32 saddr; | ||
121 | __s16 uc_ttl; | ||
122 | __u16 cmsg_flags; | ||
123 | struct ip_options *opt; | ||
124 | __u16 sport; | ||
125 | __u16 id; | ||
126 | __u8 tos; | ||
127 | __u8 mc_ttl; | ||
128 | __u8 pmtudisc; | ||
129 | __u8 recverr:1, | ||
130 | is_icsk:1, | ||
131 | freebind:1, | ||
132 | hdrincl:1, | ||
133 | mc_loop:1; | ||
134 | int mc_index; | ||
135 | __u32 mc_addr; | ||
136 | struct ip_mc_socklist *mc_list; | ||
137 | struct { | ||
138 | unsigned int flags; | ||
139 | unsigned int fragsize; | ||
140 | struct ip_options *opt; | ||
141 | struct rtable *rt; | ||
142 | int length; /* Total length of all frames */ | ||
143 | u32 addr; | ||
144 | struct flowi fl; | ||
145 | } cork; | ||
146 | }; | ||
147 | |||
148 | #define IPCORK_OPT 1 /* ip-options has been held in ipcork.opt */ | ||
149 | #define IPCORK_ALLFRAG 2 /* always fragment (for ipv6 for now) */ | ||
150 | |||
151 | static inline struct inet_sock *inet_sk(const struct sock *sk) | ||
152 | { | ||
153 | return (struct inet_sock *)sk; | ||
154 | } | ||
155 | |||
156 | static inline void __inet_sk_copy_descendant(struct sock *sk_to, | ||
157 | const struct sock *sk_from, | ||
158 | const int ancestor_size) | ||
159 | { | ||
160 | memcpy(inet_sk(sk_to) + 1, inet_sk(sk_from) + 1, | ||
161 | sk_from->sk_prot->obj_size - ancestor_size); | ||
162 | } | ||
163 | #if !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)) | ||
164 | static inline void inet_sk_copy_descendant(struct sock *sk_to, | ||
165 | const struct sock *sk_from) | ||
166 | { | ||
167 | __inet_sk_copy_descendant(sk_to, sk_from, sizeof(struct inet_sock)); | ||
168 | } | ||
169 | #endif | ||
170 | |||
171 | extern int inet_sk_rebuild_header(struct sock *sk); | ||
172 | |||
173 | static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport, | ||
174 | const __u32 faddr, const __u16 fport) | ||
175 | { | ||
176 | unsigned int h = (laddr ^ lport) ^ (faddr ^ fport); | ||
177 | h ^= h >> 16; | ||
178 | h ^= h >> 8; | ||
179 | return h; | ||
180 | } | ||
181 | |||
182 | static inline int inet_sk_ehashfn(const struct sock *sk) | ||
183 | { | ||
184 | const struct inet_sock *inet = inet_sk(sk); | ||
185 | const __u32 laddr = inet->rcv_saddr; | ||
186 | const __u16 lport = inet->num; | ||
187 | const __u32 faddr = inet->daddr; | ||
188 | const __u16 fport = inet->dport; | ||
189 | |||
190 | return inet_ehashfn(laddr, lport, faddr, fport); | ||
191 | } | ||
192 | |||
193 | #endif /* _INET_SOCK_H */ | ||
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index 28f7b2103505..1da294c47522 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h | |||
@@ -17,15 +17,16 @@ | |||
17 | 17 | ||
18 | #include <linux/config.h> | 18 | #include <linux/config.h> |
19 | 19 | ||
20 | #include <linux/ip.h> | ||
21 | #include <linux/list.h> | 20 | #include <linux/list.h> |
22 | #include <linux/module.h> | 21 | #include <linux/module.h> |
23 | #include <linux/timer.h> | 22 | #include <linux/timer.h> |
24 | #include <linux/types.h> | 23 | #include <linux/types.h> |
25 | #include <linux/workqueue.h> | 24 | #include <linux/workqueue.h> |
26 | 25 | ||
26 | #include <net/inet_sock.h> | ||
27 | #include <net/sock.h> | 27 | #include <net/sock.h> |
28 | #include <net/tcp_states.h> | 28 | #include <net/tcp_states.h> |
29 | #include <net/timewait_sock.h> | ||
29 | 30 | ||
30 | #include <asm/atomic.h> | 31 | #include <asm/atomic.h> |
31 | 32 | ||
@@ -127,7 +128,8 @@ struct inet_timewait_sock { | |||
127 | __u16 tw_num; | 128 | __u16 tw_num; |
128 | /* And these are ours. */ | 129 | /* And these are ours. */ |
129 | __u8 tw_ipv6only:1; | 130 | __u8 tw_ipv6only:1; |
130 | /* 31 bits hole, try to pack */ | 131 | /* 15 bits hole, try to pack */ |
132 | __u16 tw_ipv6_offset; | ||
131 | int tw_timeout; | 133 | int tw_timeout; |
132 | unsigned long tw_ttd; | 134 | unsigned long tw_ttd; |
133 | struct inet_bind_bucket *tw_tb; | 135 | struct inet_bind_bucket *tw_tb; |
@@ -199,7 +201,7 @@ static inline void inet_twsk_put(struct inet_timewait_sock *tw) | |||
199 | printk(KERN_DEBUG "%s timewait_sock %p released\n", | 201 | printk(KERN_DEBUG "%s timewait_sock %p released\n", |
200 | tw->tw_prot->name, tw); | 202 | tw->tw_prot->name, tw); |
201 | #endif | 203 | #endif |
202 | kmem_cache_free(tw->tw_prot->twsk_slab, tw); | 204 | kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw); |
203 | module_put(owner); | 205 | module_put(owner); |
204 | } | 206 | } |
205 | } | 207 | } |
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index 7fda471002b6..0965515f40cf 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h | |||
@@ -25,6 +25,7 @@ struct inet_peer | |||
25 | __u32 v4daddr; /* peer's address */ | 25 | __u32 v4daddr; /* peer's address */ |
26 | __u16 avl_height; | 26 | __u16 avl_height; |
27 | __u16 ip_id_count; /* IP ID for the next packet */ | 27 | __u16 ip_id_count; /* IP ID for the next packet */ |
28 | atomic_t rid; /* Frag reception counter */ | ||
28 | __u32 tcp_ts; | 29 | __u32 tcp_ts; |
29 | unsigned long tcp_ts_stamp; | 30 | unsigned long tcp_ts_stamp; |
30 | }; | 31 | }; |
diff --git a/include/net/ip.h b/include/net/ip.h index e4563bbee6ea..f7e7fd728b67 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
@@ -24,14 +24,10 @@ | |||
24 | 24 | ||
25 | #include <linux/config.h> | 25 | #include <linux/config.h> |
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <linux/socket.h> | ||
28 | #include <linux/ip.h> | 27 | #include <linux/ip.h> |
29 | #include <linux/in.h> | 28 | #include <linux/in.h> |
30 | #include <linux/netdevice.h> | 29 | |
31 | #include <linux/inetdevice.h> | 30 | #include <net/inet_sock.h> |
32 | #include <linux/in_route.h> | ||
33 | #include <net/route.h> | ||
34 | #include <net/arp.h> | ||
35 | #include <net/snmp.h> | 31 | #include <net/snmp.h> |
36 | 32 | ||
37 | struct sock; | 33 | struct sock; |
@@ -45,6 +41,7 @@ struct inet_skb_parm | |||
45 | #define IPSKB_TRANSLATED 2 | 41 | #define IPSKB_TRANSLATED 2 |
46 | #define IPSKB_FORWARDED 4 | 42 | #define IPSKB_FORWARDED 4 |
47 | #define IPSKB_XFRM_TUNNEL_SIZE 8 | 43 | #define IPSKB_XFRM_TUNNEL_SIZE 8 |
44 | #define IPSKB_FRAG_COMPLETE 16 | ||
48 | }; | 45 | }; |
49 | 46 | ||
50 | struct ipcm_cookie | 47 | struct ipcm_cookie |
@@ -74,6 +71,13 @@ extern rwlock_t ip_ra_lock; | |||
74 | 71 | ||
75 | #define IP_FRAG_TIME (30 * HZ) /* fragment lifetime */ | 72 | #define IP_FRAG_TIME (30 * HZ) /* fragment lifetime */ |
76 | 73 | ||
74 | struct msghdr; | ||
75 | struct net_device; | ||
76 | struct packet_type; | ||
77 | struct rtable; | ||
78 | struct sk_buff; | ||
79 | struct sockaddr; | ||
80 | |||
77 | extern void ip_mc_dropsocket(struct sock *); | 81 | extern void ip_mc_dropsocket(struct sock *); |
78 | extern void ip_mc_dropdevice(struct net_device *dev); | 82 | extern void ip_mc_dropdevice(struct net_device *dev); |
79 | extern int igmp_mc_proc_init(void); | 83 | extern int igmp_mc_proc_init(void); |
@@ -168,6 +172,7 @@ extern int sysctl_ipfrag_high_thresh; | |||
168 | extern int sysctl_ipfrag_low_thresh; | 172 | extern int sysctl_ipfrag_low_thresh; |
169 | extern int sysctl_ipfrag_time; | 173 | extern int sysctl_ipfrag_time; |
170 | extern int sysctl_ipfrag_secret_interval; | 174 | extern int sysctl_ipfrag_secret_interval; |
175 | extern int sysctl_ipfrag_max_dist; | ||
171 | 176 | ||
172 | /* From inetpeer.c */ | 177 | /* From inetpeer.c */ |
173 | extern int inet_peer_threshold; | 178 | extern int inet_peer_threshold; |
@@ -182,6 +187,8 @@ extern int sysctl_ip_dynaddr; | |||
182 | extern void ipfrag_init(void); | 187 | extern void ipfrag_init(void); |
183 | 188 | ||
184 | #ifdef CONFIG_INET | 189 | #ifdef CONFIG_INET |
190 | #include <net/dst.h> | ||
191 | |||
185 | /* The function in 2.2 was invalid, producing wrong result for | 192 | /* The function in 2.2 was invalid, producing wrong result for |
186 | * check=0xFEFF. It was noticed by Arthur Skawina _year_ ago. --ANK(000625) */ | 193 | * check=0xFEFF. It was noticed by Arthur Skawina _year_ ago. --ANK(000625) */ |
187 | static inline | 194 | static inline |
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 14de4ebd1211..e000fa2cd5f6 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h | |||
@@ -238,6 +238,8 @@ extern int fib_validate_source(u32 src, u32 dst, u8 tos, int oif, | |||
238 | struct net_device *dev, u32 *spec_dst, u32 *itag); | 238 | struct net_device *dev, u32 *spec_dst, u32 *itag); |
239 | extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res); | 239 | extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res); |
240 | 240 | ||
241 | struct rtentry; | ||
242 | |||
241 | /* Exported by fib_semantics.c */ | 243 | /* Exported by fib_semantics.c */ |
242 | extern int ip_fib_check_default(u32 gw, struct net_device *dev); | 244 | extern int ip_fib_check_default(u32 gw, struct net_device *dev); |
243 | extern int fib_sync_down(u32 local, struct net_device *dev, int force); | 245 | extern int fib_sync_down(u32 local, struct net_device *dev, int force); |
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 3b5559a023a4..7d2674fde19a 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -251,16 +251,15 @@ struct ip_vs_daemon_user { | |||
251 | #include <linux/config.h> | 251 | #include <linux/config.h> |
252 | #include <linux/list.h> /* for struct list_head */ | 252 | #include <linux/list.h> /* for struct list_head */ |
253 | #include <linux/spinlock.h> /* for struct rwlock_t */ | 253 | #include <linux/spinlock.h> /* for struct rwlock_t */ |
254 | #include <linux/skbuff.h> /* for struct sk_buff */ | ||
255 | #include <linux/ip.h> /* for struct iphdr */ | ||
256 | #include <asm/atomic.h> /* for struct atomic_t */ | 254 | #include <asm/atomic.h> /* for struct atomic_t */ |
257 | #include <linux/netdevice.h> /* for struct neighbour */ | ||
258 | #include <net/dst.h> /* for struct dst_entry */ | ||
259 | #include <net/udp.h> | ||
260 | #include <linux/compiler.h> | 255 | #include <linux/compiler.h> |
256 | #include <linux/timer.h> | ||
261 | 257 | ||
258 | #include <net/checksum.h> | ||
262 | 259 | ||
263 | #ifdef CONFIG_IP_VS_DEBUG | 260 | #ifdef CONFIG_IP_VS_DEBUG |
261 | #include <linux/net.h> | ||
262 | |||
264 | extern int ip_vs_get_debug_level(void); | 263 | extern int ip_vs_get_debug_level(void); |
265 | #define IP_VS_DBG(level, msg...) \ | 264 | #define IP_VS_DBG(level, msg...) \ |
266 | do { \ | 265 | do { \ |
@@ -429,8 +428,11 @@ struct ip_vs_stats | |||
429 | spinlock_t lock; /* spin lock */ | 428 | spinlock_t lock; /* spin lock */ |
430 | }; | 429 | }; |
431 | 430 | ||
431 | struct dst_entry; | ||
432 | struct iphdr; | ||
432 | struct ip_vs_conn; | 433 | struct ip_vs_conn; |
433 | struct ip_vs_app; | 434 | struct ip_vs_app; |
435 | struct sk_buff; | ||
434 | 436 | ||
435 | struct ip_vs_protocol { | 437 | struct ip_vs_protocol { |
436 | struct ip_vs_protocol *next; | 438 | struct ip_vs_protocol *next; |
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 0a2ad51cff82..860bbac4c4ee 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
@@ -240,6 +240,8 @@ extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_t | |||
240 | struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space, | 240 | struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space, |
241 | struct ipv6_txoptions *opt); | 241 | struct ipv6_txoptions *opt); |
242 | 242 | ||
243 | extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb); | ||
244 | |||
243 | extern int ip6_frag_nqueues; | 245 | extern int ip6_frag_nqueues; |
244 | extern atomic_t ip6_frag_mem; | 246 | extern atomic_t ip6_frag_mem; |
245 | 247 | ||
@@ -525,6 +527,9 @@ extern int inet6_getname(struct socket *sock, struct sockaddr *uaddr, | |||
525 | extern int inet6_ioctl(struct socket *sock, unsigned int cmd, | 527 | extern int inet6_ioctl(struct socket *sock, unsigned int cmd, |
526 | unsigned long arg); | 528 | unsigned long arg); |
527 | 529 | ||
530 | extern int inet6_hash_connect(struct inet_timewait_death_row *death_row, | ||
531 | struct sock *sk); | ||
532 | |||
528 | /* | 533 | /* |
529 | * reassembly.c | 534 | * reassembly.c |
530 | */ | 535 | */ |
@@ -533,8 +538,11 @@ extern int sysctl_ip6frag_low_thresh; | |||
533 | extern int sysctl_ip6frag_time; | 538 | extern int sysctl_ip6frag_time; |
534 | extern int sysctl_ip6frag_secret_interval; | 539 | extern int sysctl_ip6frag_secret_interval; |
535 | 540 | ||
536 | extern struct proto_ops inet6_stream_ops; | 541 | extern const struct proto_ops inet6_stream_ops; |
537 | extern struct proto_ops inet6_dgram_ops; | 542 | extern const struct proto_ops inet6_dgram_ops; |
543 | |||
544 | struct group_source_req; | ||
545 | struct group_filter; | ||
538 | 546 | ||
539 | extern int ip6_mc_source(int add, int omode, struct sock *sk, | 547 | extern int ip6_mc_source(int add, int omode, struct sock *sk, |
540 | struct group_source_req *pgsr); | 548 | struct group_source_req *pgsr); |
diff --git a/include/net/ndisc.h b/include/net/ndisc.h index f85d6e4b7442..bbac87eeb422 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h | |||
@@ -35,11 +35,20 @@ enum { | |||
35 | 35 | ||
36 | #ifdef __KERNEL__ | 36 | #ifdef __KERNEL__ |
37 | 37 | ||
38 | #include <linux/skbuff.h> | 38 | #include <linux/config.h> |
39 | #include <linux/netdevice.h> | 39 | #include <linux/compiler.h> |
40 | #include <linux/icmpv6.h> | 40 | #include <linux/icmpv6.h> |
41 | #include <linux/in6.h> | ||
42 | #include <linux/types.h> | ||
43 | |||
41 | #include <net/neighbour.h> | 44 | #include <net/neighbour.h> |
42 | #include <asm/atomic.h> | 45 | |
46 | struct ctl_table; | ||
47 | struct file; | ||
48 | struct inet6_dev; | ||
49 | struct net_device; | ||
50 | struct net_proto_family; | ||
51 | struct sk_buff; | ||
43 | 52 | ||
44 | extern struct neigh_table nd_tbl; | 53 | extern struct neigh_table nd_tbl; |
45 | 54 | ||
@@ -108,7 +117,7 @@ extern int igmp6_event_report(struct sk_buff *skb); | |||
108 | extern void igmp6_cleanup(void); | 117 | extern void igmp6_cleanup(void); |
109 | 118 | ||
110 | #ifdef CONFIG_SYSCTL | 119 | #ifdef CONFIG_SYSCTL |
111 | extern int ndisc_ifinfo_sysctl_change(ctl_table *ctl, | 120 | extern int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, |
112 | int write, | 121 | int write, |
113 | struct file * filp, | 122 | struct file * filp, |
114 | void __user *buffer, | 123 | void __user *buffer, |
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 34c07731933d..6fa9ae190741 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h | |||
@@ -49,8 +49,8 @@ | |||
49 | #ifdef __KERNEL__ | 49 | #ifdef __KERNEL__ |
50 | 50 | ||
51 | #include <asm/atomic.h> | 51 | #include <asm/atomic.h> |
52 | #include <linux/skbuff.h> | ||
53 | #include <linux/netdevice.h> | 52 | #include <linux/netdevice.h> |
53 | #include <linux/skbuff.h> | ||
54 | #include <linux/rcupdate.h> | 54 | #include <linux/rcupdate.h> |
55 | #include <linux/seq_file.h> | 55 | #include <linux/seq_file.h> |
56 | 56 | ||
diff --git a/include/net/pkt_act.h b/include/net/pkt_act.h index bd08964b72c0..b225d8472b7e 100644 --- a/include/net/pkt_act.h +++ b/include/net/pkt_act.h | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/in.h> | 15 | #include <linux/in.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/netdevice.h> | ||
19 | #include <linux/skbuff.h> | 18 | #include <linux/skbuff.h> |
20 | #include <linux/rtnetlink.h> | 19 | #include <linux/rtnetlink.h> |
21 | #include <linux/module.h> | 20 | #include <linux/module.h> |
diff --git a/include/net/protocol.h b/include/net/protocol.h index 357691f6a45f..63f7db99c2a6 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h | |||
@@ -65,7 +65,7 @@ struct inet_protosw { | |||
65 | int protocol; /* This is the L4 protocol number. */ | 65 | int protocol; /* This is the L4 protocol number. */ |
66 | 66 | ||
67 | struct proto *prot; | 67 | struct proto *prot; |
68 | struct proto_ops *ops; | 68 | const struct proto_ops *ops; |
69 | 69 | ||
70 | int capability; /* Which (if any) capability do | 70 | int capability; /* Which (if any) capability do |
71 | * we need to use this socket | 71 | * we need to use this socket |
@@ -76,6 +76,7 @@ struct inet_protosw { | |||
76 | }; | 76 | }; |
77 | #define INET_PROTOSW_REUSE 0x01 /* Are ports automatically reusable? */ | 77 | #define INET_PROTOSW_REUSE 0x01 /* Are ports automatically reusable? */ |
78 | #define INET_PROTOSW_PERMANENT 0x02 /* Permanent protocols are unremovable. */ | 78 | #define INET_PROTOSW_PERMANENT 0x02 /* Permanent protocols are unremovable. */ |
79 | #define INET_PROTOSW_ICSK 0x04 /* Is this an inet_connection_sock? */ | ||
79 | 80 | ||
80 | extern struct net_protocol *inet_protocol_base; | 81 | extern struct net_protocol *inet_protocol_base; |
81 | extern struct net_protocol *inet_protos[MAX_INET_PROTOS]; | 82 | extern struct net_protocol *inet_protos[MAX_INET_PROTOS]; |
diff --git a/include/net/raw.h b/include/net/raw.h index f47917469b12..e67b28a0248c 100644 --- a/include/net/raw.h +++ b/include/net/raw.h | |||
@@ -19,6 +19,8 @@ | |||
19 | 19 | ||
20 | #include <linux/config.h> | 20 | #include <linux/config.h> |
21 | 21 | ||
22 | #include <net/protocol.h> | ||
23 | |||
22 | extern struct proto raw_prot; | 24 | extern struct proto raw_prot; |
23 | 25 | ||
24 | extern void raw_err(struct sock *, struct sk_buff *, u32 info); | 26 | extern void raw_err(struct sock *, struct sk_buff *, u32 info); |
diff --git a/include/net/request_sock.h b/include/net/request_sock.h index b52cc52ffe39..11641c9384f7 100644 --- a/include/net/request_sock.h +++ b/include/net/request_sock.h | |||
@@ -244,7 +244,7 @@ static inline int reqsk_queue_is_full(const struct request_sock_queue *queue) | |||
244 | 244 | ||
245 | static inline void reqsk_queue_hash_req(struct request_sock_queue *queue, | 245 | static inline void reqsk_queue_hash_req(struct request_sock_queue *queue, |
246 | u32 hash, struct request_sock *req, | 246 | u32 hash, struct request_sock *req, |
247 | unsigned timeout) | 247 | unsigned long timeout) |
248 | { | 248 | { |
249 | struct listen_sock *lopt = queue->listen_opt; | 249 | struct listen_sock *lopt = queue->listen_opt; |
250 | 250 | ||
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 8e7794ee27ff..f5c22d77feab 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -277,6 +277,24 @@ struct sctp_sock { | |||
277 | __u32 default_context; | 277 | __u32 default_context; |
278 | __u32 default_timetolive; | 278 | __u32 default_timetolive; |
279 | 279 | ||
280 | /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to | ||
281 | * the destination address every heartbeat interval. This value | ||
282 | * will be inherited by all new associations. | ||
283 | */ | ||
284 | __u32 hbinterval; | ||
285 | |||
286 | /* This is the max_retrans value for new associations. */ | ||
287 | __u16 pathmaxrxt; | ||
288 | |||
289 | /* The initial Path MTU to use for new associations. */ | ||
290 | __u32 pathmtu; | ||
291 | |||
292 | /* The default SACK delay timeout for new associations. */ | ||
293 | __u32 sackdelay; | ||
294 | |||
295 | /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ | ||
296 | __u32 param_flags; | ||
297 | |||
280 | struct sctp_initmsg initmsg; | 298 | struct sctp_initmsg initmsg; |
281 | struct sctp_rtoinfo rtoinfo; | 299 | struct sctp_rtoinfo rtoinfo; |
282 | struct sctp_paddrparams paddrparam; | 300 | struct sctp_paddrparams paddrparam; |
@@ -845,9 +863,6 @@ struct sctp_transport { | |||
845 | /* Data that has been sent, but not acknowledged. */ | 863 | /* Data that has been sent, but not acknowledged. */ |
846 | __u32 flight_size; | 864 | __u32 flight_size; |
847 | 865 | ||
848 | /* PMTU : The current known path MTU. */ | ||
849 | __u32 pmtu; | ||
850 | |||
851 | /* Destination */ | 866 | /* Destination */ |
852 | struct dst_entry *dst; | 867 | struct dst_entry *dst; |
853 | /* Source address. */ | 868 | /* Source address. */ |
@@ -862,7 +877,22 @@ struct sctp_transport { | |||
862 | /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to | 877 | /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to |
863 | * the destination address every heartbeat interval. | 878 | * the destination address every heartbeat interval. |
864 | */ | 879 | */ |
865 | int hb_interval; | 880 | __u32 hbinterval; |
881 | |||
882 | /* This is the max_retrans value for the transport and will | ||
883 | * be initialized from the assocs value. This can be changed | ||
884 | * using SCTP_SET_PEER_ADDR_PARAMS socket option. | ||
885 | */ | ||
886 | __u16 pathmaxrxt; | ||
887 | |||
888 | /* PMTU : The current known path MTU. */ | ||
889 | __u32 pathmtu; | ||
890 | |||
891 | /* SACK delay timeout */ | ||
892 | __u32 sackdelay; | ||
893 | |||
894 | /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ | ||
895 | __u32 param_flags; | ||
866 | 896 | ||
867 | /* When was the last time (in jiffies) that we heard from this | 897 | /* When was the last time (in jiffies) that we heard from this |
868 | * transport? We use this to pick new active and retran paths. | 898 | * transport? We use this to pick new active and retran paths. |
@@ -882,22 +912,11 @@ struct sctp_transport { | |||
882 | */ | 912 | */ |
883 | int state; | 913 | int state; |
884 | 914 | ||
885 | /* hb_allowed : The current heartbeat state of this destination, | ||
886 | * : i.e. ALLOW-HB, NO-HEARTBEAT, etc. | ||
887 | */ | ||
888 | int hb_allowed; | ||
889 | |||
890 | /* These are the error stats for this destination. */ | 915 | /* These are the error stats for this destination. */ |
891 | 916 | ||
892 | /* Error count : The current error count for this destination. */ | 917 | /* Error count : The current error count for this destination. */ |
893 | unsigned short error_count; | 918 | unsigned short error_count; |
894 | 919 | ||
895 | /* This is the max_retrans value for the transport and will | ||
896 | * be initialized to proto.max_retrans.path. This can be changed | ||
897 | * using SCTP_SET_PEER_ADDR_PARAMS socket option. | ||
898 | */ | ||
899 | int max_retrans; | ||
900 | |||
901 | /* Per : A timer used by each destination. | 920 | /* Per : A timer used by each destination. |
902 | * Destination : | 921 | * Destination : |
903 | * Timer : | 922 | * Timer : |
@@ -1502,6 +1521,28 @@ struct sctp_association { | |||
1502 | /* The largest timeout or RTO value to use in attempting an INIT */ | 1521 | /* The largest timeout or RTO value to use in attempting an INIT */ |
1503 | __u16 max_init_timeo; | 1522 | __u16 max_init_timeo; |
1504 | 1523 | ||
1524 | /* Heartbeat interval: The endpoint sends out a Heartbeat chunk to | ||
1525 | * the destination address every heartbeat interval. This value | ||
1526 | * will be inherited by all new transports. | ||
1527 | */ | ||
1528 | __u32 hbinterval; | ||
1529 | |||
1530 | /* This is the max_retrans value for new transports in the | ||
1531 | * association. | ||
1532 | */ | ||
1533 | __u16 pathmaxrxt; | ||
1534 | |||
1535 | /* Association : The smallest PMTU discovered for all of the | ||
1536 | * PMTU : peer's transport addresses. | ||
1537 | */ | ||
1538 | __u32 pathmtu; | ||
1539 | |||
1540 | /* SACK delay timeout */ | ||
1541 | __u32 sackdelay; | ||
1542 | |||
1543 | /* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */ | ||
1544 | __u32 param_flags; | ||
1545 | |||
1505 | int timeouts[SCTP_NUM_TIMEOUT_TYPES]; | 1546 | int timeouts[SCTP_NUM_TIMEOUT_TYPES]; |
1506 | struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES]; | 1547 | struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES]; |
1507 | 1548 | ||
@@ -1571,11 +1612,6 @@ struct sctp_association { | |||
1571 | */ | 1612 | */ |
1572 | wait_queue_head_t wait; | 1613 | wait_queue_head_t wait; |
1573 | 1614 | ||
1574 | /* Association : The smallest PMTU discovered for all of the | ||
1575 | * PMTU : peer's transport addresses. | ||
1576 | */ | ||
1577 | __u32 pmtu; | ||
1578 | |||
1579 | /* The message size at which SCTP fragmentation will occur. */ | 1615 | /* The message size at which SCTP fragmentation will occur. */ |
1580 | __u32 frag_point; | 1616 | __u32 frag_point; |
1581 | 1617 | ||
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h index f1c3bc54526a..8a6bef6f91eb 100644 --- a/include/net/sctp/user.h +++ b/include/net/sctp/user.h | |||
@@ -93,6 +93,8 @@ enum sctp_optname { | |||
93 | #define SCTP_STATUS SCTP_STATUS | 93 | #define SCTP_STATUS SCTP_STATUS |
94 | SCTP_GET_PEER_ADDR_INFO, | 94 | SCTP_GET_PEER_ADDR_INFO, |
95 | #define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO | 95 | #define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO |
96 | SCTP_DELAYED_ACK_TIME, | ||
97 | #define SCTP_DELAYED_ACK_TIME SCTP_DELAYED_ACK_TIME | ||
96 | 98 | ||
97 | /* Internal Socket Options. Some of the sctp library functions are | 99 | /* Internal Socket Options. Some of the sctp library functions are |
98 | * implemented using these socket options. | 100 | * implemented using these socket options. |
@@ -503,13 +505,41 @@ struct sctp_setadaption { | |||
503 | * unreachable. The following structure is used to access and modify an | 505 | * unreachable. The following structure is used to access and modify an |
504 | * address's parameters: | 506 | * address's parameters: |
505 | */ | 507 | */ |
508 | enum sctp_spp_flags { | ||
509 | SPP_HB_ENABLE = 1, /*Enable heartbeats*/ | ||
510 | SPP_HB_DISABLE = 2, /*Disable heartbeats*/ | ||
511 | SPP_HB = SPP_HB_ENABLE | SPP_HB_DISABLE, | ||
512 | SPP_HB_DEMAND = 4, /*Send heartbeat immediately*/ | ||
513 | SPP_PMTUD_ENABLE = 8, /*Enable PMTU discovery*/ | ||
514 | SPP_PMTUD_DISABLE = 16, /*Disable PMTU discovery*/ | ||
515 | SPP_PMTUD = SPP_PMTUD_ENABLE | SPP_PMTUD_DISABLE, | ||
516 | SPP_SACKDELAY_ENABLE = 32, /*Enable SACK*/ | ||
517 | SPP_SACKDELAY_DISABLE = 64, /*Disable SACK*/ | ||
518 | SPP_SACKDELAY = SPP_SACKDELAY_ENABLE | SPP_SACKDELAY_DISABLE, | ||
519 | }; | ||
520 | |||
506 | struct sctp_paddrparams { | 521 | struct sctp_paddrparams { |
507 | sctp_assoc_t spp_assoc_id; | 522 | sctp_assoc_t spp_assoc_id; |
508 | struct sockaddr_storage spp_address; | 523 | struct sockaddr_storage spp_address; |
509 | __u32 spp_hbinterval; | 524 | __u32 spp_hbinterval; |
510 | __u16 spp_pathmaxrxt; | 525 | __u16 spp_pathmaxrxt; |
526 | __u32 spp_pathmtu; | ||
527 | __u32 spp_sackdelay; | ||
528 | __u32 spp_flags; | ||
511 | } __attribute__((packed, aligned(4))); | 529 | } __attribute__((packed, aligned(4))); |
512 | 530 | ||
531 | /* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) | ||
532 | * | ||
533 | * This options will get or set the delayed ack timer. The time is set | ||
534 | * in milliseconds. If the assoc_id is 0, then this sets or gets the | ||
535 | * endpoints default delayed ack timer value. If the assoc_id field is | ||
536 | * non-zero, then the set or get effects the specified association. | ||
537 | */ | ||
538 | struct sctp_assoc_value { | ||
539 | sctp_assoc_t assoc_id; | ||
540 | uint32_t assoc_value; | ||
541 | }; | ||
542 | |||
513 | /* | 543 | /* |
514 | * 7.2.2 Peer Address Information | 544 | * 7.2.2 Peer Address Information |
515 | * | 545 | * |
diff --git a/include/net/sock.h b/include/net/sock.h index 982b4ecd187b..6961700ff3a0 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -493,6 +493,7 @@ extern void sk_stream_kill_queues(struct sock *sk); | |||
493 | extern int sk_wait_data(struct sock *sk, long *timeo); | 493 | extern int sk_wait_data(struct sock *sk, long *timeo); |
494 | 494 | ||
495 | struct request_sock_ops; | 495 | struct request_sock_ops; |
496 | struct timewait_sock_ops; | ||
496 | 497 | ||
497 | /* Networking protocol blocks we attach to sockets. | 498 | /* Networking protocol blocks we attach to sockets. |
498 | * socket layer -> transport layer interface | 499 | * socket layer -> transport layer interface |
@@ -557,11 +558,10 @@ struct proto { | |||
557 | kmem_cache_t *slab; | 558 | kmem_cache_t *slab; |
558 | unsigned int obj_size; | 559 | unsigned int obj_size; |
559 | 560 | ||
560 | kmem_cache_t *twsk_slab; | ||
561 | unsigned int twsk_obj_size; | ||
562 | atomic_t *orphan_count; | 561 | atomic_t *orphan_count; |
563 | 562 | ||
564 | struct request_sock_ops *rsk_prot; | 563 | struct request_sock_ops *rsk_prot; |
564 | struct timewait_sock_ops *twsk_prot; | ||
565 | 565 | ||
566 | struct module *owner; | 566 | struct module *owner; |
567 | 567 | ||
@@ -926,6 +926,29 @@ static inline void sock_put(struct sock *sk) | |||
926 | sk_free(sk); | 926 | sk_free(sk); |
927 | } | 927 | } |
928 | 928 | ||
929 | static inline int sk_receive_skb(struct sock *sk, struct sk_buff *skb) | ||
930 | { | ||
931 | int rc = NET_RX_SUCCESS; | ||
932 | |||
933 | if (sk_filter(sk, skb, 0)) | ||
934 | goto discard_and_relse; | ||
935 | |||
936 | skb->dev = NULL; | ||
937 | |||
938 | bh_lock_sock(sk); | ||
939 | if (!sock_owned_by_user(sk)) | ||
940 | rc = sk->sk_backlog_rcv(sk, skb); | ||
941 | else | ||
942 | sk_add_backlog(sk, skb); | ||
943 | bh_unlock_sock(sk); | ||
944 | out: | ||
945 | sock_put(sk); | ||
946 | return rc; | ||
947 | discard_and_relse: | ||
948 | kfree_skb(skb); | ||
949 | goto out; | ||
950 | } | ||
951 | |||
929 | /* Detach socket from process context. | 952 | /* Detach socket from process context. |
930 | * Announce socket dead, detach it from wait queue and inode. | 953 | * Announce socket dead, detach it from wait queue and inode. |
931 | * Note that parent inode held reference count on this struct sock, | 954 | * Note that parent inode held reference count on this struct sock, |
@@ -1166,7 +1189,10 @@ static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) | |||
1166 | 1189 | ||
1167 | static inline int sock_error(struct sock *sk) | 1190 | static inline int sock_error(struct sock *sk) |
1168 | { | 1191 | { |
1169 | int err = xchg(&sk->sk_err, 0); | 1192 | int err; |
1193 | if (likely(!sk->sk_err)) | ||
1194 | return 0; | ||
1195 | err = xchg(&sk->sk_err, 0); | ||
1170 | return -err; | 1196 | return -err; |
1171 | } | 1197 | } |
1172 | 1198 | ||
diff --git a/include/net/tcp.h b/include/net/tcp.h index d78025f9fbea..77f21c65bbca 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -225,53 +225,6 @@ extern atomic_t tcp_sockets_allocated; | |||
225 | extern int tcp_memory_pressure; | 225 | extern int tcp_memory_pressure; |
226 | 226 | ||
227 | /* | 227 | /* |
228 | * Pointers to address related TCP functions | ||
229 | * (i.e. things that depend on the address family) | ||
230 | */ | ||
231 | |||
232 | struct tcp_func { | ||
233 | int (*queue_xmit) (struct sk_buff *skb, | ||
234 | int ipfragok); | ||
235 | |||
236 | void (*send_check) (struct sock *sk, | ||
237 | struct tcphdr *th, | ||
238 | int len, | ||
239 | struct sk_buff *skb); | ||
240 | |||
241 | int (*rebuild_header) (struct sock *sk); | ||
242 | |||
243 | int (*conn_request) (struct sock *sk, | ||
244 | struct sk_buff *skb); | ||
245 | |||
246 | struct sock * (*syn_recv_sock) (struct sock *sk, | ||
247 | struct sk_buff *skb, | ||
248 | struct request_sock *req, | ||
249 | struct dst_entry *dst); | ||
250 | |||
251 | int (*remember_stamp) (struct sock *sk); | ||
252 | |||
253 | __u16 net_header_len; | ||
254 | |||
255 | int (*setsockopt) (struct sock *sk, | ||
256 | int level, | ||
257 | int optname, | ||
258 | char __user *optval, | ||
259 | int optlen); | ||
260 | |||
261 | int (*getsockopt) (struct sock *sk, | ||
262 | int level, | ||
263 | int optname, | ||
264 | char __user *optval, | ||
265 | int __user *optlen); | ||
266 | |||
267 | |||
268 | void (*addr2sockaddr) (struct sock *sk, | ||
269 | struct sockaddr *); | ||
270 | |||
271 | int sockaddr_len; | ||
272 | }; | ||
273 | |||
274 | /* | ||
275 | * The next routines deal with comparing 32 bit unsigned ints | 228 | * The next routines deal with comparing 32 bit unsigned ints |
276 | * and worry about wraparound (automatic with unsigned arithmetic). | 229 | * and worry about wraparound (automatic with unsigned arithmetic). |
277 | */ | 230 | */ |
@@ -334,6 +287,9 @@ extern int tcp_rcv_established(struct sock *sk, | |||
334 | 287 | ||
335 | extern void tcp_rcv_space_adjust(struct sock *sk); | 288 | extern void tcp_rcv_space_adjust(struct sock *sk); |
336 | 289 | ||
290 | extern int tcp_twsk_unique(struct sock *sk, | ||
291 | struct sock *sktw, void *twp); | ||
292 | |||
337 | static inline void tcp_dec_quickack_mode(struct sock *sk, | 293 | static inline void tcp_dec_quickack_mode(struct sock *sk, |
338 | const unsigned int pkts) | 294 | const unsigned int pkts) |
339 | { | 295 | { |
@@ -405,8 +361,7 @@ extern void tcp_parse_options(struct sk_buff *skb, | |||
405 | * TCP v4 functions exported for the inet6 API | 361 | * TCP v4 functions exported for the inet6 API |
406 | */ | 362 | */ |
407 | 363 | ||
408 | extern void tcp_v4_send_check(struct sock *sk, | 364 | extern void tcp_v4_send_check(struct sock *sk, int len, |
409 | struct tcphdr *th, int len, | ||
410 | struct sk_buff *skb); | 365 | struct sk_buff *skb); |
411 | 366 | ||
412 | extern int tcp_v4_conn_request(struct sock *sk, | 367 | extern int tcp_v4_conn_request(struct sock *sk, |
@@ -490,34 +445,16 @@ typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *, | |||
490 | extern int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, | 445 | extern int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, |
491 | sk_read_actor_t recv_actor); | 446 | sk_read_actor_t recv_actor); |
492 | 447 | ||
493 | /* Initialize RCV_MSS value. | 448 | extern void tcp_initialize_rcv_mss(struct sock *sk); |
494 | * RCV_MSS is an our guess about MSS used by the peer. | ||
495 | * We haven't any direct information about the MSS. | ||
496 | * It's better to underestimate the RCV_MSS rather than overestimate. | ||
497 | * Overestimations make us ACKing less frequently than needed. | ||
498 | * Underestimations are more easy to detect and fix by tcp_measure_rcv_mss(). | ||
499 | */ | ||
500 | 449 | ||
501 | static inline void tcp_initialize_rcv_mss(struct sock *sk) | 450 | static inline void __tcp_fast_path_on(struct tcp_sock *tp, u32 snd_wnd) |
502 | { | ||
503 | struct tcp_sock *tp = tcp_sk(sk); | ||
504 | unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache); | ||
505 | |||
506 | hint = min(hint, tp->rcv_wnd/2); | ||
507 | hint = min(hint, TCP_MIN_RCVMSS); | ||
508 | hint = max(hint, TCP_MIN_MSS); | ||
509 | |||
510 | inet_csk(sk)->icsk_ack.rcv_mss = hint; | ||
511 | } | ||
512 | |||
513 | static __inline__ void __tcp_fast_path_on(struct tcp_sock *tp, u32 snd_wnd) | ||
514 | { | 451 | { |
515 | tp->pred_flags = htonl((tp->tcp_header_len << 26) | | 452 | tp->pred_flags = htonl((tp->tcp_header_len << 26) | |
516 | ntohl(TCP_FLAG_ACK) | | 453 | ntohl(TCP_FLAG_ACK) | |
517 | snd_wnd); | 454 | snd_wnd); |
518 | } | 455 | } |
519 | 456 | ||
520 | static __inline__ void tcp_fast_path_on(struct tcp_sock *tp) | 457 | static inline void tcp_fast_path_on(struct tcp_sock *tp) |
521 | { | 458 | { |
522 | __tcp_fast_path_on(tp, tp->snd_wnd >> tp->rx_opt.snd_wscale); | 459 | __tcp_fast_path_on(tp, tp->snd_wnd >> tp->rx_opt.snd_wscale); |
523 | } | 460 | } |
@@ -535,7 +472,7 @@ static inline void tcp_fast_path_check(struct sock *sk, struct tcp_sock *tp) | |||
535 | * Rcv_nxt can be after the window if our peer push more data | 472 | * Rcv_nxt can be after the window if our peer push more data |
536 | * than the offered window. | 473 | * than the offered window. |
537 | */ | 474 | */ |
538 | static __inline__ u32 tcp_receive_window(const struct tcp_sock *tp) | 475 | static inline u32 tcp_receive_window(const struct tcp_sock *tp) |
539 | { | 476 | { |
540 | s32 win = tp->rcv_wup + tp->rcv_wnd - tp->rcv_nxt; | 477 | s32 win = tp->rcv_wup + tp->rcv_wnd - tp->rcv_nxt; |
541 | 478 | ||
@@ -707,6 +644,7 @@ extern void tcp_cleanup_congestion_control(struct sock *sk); | |||
707 | extern int tcp_set_default_congestion_control(const char *name); | 644 | extern int tcp_set_default_congestion_control(const char *name); |
708 | extern void tcp_get_default_congestion_control(char *name); | 645 | extern void tcp_get_default_congestion_control(char *name); |
709 | extern int tcp_set_congestion_control(struct sock *sk, const char *name); | 646 | extern int tcp_set_congestion_control(struct sock *sk, const char *name); |
647 | extern void tcp_slow_start(struct tcp_sock *tp); | ||
710 | 648 | ||
711 | extern struct tcp_congestion_ops tcp_init_congestion_ops; | 649 | extern struct tcp_congestion_ops tcp_init_congestion_ops; |
712 | extern u32 tcp_reno_ssthresh(struct sock *sk); | 650 | extern u32 tcp_reno_ssthresh(struct sock *sk); |
@@ -746,7 +684,7 @@ static inline void tcp_ca_event(struct sock *sk, const enum tcp_ca_event event) | |||
746 | * "Packets left network, but not honestly ACKed yet" PLUS | 684 | * "Packets left network, but not honestly ACKed yet" PLUS |
747 | * "Packets fast retransmitted" | 685 | * "Packets fast retransmitted" |
748 | */ | 686 | */ |
749 | static __inline__ unsigned int tcp_packets_in_flight(const struct tcp_sock *tp) | 687 | static inline unsigned int tcp_packets_in_flight(const struct tcp_sock *tp) |
750 | { | 688 | { |
751 | return (tp->packets_out - tp->left_out + tp->retrans_out); | 689 | return (tp->packets_out - tp->left_out + tp->retrans_out); |
752 | } | 690 | } |
@@ -766,33 +704,6 @@ static inline __u32 tcp_current_ssthresh(const struct sock *sk) | |||
766 | (tp->snd_cwnd >> 2))); | 704 | (tp->snd_cwnd >> 2))); |
767 | } | 705 | } |
768 | 706 | ||
769 | /* | ||
770 | * Linear increase during slow start | ||
771 | */ | ||
772 | static inline void tcp_slow_start(struct tcp_sock *tp) | ||
773 | { | ||
774 | if (sysctl_tcp_abc) { | ||
775 | /* RFC3465: Slow Start | ||
776 | * TCP sender SHOULD increase cwnd by the number of | ||
777 | * previously unacknowledged bytes ACKed by each incoming | ||
778 | * acknowledgment, provided the increase is not more than L | ||
779 | */ | ||
780 | if (tp->bytes_acked < tp->mss_cache) | ||
781 | return; | ||
782 | |||
783 | /* We MAY increase by 2 if discovered delayed ack */ | ||
784 | if (sysctl_tcp_abc > 1 && tp->bytes_acked > 2*tp->mss_cache) { | ||
785 | if (tp->snd_cwnd < tp->snd_cwnd_clamp) | ||
786 | tp->snd_cwnd++; | ||
787 | } | ||
788 | } | ||
789 | tp->bytes_acked = 0; | ||
790 | |||
791 | if (tp->snd_cwnd < tp->snd_cwnd_clamp) | ||
792 | tp->snd_cwnd++; | ||
793 | } | ||
794 | |||
795 | |||
796 | static inline void tcp_sync_left_out(struct tcp_sock *tp) | 707 | static inline void tcp_sync_left_out(struct tcp_sock *tp) |
797 | { | 708 | { |
798 | if (tp->rx_opt.sack_ok && | 709 | if (tp->rx_opt.sack_ok && |
@@ -801,34 +712,7 @@ static inline void tcp_sync_left_out(struct tcp_sock *tp) | |||
801 | tp->left_out = tp->sacked_out + tp->lost_out; | 712 | tp->left_out = tp->sacked_out + tp->lost_out; |
802 | } | 713 | } |
803 | 714 | ||
804 | /* Set slow start threshold and cwnd not falling to slow start */ | 715 | extern void tcp_enter_cwr(struct sock *sk); |
805 | static inline void __tcp_enter_cwr(struct sock *sk) | ||
806 | { | ||
807 | const struct inet_connection_sock *icsk = inet_csk(sk); | ||
808 | struct tcp_sock *tp = tcp_sk(sk); | ||
809 | |||
810 | tp->undo_marker = 0; | ||
811 | tp->snd_ssthresh = icsk->icsk_ca_ops->ssthresh(sk); | ||
812 | tp->snd_cwnd = min(tp->snd_cwnd, | ||
813 | tcp_packets_in_flight(tp) + 1U); | ||
814 | tp->snd_cwnd_cnt = 0; | ||
815 | tp->high_seq = tp->snd_nxt; | ||
816 | tp->snd_cwnd_stamp = tcp_time_stamp; | ||
817 | TCP_ECN_queue_cwr(tp); | ||
818 | } | ||
819 | |||
820 | static inline void tcp_enter_cwr(struct sock *sk) | ||
821 | { | ||
822 | struct tcp_sock *tp = tcp_sk(sk); | ||
823 | |||
824 | tp->prior_ssthresh = 0; | ||
825 | tp->bytes_acked = 0; | ||
826 | if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) { | ||
827 | __tcp_enter_cwr(sk); | ||
828 | tcp_set_ca_state(sk, TCP_CA_CWR); | ||
829 | } | ||
830 | } | ||
831 | |||
832 | extern __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst); | 716 | extern __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst); |
833 | 717 | ||
834 | /* Slow start with delack produces 3 packets of burst, so that | 718 | /* Slow start with delack produces 3 packets of burst, so that |
@@ -860,14 +744,14 @@ static inline int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight) | |||
860 | return left <= tcp_max_burst(tp); | 744 | return left <= tcp_max_burst(tp); |
861 | } | 745 | } |
862 | 746 | ||
863 | static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss, | 747 | static inline void tcp_minshall_update(struct tcp_sock *tp, int mss, |
864 | const struct sk_buff *skb) | 748 | const struct sk_buff *skb) |
865 | { | 749 | { |
866 | if (skb->len < mss) | 750 | if (skb->len < mss) |
867 | tp->snd_sml = TCP_SKB_CB(skb)->end_seq; | 751 | tp->snd_sml = TCP_SKB_CB(skb)->end_seq; |
868 | } | 752 | } |
869 | 753 | ||
870 | static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp) | 754 | static inline void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp) |
871 | { | 755 | { |
872 | const struct inet_connection_sock *icsk = inet_csk(sk); | 756 | const struct inet_connection_sock *icsk = inet_csk(sk); |
873 | if (!tp->packets_out && !icsk->icsk_pending) | 757 | if (!tp->packets_out && !icsk->icsk_pending) |
@@ -875,18 +759,18 @@ static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *t | |||
875 | icsk->icsk_rto, TCP_RTO_MAX); | 759 | icsk->icsk_rto, TCP_RTO_MAX); |
876 | } | 760 | } |
877 | 761 | ||
878 | static __inline__ void tcp_push_pending_frames(struct sock *sk, | 762 | static inline void tcp_push_pending_frames(struct sock *sk, |
879 | struct tcp_sock *tp) | 763 | struct tcp_sock *tp) |
880 | { | 764 | { |
881 | __tcp_push_pending_frames(sk, tp, tcp_current_mss(sk, 1), tp->nonagle); | 765 | __tcp_push_pending_frames(sk, tp, tcp_current_mss(sk, 1), tp->nonagle); |
882 | } | 766 | } |
883 | 767 | ||
884 | static __inline__ void tcp_init_wl(struct tcp_sock *tp, u32 ack, u32 seq) | 768 | static inline void tcp_init_wl(struct tcp_sock *tp, u32 ack, u32 seq) |
885 | { | 769 | { |
886 | tp->snd_wl1 = seq; | 770 | tp->snd_wl1 = seq; |
887 | } | 771 | } |
888 | 772 | ||
889 | static __inline__ void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq) | 773 | static inline void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq) |
890 | { | 774 | { |
891 | tp->snd_wl1 = seq; | 775 | tp->snd_wl1 = seq; |
892 | } | 776 | } |
@@ -894,19 +778,19 @@ static __inline__ void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq) | |||
894 | /* | 778 | /* |
895 | * Calculate(/check) TCP checksum | 779 | * Calculate(/check) TCP checksum |
896 | */ | 780 | */ |
897 | static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len, | 781 | static inline u16 tcp_v4_check(struct tcphdr *th, int len, |
898 | unsigned long saddr, unsigned long daddr, | 782 | unsigned long saddr, unsigned long daddr, |
899 | unsigned long base) | 783 | unsigned long base) |
900 | { | 784 | { |
901 | return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base); | 785 | return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base); |
902 | } | 786 | } |
903 | 787 | ||
904 | static __inline__ int __tcp_checksum_complete(struct sk_buff *skb) | 788 | static inline int __tcp_checksum_complete(struct sk_buff *skb) |
905 | { | 789 | { |
906 | return __skb_checksum_complete(skb); | 790 | return __skb_checksum_complete(skb); |
907 | } | 791 | } |
908 | 792 | ||
909 | static __inline__ int tcp_checksum_complete(struct sk_buff *skb) | 793 | static inline int tcp_checksum_complete(struct sk_buff *skb) |
910 | { | 794 | { |
911 | return skb->ip_summed != CHECKSUM_UNNECESSARY && | 795 | return skb->ip_summed != CHECKSUM_UNNECESSARY && |
912 | __tcp_checksum_complete(skb); | 796 | __tcp_checksum_complete(skb); |
@@ -914,7 +798,7 @@ static __inline__ int tcp_checksum_complete(struct sk_buff *skb) | |||
914 | 798 | ||
915 | /* Prequeue for VJ style copy to user, combined with checksumming. */ | 799 | /* Prequeue for VJ style copy to user, combined with checksumming. */ |
916 | 800 | ||
917 | static __inline__ void tcp_prequeue_init(struct tcp_sock *tp) | 801 | static inline void tcp_prequeue_init(struct tcp_sock *tp) |
918 | { | 802 | { |
919 | tp->ucopy.task = NULL; | 803 | tp->ucopy.task = NULL; |
920 | tp->ucopy.len = 0; | 804 | tp->ucopy.len = 0; |
@@ -930,7 +814,7 @@ static __inline__ void tcp_prequeue_init(struct tcp_sock *tp) | |||
930 | * | 814 | * |
931 | * NOTE: is this not too big to inline? | 815 | * NOTE: is this not too big to inline? |
932 | */ | 816 | */ |
933 | static __inline__ int tcp_prequeue(struct sock *sk, struct sk_buff *skb) | 817 | static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb) |
934 | { | 818 | { |
935 | struct tcp_sock *tp = tcp_sk(sk); | 819 | struct tcp_sock *tp = tcp_sk(sk); |
936 | 820 | ||
@@ -971,7 +855,7 @@ static const char *statename[]={ | |||
971 | }; | 855 | }; |
972 | #endif | 856 | #endif |
973 | 857 | ||
974 | static __inline__ void tcp_set_state(struct sock *sk, int state) | 858 | static inline void tcp_set_state(struct sock *sk, int state) |
975 | { | 859 | { |
976 | int oldstate = sk->sk_state; | 860 | int oldstate = sk->sk_state; |
977 | 861 | ||
@@ -1005,7 +889,7 @@ static __inline__ void tcp_set_state(struct sock *sk, int state) | |||
1005 | #endif | 889 | #endif |
1006 | } | 890 | } |
1007 | 891 | ||
1008 | static __inline__ void tcp_done(struct sock *sk) | 892 | static inline void tcp_done(struct sock *sk) |
1009 | { | 893 | { |
1010 | tcp_set_state(sk, TCP_CLOSE); | 894 | tcp_set_state(sk, TCP_CLOSE); |
1011 | tcp_clear_xmit_timers(sk); | 895 | tcp_clear_xmit_timers(sk); |
@@ -1018,81 +902,13 @@ static __inline__ void tcp_done(struct sock *sk) | |||
1018 | inet_csk_destroy_sock(sk); | 902 | inet_csk_destroy_sock(sk); |
1019 | } | 903 | } |
1020 | 904 | ||
1021 | static __inline__ void tcp_sack_reset(struct tcp_options_received *rx_opt) | 905 | static inline void tcp_sack_reset(struct tcp_options_received *rx_opt) |
1022 | { | 906 | { |
1023 | rx_opt->dsack = 0; | 907 | rx_opt->dsack = 0; |
1024 | rx_opt->eff_sacks = 0; | 908 | rx_opt->eff_sacks = 0; |
1025 | rx_opt->num_sacks = 0; | 909 | rx_opt->num_sacks = 0; |
1026 | } | 910 | } |
1027 | 911 | ||
1028 | static __inline__ void tcp_build_and_update_options(__u32 *ptr, struct tcp_sock *tp, __u32 tstamp) | ||
1029 | { | ||
1030 | if (tp->rx_opt.tstamp_ok) { | ||
1031 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | | ||
1032 | (TCPOPT_NOP << 16) | | ||
1033 | (TCPOPT_TIMESTAMP << 8) | | ||
1034 | TCPOLEN_TIMESTAMP); | ||
1035 | *ptr++ = htonl(tstamp); | ||
1036 | *ptr++ = htonl(tp->rx_opt.ts_recent); | ||
1037 | } | ||
1038 | if (tp->rx_opt.eff_sacks) { | ||
1039 | struct tcp_sack_block *sp = tp->rx_opt.dsack ? tp->duplicate_sack : tp->selective_acks; | ||
1040 | int this_sack; | ||
1041 | |||
1042 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | | ||
1043 | (TCPOPT_NOP << 16) | | ||
1044 | (TCPOPT_SACK << 8) | | ||
1045 | (TCPOLEN_SACK_BASE + | ||
1046 | (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK))); | ||
1047 | for(this_sack = 0; this_sack < tp->rx_opt.eff_sacks; this_sack++) { | ||
1048 | *ptr++ = htonl(sp[this_sack].start_seq); | ||
1049 | *ptr++ = htonl(sp[this_sack].end_seq); | ||
1050 | } | ||
1051 | if (tp->rx_opt.dsack) { | ||
1052 | tp->rx_opt.dsack = 0; | ||
1053 | tp->rx_opt.eff_sacks--; | ||
1054 | } | ||
1055 | } | ||
1056 | } | ||
1057 | |||
1058 | /* Construct a tcp options header for a SYN or SYN_ACK packet. | ||
1059 | * If this is every changed make sure to change the definition of | ||
1060 | * MAX_SYN_SIZE to match the new maximum number of options that you | ||
1061 | * can generate. | ||
1062 | */ | ||
1063 | static inline void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack, | ||
1064 | int offer_wscale, int wscale, __u32 tstamp, __u32 ts_recent) | ||
1065 | { | ||
1066 | /* We always get an MSS option. | ||
1067 | * The option bytes which will be seen in normal data | ||
1068 | * packets should timestamps be used, must be in the MSS | ||
1069 | * advertised. But we subtract them from tp->mss_cache so | ||
1070 | * that calculations in tcp_sendmsg are simpler etc. | ||
1071 | * So account for this fact here if necessary. If we | ||
1072 | * don't do this correctly, as a receiver we won't | ||
1073 | * recognize data packets as being full sized when we | ||
1074 | * should, and thus we won't abide by the delayed ACK | ||
1075 | * rules correctly. | ||
1076 | * SACKs don't matter, we never delay an ACK when we | ||
1077 | * have any of those going out. | ||
1078 | */ | ||
1079 | *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss); | ||
1080 | if (ts) { | ||
1081 | if(sack) | ||
1082 | *ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) | | ||
1083 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); | ||
1084 | else | ||
1085 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | | ||
1086 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); | ||
1087 | *ptr++ = htonl(tstamp); /* TSVAL */ | ||
1088 | *ptr++ = htonl(ts_recent); /* TSECR */ | ||
1089 | } else if(sack) | ||
1090 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | | ||
1091 | (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM); | ||
1092 | if (offer_wscale) | ||
1093 | *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale)); | ||
1094 | } | ||
1095 | |||
1096 | /* Determine a window scaling and initial window to offer. */ | 912 | /* Determine a window scaling and initial window to offer. */ |
1097 | extern void tcp_select_initial_window(int __space, __u32 mss, | 913 | extern void tcp_select_initial_window(int __space, __u32 mss, |
1098 | __u32 *rcv_wnd, __u32 *window_clamp, | 914 | __u32 *rcv_wnd, __u32 *window_clamp, |
@@ -1117,9 +933,9 @@ static inline int tcp_full_space(const struct sock *sk) | |||
1117 | return tcp_win_from_space(sk->sk_rcvbuf); | 933 | return tcp_win_from_space(sk->sk_rcvbuf); |
1118 | } | 934 | } |
1119 | 935 | ||
1120 | static __inline__ void tcp_openreq_init(struct request_sock *req, | 936 | static inline void tcp_openreq_init(struct request_sock *req, |
1121 | struct tcp_options_received *rx_opt, | 937 | struct tcp_options_received *rx_opt, |
1122 | struct sk_buff *skb) | 938 | struct sk_buff *skb) |
1123 | { | 939 | { |
1124 | struct inet_request_sock *ireq = inet_rsk(req); | 940 | struct inet_request_sock *ireq = inet_rsk(req); |
1125 | 941 | ||
diff --git a/include/net/tcp_states.h b/include/net/tcp_states.h index b9d4176b2d15..b0b645988bd8 100644 --- a/include/net/tcp_states.h +++ b/include/net/tcp_states.h | |||
@@ -31,4 +31,20 @@ enum { | |||
31 | 31 | ||
32 | #define TCP_STATE_MASK 0xF | 32 | #define TCP_STATE_MASK 0xF |
33 | 33 | ||
34 | #define TCP_ACTION_FIN (1 << 7) | ||
35 | |||
36 | enum { | ||
37 | TCPF_ESTABLISHED = (1 << 1), | ||
38 | TCPF_SYN_SENT = (1 << 2), | ||
39 | TCPF_SYN_RECV = (1 << 3), | ||
40 | TCPF_FIN_WAIT1 = (1 << 4), | ||
41 | TCPF_FIN_WAIT2 = (1 << 5), | ||
42 | TCPF_TIME_WAIT = (1 << 6), | ||
43 | TCPF_CLOSE = (1 << 7), | ||
44 | TCPF_CLOSE_WAIT = (1 << 8), | ||
45 | TCPF_LAST_ACK = (1 << 9), | ||
46 | TCPF_LISTEN = (1 << 10), | ||
47 | TCPF_CLOSING = (1 << 11) | ||
48 | }; | ||
49 | |||
34 | #endif /* _LINUX_TCP_STATES_H */ | 50 | #endif /* _LINUX_TCP_STATES_H */ |
diff --git a/include/net/timewait_sock.h b/include/net/timewait_sock.h new file mode 100644 index 000000000000..2544281e1d5e --- /dev/null +++ b/include/net/timewait_sock.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * NET Generic infrastructure for Network protocols. | ||
3 | * | ||
4 | * Authors: Arnaldo Carvalho de Melo <acme@conectiva.com.br> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | #ifndef _TIMEWAIT_SOCK_H | ||
12 | #define _TIMEWAIT_SOCK_H | ||
13 | |||
14 | #include <linux/slab.h> | ||
15 | #include <net/sock.h> | ||
16 | |||
17 | struct timewait_sock_ops { | ||
18 | kmem_cache_t *twsk_slab; | ||
19 | unsigned int twsk_obj_size; | ||
20 | int (*twsk_unique)(struct sock *sk, | ||
21 | struct sock *sktw, void *twp); | ||
22 | }; | ||
23 | |||
24 | static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp) | ||
25 | { | ||
26 | if (sk->sk_prot->twsk_prot->twsk_unique != NULL) | ||
27 | return sk->sk_prot->twsk_prot->twsk_unique(sk, sktw, twp); | ||
28 | return 0; | ||
29 | } | ||
30 | |||
31 | #endif /* _TIMEWAIT_SOCK_H */ | ||
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h index 4e86f2de6638..61f724c1036f 100644 --- a/include/net/transp_v6.h +++ b/include/net/transp_v6.h | |||
@@ -44,7 +44,7 @@ extern int datagram_send_ctl(struct msghdr *msg, | |||
44 | /* | 44 | /* |
45 | * address family specific functions | 45 | * address family specific functions |
46 | */ | 46 | */ |
47 | extern struct tcp_func ipv4_specific; | 47 | extern struct inet_connection_sock_af_ops ipv4_specific; |
48 | 48 | ||
49 | extern int inet6_destroy_sock(struct sock *sk); | 49 | extern int inet6_destroy_sock(struct sock *sk); |
50 | 50 | ||
diff --git a/include/net/udp.h b/include/net/udp.h index 107b9d791a1f..766fba1369ce 100644 --- a/include/net/udp.h +++ b/include/net/udp.h | |||
@@ -22,9 +22,8 @@ | |||
22 | #ifndef _UDP_H | 22 | #ifndef _UDP_H |
23 | #define _UDP_H | 23 | #define _UDP_H |
24 | 24 | ||
25 | #include <linux/udp.h> | ||
26 | #include <linux/ip.h> | ||
27 | #include <linux/list.h> | 25 | #include <linux/list.h> |
26 | #include <net/inet_sock.h> | ||
28 | #include <net/sock.h> | 27 | #include <net/sock.h> |
29 | #include <net/snmp.h> | 28 | #include <net/snmp.h> |
30 | #include <linux/seq_file.h> | 29 | #include <linux/seq_file.h> |
@@ -62,6 +61,7 @@ static inline int udp_lport_inuse(u16 num) | |||
62 | 61 | ||
63 | extern struct proto udp_prot; | 62 | extern struct proto udp_prot; |
64 | 63 | ||
64 | struct sk_buff; | ||
65 | 65 | ||
66 | extern void udp_err(struct sk_buff *, u32); | 66 | extern void udp_err(struct sk_buff *, u32); |
67 | 67 | ||
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 5beae1ccd574..07d7b50cdd76 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -2,11 +2,12 @@ | |||
2 | #define _NET_XFRM_H | 2 | #define _NET_XFRM_H |
3 | 3 | ||
4 | #include <linux/compiler.h> | 4 | #include <linux/compiler.h> |
5 | #include <linux/in.h> | ||
5 | #include <linux/xfrm.h> | 6 | #include <linux/xfrm.h> |
6 | #include <linux/spinlock.h> | 7 | #include <linux/spinlock.h> |
7 | #include <linux/list.h> | 8 | #include <linux/list.h> |
8 | #include <linux/skbuff.h> | 9 | #include <linux/skbuff.h> |
9 | #include <linux/netdevice.h> | 10 | #include <linux/socket.h> |
10 | #include <linux/crypto.h> | 11 | #include <linux/crypto.h> |
11 | #include <linux/pfkeyv2.h> | 12 | #include <linux/pfkeyv2.h> |
12 | #include <linux/in6.h> | 13 | #include <linux/in6.h> |
@@ -144,6 +145,9 @@ struct xfrm_state | |||
144 | * transformer. */ | 145 | * transformer. */ |
145 | struct xfrm_type *type; | 146 | struct xfrm_type *type; |
146 | 147 | ||
148 | /* Security context */ | ||
149 | struct xfrm_sec_ctx *security; | ||
150 | |||
147 | /* Private data of this transformer, format is opaque, | 151 | /* Private data of this transformer, format is opaque, |
148 | * interpreted by xfrm_type methods. */ | 152 | * interpreted by xfrm_type methods. */ |
149 | void *data; | 153 | void *data; |
@@ -298,6 +302,7 @@ struct xfrm_policy | |||
298 | __u8 flags; | 302 | __u8 flags; |
299 | __u8 dead; | 303 | __u8 dead; |
300 | __u8 xfrm_nr; | 304 | __u8 xfrm_nr; |
305 | struct xfrm_sec_ctx *security; | ||
301 | struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH]; | 306 | struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH]; |
302 | }; | 307 | }; |
303 | 308 | ||
@@ -510,6 +515,25 @@ xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl, | |||
510 | return 0; | 515 | return 0; |
511 | } | 516 | } |
512 | 517 | ||
518 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | ||
519 | /* If neither has a context --> match | ||
520 | * Otherwise, both must have a context and the sids, doi, alg must match | ||
521 | */ | ||
522 | static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2) | ||
523 | { | ||
524 | return ((!s1 && !s2) || | ||
525 | (s1 && s2 && | ||
526 | (s1->ctx_sid == s2->ctx_sid) && | ||
527 | (s1->ctx_doi == s2->ctx_doi) && | ||
528 | (s1->ctx_alg == s2->ctx_alg))); | ||
529 | } | ||
530 | #else | ||
531 | static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2) | ||
532 | { | ||
533 | return 1; | ||
534 | } | ||
535 | #endif | ||
536 | |||
513 | /* A struct encoding bundle of transformations to apply to some set of flow. | 537 | /* A struct encoding bundle of transformations to apply to some set of flow. |
514 | * | 538 | * |
515 | * dst->child points to the next element of bundle. | 539 | * dst->child points to the next element of bundle. |
@@ -878,8 +902,8 @@ static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsig | |||
878 | struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp); | 902 | struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp); |
879 | extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *); | 903 | extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *); |
880 | int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); | 904 | int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); |
881 | struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel, | 905 | struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel, |
882 | int delete); | 906 | struct xfrm_sec_ctx *ctx, int delete); |
883 | struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete); | 907 | struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete); |
884 | void xfrm_policy_flush(void); | 908 | void xfrm_policy_flush(void); |
885 | u32 xfrm_get_acqseq(void); | 909 | u32 xfrm_get_acqseq(void); |
@@ -890,6 +914,7 @@ struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, | |||
890 | extern void xfrm_policy_flush(void); | 914 | extern void xfrm_policy_flush(void); |
891 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); | 915 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); |
892 | extern int xfrm_flush_bundles(void); | 916 | extern int xfrm_flush_bundles(void); |
917 | extern void xfrm_flush_all_bundles(void); | ||
893 | extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family); | 918 | extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family); |
894 | extern void xfrm_init_pmtu(struct dst_entry *dst); | 919 | extern void xfrm_init_pmtu(struct dst_entry *dst); |
895 | 920 | ||
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index fac547d32a98..394f14a5b7cb 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h | |||
@@ -79,6 +79,7 @@ enum fc_port_state { | |||
79 | FC_PORTSTATE_LINKDOWN, | 79 | FC_PORTSTATE_LINKDOWN, |
80 | FC_PORTSTATE_ERROR, | 80 | FC_PORTSTATE_ERROR, |
81 | FC_PORTSTATE_LOOPBACK, | 81 | FC_PORTSTATE_LOOPBACK, |
82 | FC_PORTSTATE_DELETED, | ||
82 | }; | 83 | }; |
83 | 84 | ||
84 | 85 | ||
@@ -325,8 +326,14 @@ struct fc_host_attrs { | |||
325 | struct list_head rport_bindings; | 326 | struct list_head rport_bindings; |
326 | u32 next_rport_number; | 327 | u32 next_rport_number; |
327 | u32 next_target_id; | 328 | u32 next_target_id; |
329 | u8 flags; | ||
330 | struct work_struct rport_del_work; | ||
328 | }; | 331 | }; |
329 | 332 | ||
333 | /* values for struct fc_host_attrs "flags" field: */ | ||
334 | #define FC_SHOST_RPORT_DEL_SCHEDULED 0x01 | ||
335 | |||
336 | |||
330 | #define fc_host_node_name(x) \ | 337 | #define fc_host_node_name(x) \ |
331 | (((struct fc_host_attrs *)(x)->shost_data)->node_name) | 338 | (((struct fc_host_attrs *)(x)->shost_data)->node_name) |
332 | #define fc_host_port_name(x) \ | 339 | #define fc_host_port_name(x) \ |
@@ -365,6 +372,10 @@ struct fc_host_attrs { | |||
365 | (((struct fc_host_attrs *)(x)->shost_data)->next_rport_number) | 372 | (((struct fc_host_attrs *)(x)->shost_data)->next_rport_number) |
366 | #define fc_host_next_target_id(x) \ | 373 | #define fc_host_next_target_id(x) \ |
367 | (((struct fc_host_attrs *)(x)->shost_data)->next_target_id) | 374 | (((struct fc_host_attrs *)(x)->shost_data)->next_target_id) |
375 | #define fc_host_flags(x) \ | ||
376 | (((struct fc_host_attrs *)(x)->shost_data)->flags) | ||
377 | #define fc_host_rport_del_work(x) \ | ||
378 | (((struct fc_host_attrs *)(x)->shost_data)->rport_del_work) | ||
368 | 379 | ||
369 | 380 | ||
370 | /* The functions by which the transport class and the driver communicate */ | 381 | /* The functions by which the transport class and the driver communicate */ |
diff --git a/init/Kconfig b/init/Kconfig index 6c5dbedc6e96..9fc0759fa942 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -260,7 +260,6 @@ config CC_OPTIMIZE_FOR_SIZE | |||
260 | bool "Optimize for size (Look out for broken compilers!)" | 260 | bool "Optimize for size (Look out for broken compilers!)" |
261 | default y | 261 | default y |
262 | depends on ARM || H8300 || EXPERIMENTAL | 262 | depends on ARM || H8300 || EXPERIMENTAL |
263 | depends on !SPARC64 | ||
264 | help | 263 | help |
265 | Enabling this option will pass "-Os" instead of "-O2" to gcc | 264 | Enabling this option will pass "-Os" instead of "-O2" to gcc |
266 | resulting in a smaller kernel. | 265 | resulting in a smaller kernel. |
diff --git a/init/main.c b/init/main.c index 27f97f9b4636..54aaf561cf66 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <linux/rmap.h> | 47 | #include <linux/rmap.h> |
48 | #include <linux/mempolicy.h> | 48 | #include <linux/mempolicy.h> |
49 | #include <linux/key.h> | 49 | #include <linux/key.h> |
50 | #include <net/sock.h> | ||
51 | 50 | ||
52 | #include <asm/io.h> | 51 | #include <asm/io.h> |
53 | #include <asm/bugs.h> | 52 | #include <asm/bugs.h> |
@@ -614,9 +613,6 @@ static void __init do_basic_setup(void) | |||
614 | sysctl_init(); | 613 | sysctl_init(); |
615 | #endif | 614 | #endif |
616 | 615 | ||
617 | /* Networking initialization needs a process context */ | ||
618 | sock_init(); | ||
619 | |||
620 | do_initcalls(); | 616 | do_initcalls(); |
621 | } | 617 | } |
622 | 618 | ||
@@ -381,6 +381,7 @@ static void update_queue (struct sem_array * sma) | |||
381 | /* hands-off: q will disappear immediately after | 381 | /* hands-off: q will disappear immediately after |
382 | * writing q->status. | 382 | * writing q->status. |
383 | */ | 383 | */ |
384 | smp_wmb(); | ||
384 | q->status = error; | 385 | q->status = error; |
385 | q = n; | 386 | q = n; |
386 | } else { | 387 | } else { |
@@ -461,6 +462,7 @@ static void freeary (struct sem_array *sma, int id) | |||
461 | n = q->next; | 462 | n = q->next; |
462 | q->status = IN_WAKEUP; | 463 | q->status = IN_WAKEUP; |
463 | wake_up_process(q->sleeper); /* doesn't sleep */ | 464 | wake_up_process(q->sleeper); /* doesn't sleep */ |
465 | smp_wmb(); | ||
464 | q->status = -EIDRM; /* hands-off q */ | 466 | q->status = -EIDRM; /* hands-off q */ |
465 | q = n; | 467 | q = n; |
466 | } | 468 | } |
diff --git a/kernel/futex.c b/kernel/futex.c index 5872e3507f35..5e71a6bf6f6b 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -270,7 +270,13 @@ static void wake_futex(struct futex_q *q) | |||
270 | /* | 270 | /* |
271 | * The waiting task can free the futex_q as soon as this is written, | 271 | * The waiting task can free the futex_q as soon as this is written, |
272 | * without taking any locks. This must come last. | 272 | * without taking any locks. This must come last. |
273 | * | ||
274 | * A memory barrier is required here to prevent the following store | ||
275 | * to lock_ptr from getting ahead of the wakeup. Clearing the lock | ||
276 | * at the end of wake_up_all() does not prevent this store from | ||
277 | * moving. | ||
273 | */ | 278 | */ |
279 | wmb(); | ||
274 | q->lock_ptr = NULL; | 280 | q->lock_ptr = NULL; |
275 | } | 281 | } |
276 | 282 | ||
diff --git a/kernel/params.c b/kernel/params.c index 47ba69547945..c76ad25e6a21 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
@@ -619,7 +619,7 @@ static void __init param_sysfs_builtin(void) | |||
619 | 619 | ||
620 | 620 | ||
621 | /* module-related sysfs stuff */ | 621 | /* module-related sysfs stuff */ |
622 | #ifdef CONFIG_MODULES | 622 | #ifdef CONFIG_SYSFS |
623 | 623 | ||
624 | #define to_module_attr(n) container_of(n, struct module_attribute, attr); | 624 | #define to_module_attr(n) container_of(n, struct module_attribute, attr); |
625 | #define to_module_kobject(n) container_of(n, struct module_kobject, kobj); | 625 | #define to_module_kobject(n) container_of(n, struct module_kobject, kobj); |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 9990e10192e8..b53115b882e1 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -2192,29 +2192,32 @@ int sysctl_string(ctl_table *table, int __user *name, int nlen, | |||
2192 | void __user *oldval, size_t __user *oldlenp, | 2192 | void __user *oldval, size_t __user *oldlenp, |
2193 | void __user *newval, size_t newlen, void **context) | 2193 | void __user *newval, size_t newlen, void **context) |
2194 | { | 2194 | { |
2195 | size_t l, len; | ||
2196 | |||
2197 | if (!table->data || !table->maxlen) | 2195 | if (!table->data || !table->maxlen) |
2198 | return -ENOTDIR; | 2196 | return -ENOTDIR; |
2199 | 2197 | ||
2200 | if (oldval && oldlenp) { | 2198 | if (oldval && oldlenp) { |
2201 | if (get_user(len, oldlenp)) | 2199 | size_t bufsize; |
2200 | if (get_user(bufsize, oldlenp)) | ||
2202 | return -EFAULT; | 2201 | return -EFAULT; |
2203 | if (len) { | 2202 | if (bufsize) { |
2204 | l = strlen(table->data); | 2203 | size_t len = strlen(table->data), copied; |
2205 | if (len > l) len = l; | 2204 | |
2206 | if (len >= table->maxlen) | 2205 | /* This shouldn't trigger for a well-formed sysctl */ |
2206 | if (len > table->maxlen) | ||
2207 | len = table->maxlen; | 2207 | len = table->maxlen; |
2208 | if(copy_to_user(oldval, table->data, len)) | 2208 | |
2209 | return -EFAULT; | 2209 | /* Copy up to a max of bufsize-1 bytes of the string */ |
2210 | if(put_user(0, ((char __user *) oldval) + len)) | 2210 | copied = (len >= bufsize) ? bufsize - 1 : len; |
2211 | |||
2212 | if (copy_to_user(oldval, table->data, copied) || | ||
2213 | put_user(0, (char __user *)(oldval + copied))) | ||
2211 | return -EFAULT; | 2214 | return -EFAULT; |
2212 | if(put_user(len, oldlenp)) | 2215 | if (put_user(len, oldlenp)) |
2213 | return -EFAULT; | 2216 | return -EFAULT; |
2214 | } | 2217 | } |
2215 | } | 2218 | } |
2216 | if (newval && newlen) { | 2219 | if (newval && newlen) { |
2217 | len = newlen; | 2220 | size_t len = newlen; |
2218 | if (len > table->maxlen) | 2221 | if (len > table->maxlen) |
2219 | len = table->maxlen; | 2222 | len = table->maxlen; |
2220 | if(copy_from_user(table->data, newval, len)) | 2223 | if(copy_from_user(table->data, newval, len)) |
@@ -2223,7 +2226,7 @@ int sysctl_string(ctl_table *table, int __user *name, int nlen, | |||
2223 | len--; | 2226 | len--; |
2224 | ((char *) table->data)[len] = 0; | 2227 | ((char *) table->data)[len] = 0; |
2225 | } | 2228 | } |
2226 | return 0; | 2229 | return 1; |
2227 | } | 2230 | } |
2228 | 2231 | ||
2229 | /* | 2232 | /* |
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index 906ad101eab3..dcd4be9bd4e5 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c | |||
@@ -20,7 +20,8 @@ static void spin_bug(spinlock_t *lock, const char *msg) | |||
20 | if (lock->owner && lock->owner != SPINLOCK_OWNER_INIT) | 20 | if (lock->owner && lock->owner != SPINLOCK_OWNER_INIT) |
21 | owner = lock->owner; | 21 | owner = lock->owner; |
22 | printk("BUG: spinlock %s on CPU#%d, %s/%d\n", | 22 | printk("BUG: spinlock %s on CPU#%d, %s/%d\n", |
23 | msg, smp_processor_id(), current->comm, current->pid); | 23 | msg, raw_smp_processor_id(), |
24 | current->comm, current->pid); | ||
24 | printk(" lock: %p, .magic: %08x, .owner: %s/%d, .owner_cpu: %d\n", | 25 | printk(" lock: %p, .magic: %08x, .owner: %s/%d, .owner_cpu: %d\n", |
25 | lock, lock->magic, | 26 | lock, lock->magic, |
26 | owner ? owner->comm : "<none>", | 27 | owner ? owner->comm : "<none>", |
@@ -78,8 +79,8 @@ static void __spin_lock_debug(spinlock_t *lock) | |||
78 | if (print_once) { | 79 | if (print_once) { |
79 | print_once = 0; | 80 | print_once = 0; |
80 | printk("BUG: spinlock lockup on CPU#%d, %s/%d, %p\n", | 81 | printk("BUG: spinlock lockup on CPU#%d, %s/%d, %p\n", |
81 | smp_processor_id(), current->comm, current->pid, | 82 | raw_smp_processor_id(), current->comm, |
82 | lock); | 83 | current->pid, lock); |
83 | dump_stack(); | 84 | dump_stack(); |
84 | } | 85 | } |
85 | } | 86 | } |
@@ -120,7 +121,8 @@ static void rwlock_bug(rwlock_t *lock, const char *msg) | |||
120 | 121 | ||
121 | if (xchg(&print_once, 0)) { | 122 | if (xchg(&print_once, 0)) { |
122 | printk("BUG: rwlock %s on CPU#%d, %s/%d, %p\n", msg, | 123 | printk("BUG: rwlock %s on CPU#%d, %s/%d, %p\n", msg, |
123 | smp_processor_id(), current->comm, current->pid, lock); | 124 | raw_smp_processor_id(), current->comm, |
125 | current->pid, lock); | ||
124 | dump_stack(); | 126 | dump_stack(); |
125 | #ifdef CONFIG_SMP | 127 | #ifdef CONFIG_SMP |
126 | /* | 128 | /* |
@@ -148,8 +150,8 @@ static void __read_lock_debug(rwlock_t *lock) | |||
148 | if (print_once) { | 150 | if (print_once) { |
149 | print_once = 0; | 151 | print_once = 0; |
150 | printk("BUG: read-lock lockup on CPU#%d, %s/%d, %p\n", | 152 | printk("BUG: read-lock lockup on CPU#%d, %s/%d, %p\n", |
151 | smp_processor_id(), current->comm, current->pid, | 153 | raw_smp_processor_id(), current->comm, |
152 | lock); | 154 | current->pid, lock); |
153 | dump_stack(); | 155 | dump_stack(); |
154 | } | 156 | } |
155 | } | 157 | } |
@@ -220,8 +222,8 @@ static void __write_lock_debug(rwlock_t *lock) | |||
220 | if (print_once) { | 222 | if (print_once) { |
221 | print_once = 0; | 223 | print_once = 0; |
222 | printk("BUG: write-lock lockup on CPU#%d, %s/%d, %p\n", | 224 | printk("BUG: write-lock lockup on CPU#%d, %s/%d, %p\n", |
223 | smp_processor_id(), current->comm, current->pid, | 225 | raw_smp_processor_id(), current->comm, |
224 | lock); | 226 | current->pid, lock); |
225 | dump_stack(); | 227 | dump_stack(); |
226 | } | 228 | } |
227 | } | 229 | } |
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 57216f3544ca..1ff8dcebf7c6 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
@@ -704,8 +704,9 @@ swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems, | |||
704 | addr = SG_ENT_VIRT_ADDRESS(sg); | 704 | addr = SG_ENT_VIRT_ADDRESS(sg); |
705 | dev_addr = virt_to_phys(addr); | 705 | dev_addr = virt_to_phys(addr); |
706 | if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) { | 706 | if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) { |
707 | sg->dma_address = (dma_addr_t) virt_to_phys(map_single(hwdev, addr, sg->length, dir)); | 707 | void *map = map_single(hwdev, addr, sg->length, dir); |
708 | if (!sg->dma_address) { | 708 | sg->dma_address = virt_to_bus(map); |
709 | if (!map) { | ||
709 | /* Don't panic here, we expect map_sg users | 710 | /* Don't panic here, we expect map_sg users |
710 | to do proper error handling. */ | 711 | to do proper error handling. */ |
711 | swiotlb_full(hwdev, sg->length, dir, 0); | 712 | swiotlb_full(hwdev, sg->length, dir, 0); |
diff --git a/mm/memory.c b/mm/memory.c index d22f78c8a381..d8dde07a3656 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -574,7 +574,7 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm, | |||
574 | * readonly mappings. The tradeoff is that copy_page_range is more | 574 | * readonly mappings. The tradeoff is that copy_page_range is more |
575 | * efficient than faulting. | 575 | * efficient than faulting. |
576 | */ | 576 | */ |
577 | if (!(vma->vm_flags & (VM_HUGETLB|VM_NONLINEAR|VM_PFNMAP))) { | 577 | if (!(vma->vm_flags & (VM_HUGETLB|VM_NONLINEAR|VM_PFNMAP|VM_INSERTPAGE))) { |
578 | if (!vma->anon_vma) | 578 | if (!vma->anon_vma) |
579 | return 0; | 579 | return 0; |
580 | } | 580 | } |
@@ -1228,6 +1228,7 @@ int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, struct page * | |||
1228 | return -EFAULT; | 1228 | return -EFAULT; |
1229 | if (!page_count(page)) | 1229 | if (!page_count(page)) |
1230 | return -EINVAL; | 1230 | return -EINVAL; |
1231 | vma->vm_flags |= VM_INSERTPAGE; | ||
1231 | return insert_page(vma->vm_mm, addr, page, vma->vm_page_prot); | 1232 | return insert_page(vma->vm_mm, addr, page, vma->vm_page_prot); |
1232 | } | 1233 | } |
1233 | EXPORT_SYMBOL(vm_insert_page); | 1234 | EXPORT_SYMBOL(vm_insert_page); |
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index bec88c81244e..72f402cc9c9a 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -161,6 +161,10 @@ static struct mempolicy *mpol_new(int mode, nodemask_t *nodes) | |||
161 | switch (mode) { | 161 | switch (mode) { |
162 | case MPOL_INTERLEAVE: | 162 | case MPOL_INTERLEAVE: |
163 | policy->v.nodes = *nodes; | 163 | policy->v.nodes = *nodes; |
164 | if (nodes_weight(*nodes) == 0) { | ||
165 | kmem_cache_free(policy_cache, policy); | ||
166 | return ERR_PTR(-EINVAL); | ||
167 | } | ||
164 | break; | 168 | break; |
165 | case MPOL_PREFERRED: | 169 | case MPOL_PREFERRED: |
166 | policy->v.preferred_node = first_node(*nodes); | 170 | policy->v.preferred_node = first_node(*nodes); |
@@ -611,7 +611,7 @@ again: remove_next = 1 + (end > next->vm_end); | |||
611 | * If the vma has a ->close operation then the driver probably needs to release | 611 | * If the vma has a ->close operation then the driver probably needs to release |
612 | * per-vma resources, so we don't attempt to merge those. | 612 | * per-vma resources, so we don't attempt to merge those. |
613 | */ | 613 | */ |
614 | #define VM_SPECIAL (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED) | 614 | #define VM_SPECIAL (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP) |
615 | 615 | ||
616 | static inline int is_mergeable_vma(struct vm_area_struct *vma, | 616 | static inline int is_mergeable_vma(struct vm_area_struct *vma, |
617 | struct file *file, unsigned long vm_flags) | 617 | struct file *file, unsigned long vm_flags) |
diff --git a/mm/mremap.c b/mm/mremap.c index b535438c363c..ddaeee9a0b69 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
@@ -323,7 +323,7 @@ unsigned long do_mremap(unsigned long addr, | |||
323 | /* We can't remap across vm area boundaries */ | 323 | /* We can't remap across vm area boundaries */ |
324 | if (old_len > vma->vm_end - addr) | 324 | if (old_len > vma->vm_end - addr) |
325 | goto out; | 325 | goto out; |
326 | if (vma->vm_flags & VM_DONTEXPAND) { | 326 | if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) { |
327 | if (new_len > old_len) | 327 | if (new_len > old_len) |
328 | goto out; | 328 | goto out; |
329 | } | 329 | } |
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 91e412b0ab00..67465b65abe4 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -753,6 +753,8 @@ static int vlan_ioctl_handler(void __user *arg) | |||
753 | break; | 753 | break; |
754 | case GET_VLAN_REALDEV_NAME_CMD: | 754 | case GET_VLAN_REALDEV_NAME_CMD: |
755 | err = vlan_dev_get_realdev_name(args.device1, args.u.device2); | 755 | err = vlan_dev_get_realdev_name(args.device1, args.u.device2); |
756 | if (err) | ||
757 | goto out; | ||
756 | if (copy_to_user(arg, &args, | 758 | if (copy_to_user(arg, &args, |
757 | sizeof(struct vlan_ioctl_args))) { | 759 | sizeof(struct vlan_ioctl_args))) { |
758 | err = -EFAULT; | 760 | err = -EFAULT; |
@@ -761,6 +763,8 @@ static int vlan_ioctl_handler(void __user *arg) | |||
761 | 763 | ||
762 | case GET_VLAN_VID_CMD: | 764 | case GET_VLAN_VID_CMD: |
763 | err = vlan_dev_get_vid(args.device1, &vid); | 765 | err = vlan_dev_get_vid(args.device1, &vid); |
766 | if (err) | ||
767 | goto out; | ||
764 | args.u.VID = vid; | 768 | args.u.VID = vid; |
765 | if (copy_to_user(arg, &args, | 769 | if (copy_to_user(arg, &args, |
766 | sizeof(struct vlan_ioctl_args))) { | 770 | sizeof(struct vlan_ioctl_args))) { |
@@ -774,7 +778,7 @@ static int vlan_ioctl_handler(void __user *arg) | |||
774 | __FUNCTION__, args.cmd); | 778 | __FUNCTION__, args.cmd); |
775 | return -EINVAL; | 779 | return -EINVAL; |
776 | }; | 780 | }; |
777 | 781 | out: | |
778 | return err; | 782 | return err; |
779 | } | 783 | } |
780 | 784 | ||
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 7982656b9c83..a5144e43aae1 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
@@ -63,7 +63,7 @@ | |||
63 | #include <linux/atalk.h> | 63 | #include <linux/atalk.h> |
64 | 64 | ||
65 | struct datalink_proto *ddp_dl, *aarp_dl; | 65 | struct datalink_proto *ddp_dl, *aarp_dl; |
66 | static struct proto_ops atalk_dgram_ops; | 66 | static const struct proto_ops atalk_dgram_ops; |
67 | 67 | ||
68 | /**************************************************************************\ | 68 | /**************************************************************************\ |
69 | * * | 69 | * * |
@@ -1763,7 +1763,7 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr | |||
1763 | */ | 1763 | */ |
1764 | static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | 1764 | static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
1765 | { | 1765 | { |
1766 | int rc = -EINVAL; | 1766 | int rc = -ENOIOCTLCMD; |
1767 | struct sock *sk = sock->sk; | 1767 | struct sock *sk = sock->sk; |
1768 | void __user *argp = (void __user *)arg; | 1768 | void __user *argp = (void __user *)arg; |
1769 | 1769 | ||
@@ -1813,23 +1813,6 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1813 | rc = atif_ioctl(cmd, argp); | 1813 | rc = atif_ioctl(cmd, argp); |
1814 | rtnl_unlock(); | 1814 | rtnl_unlock(); |
1815 | break; | 1815 | break; |
1816 | /* Physical layer ioctl calls */ | ||
1817 | case SIOCSIFLINK: | ||
1818 | case SIOCGIFHWADDR: | ||
1819 | case SIOCSIFHWADDR: | ||
1820 | case SIOCGIFFLAGS: | ||
1821 | case SIOCSIFFLAGS: | ||
1822 | case SIOCGIFTXQLEN: | ||
1823 | case SIOCSIFTXQLEN: | ||
1824 | case SIOCGIFMTU: | ||
1825 | case SIOCGIFCONF: | ||
1826 | case SIOCADDMULTI: | ||
1827 | case SIOCDELMULTI: | ||
1828 | case SIOCGIFCOUNT: | ||
1829 | case SIOCGIFINDEX: | ||
1830 | case SIOCGIFNAME: | ||
1831 | rc = dev_ioctl(cmd, argp); | ||
1832 | break; | ||
1833 | } | 1816 | } |
1834 | 1817 | ||
1835 | return rc; | 1818 | return rc; |
@@ -1841,7 +1824,7 @@ static struct net_proto_family atalk_family_ops = { | |||
1841 | .owner = THIS_MODULE, | 1824 | .owner = THIS_MODULE, |
1842 | }; | 1825 | }; |
1843 | 1826 | ||
1844 | static struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = { | 1827 | static const struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = { |
1845 | .family = PF_APPLETALK, | 1828 | .family = PF_APPLETALK, |
1846 | .owner = THIS_MODULE, | 1829 | .owner = THIS_MODULE, |
1847 | .release = atalk_release, | 1830 | .release = atalk_release, |
diff --git a/net/atm/pvc.c b/net/atm/pvc.c index 2684a92da22b..f2c541774dcd 100644 --- a/net/atm/pvc.c +++ b/net/atm/pvc.c | |||
@@ -102,7 +102,7 @@ static int pvc_getname(struct socket *sock,struct sockaddr *sockaddr, | |||
102 | } | 102 | } |
103 | 103 | ||
104 | 104 | ||
105 | static struct proto_ops pvc_proto_ops = { | 105 | static const struct proto_ops pvc_proto_ops = { |
106 | .family = PF_ATMPVC, | 106 | .family = PF_ATMPVC, |
107 | .owner = THIS_MODULE, | 107 | .owner = THIS_MODULE, |
108 | 108 | ||
diff --git a/net/atm/svc.c b/net/atm/svc.c index d7b266136bf6..3a180cfd7b48 100644 --- a/net/atm/svc.c +++ b/net/atm/svc.c | |||
@@ -613,7 +613,7 @@ static int svc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
613 | return error; | 613 | return error; |
614 | } | 614 | } |
615 | 615 | ||
616 | static struct proto_ops svc_proto_ops = { | 616 | static const struct proto_ops svc_proto_ops = { |
617 | .family = PF_ATMSVC, | 617 | .family = PF_ATMSVC, |
618 | .owner = THIS_MODULE, | 618 | .owner = THIS_MODULE, |
619 | 619 | ||
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 1b683f302657..e8753c7fcad1 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
@@ -54,7 +54,7 @@ | |||
54 | HLIST_HEAD(ax25_list); | 54 | HLIST_HEAD(ax25_list); |
55 | DEFINE_SPINLOCK(ax25_list_lock); | 55 | DEFINE_SPINLOCK(ax25_list_lock); |
56 | 56 | ||
57 | static struct proto_ops ax25_proto_ops; | 57 | static const struct proto_ops ax25_proto_ops; |
58 | 58 | ||
59 | static void ax25_free_sock(struct sock *sk) | 59 | static void ax25_free_sock(struct sock *sk) |
60 | { | 60 | { |
@@ -1827,7 +1827,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1827 | break; | 1827 | break; |
1828 | 1828 | ||
1829 | default: | 1829 | default: |
1830 | res = dev_ioctl(cmd, argp); | 1830 | res = -ENOIOCTLCMD; |
1831 | break; | 1831 | break; |
1832 | } | 1832 | } |
1833 | release_sock(sk); | 1833 | release_sock(sk); |
@@ -1944,7 +1944,7 @@ static struct net_proto_family ax25_family_ops = { | |||
1944 | .owner = THIS_MODULE, | 1944 | .owner = THIS_MODULE, |
1945 | }; | 1945 | }; |
1946 | 1946 | ||
1947 | static struct proto_ops ax25_proto_ops = { | 1947 | static const struct proto_ops ax25_proto_ops = { |
1948 | .family = PF_AX25, | 1948 | .family = PF_AX25, |
1949 | .owner = THIS_MODULE, | 1949 | .owner = THIS_MODULE, |
1950 | .release = ax25_release, | 1950 | .release = ax25_release, |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index ea616e3fc98e..fb031fe9be9e 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -287,10 +287,9 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) | |||
287 | timeo = schedule_timeout(timeo); | 287 | timeo = schedule_timeout(timeo); |
288 | lock_sock(sk); | 288 | lock_sock(sk); |
289 | 289 | ||
290 | if (sk->sk_err) { | 290 | err = sock_error(sk); |
291 | err = sock_error(sk); | 291 | if (err) |
292 | break; | 292 | break; |
293 | } | ||
294 | } | 293 | } |
295 | set_current_state(TASK_RUNNING); | 294 | set_current_state(TASK_RUNNING); |
296 | remove_wait_queue(sk->sk_sleep, &wait); | 295 | remove_wait_queue(sk->sk_sleep, &wait); |
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index 9778c6acd53b..ccbaf69afc5b 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c | |||
@@ -146,7 +146,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
146 | return 0; | 146 | return 0; |
147 | } | 147 | } |
148 | 148 | ||
149 | static struct proto_ops bnep_sock_ops = { | 149 | static const struct proto_ops bnep_sock_ops = { |
150 | .family = PF_BLUETOOTH, | 150 | .family = PF_BLUETOOTH, |
151 | .owner = THIS_MODULE, | 151 | .owner = THIS_MODULE, |
152 | .release = bnep_sock_release, | 152 | .release = bnep_sock_release, |
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c index beb045bf5714..5e22343b6090 100644 --- a/net/bluetooth/cmtp/sock.c +++ b/net/bluetooth/cmtp/sock.c | |||
@@ -137,7 +137,7 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
137 | return -EINVAL; | 137 | return -EINVAL; |
138 | } | 138 | } |
139 | 139 | ||
140 | static struct proto_ops cmtp_sock_ops = { | 140 | static const struct proto_ops cmtp_sock_ops = { |
141 | .family = PF_BLUETOOTH, | 141 | .family = PF_BLUETOOTH, |
142 | .owner = THIS_MODULE, | 142 | .owner = THIS_MODULE, |
143 | .release = cmtp_sock_release, | 143 | .release = cmtp_sock_release, |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 1d6d0a15c099..84e6c93a044a 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -575,7 +575,7 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char | |||
575 | return 0; | 575 | return 0; |
576 | } | 576 | } |
577 | 577 | ||
578 | static struct proto_ops hci_sock_ops = { | 578 | static const struct proto_ops hci_sock_ops = { |
579 | .family = PF_BLUETOOTH, | 579 | .family = PF_BLUETOOTH, |
580 | .owner = THIS_MODULE, | 580 | .owner = THIS_MODULE, |
581 | .release = hci_sock_release, | 581 | .release = hci_sock_release, |
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c index f8986f881431..8f8dd931b294 100644 --- a/net/bluetooth/hidp/sock.c +++ b/net/bluetooth/hidp/sock.c | |||
@@ -143,7 +143,7 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
143 | return -EINVAL; | 143 | return -EINVAL; |
144 | } | 144 | } |
145 | 145 | ||
146 | static struct proto_ops hidp_sock_ops = { | 146 | static const struct proto_ops hidp_sock_ops = { |
147 | .family = PF_BLUETOOTH, | 147 | .family = PF_BLUETOOTH, |
148 | .owner = THIS_MODULE, | 148 | .owner = THIS_MODULE, |
149 | .release = hidp_sock_release, | 149 | .release = hidp_sock_release, |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index e3bb11ca4235..7f0781e4326f 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -57,7 +57,7 @@ | |||
57 | 57 | ||
58 | #define VERSION "2.8" | 58 | #define VERSION "2.8" |
59 | 59 | ||
60 | static struct proto_ops l2cap_sock_ops; | 60 | static const struct proto_ops l2cap_sock_ops; |
61 | 61 | ||
62 | static struct bt_sock_list l2cap_sk_list = { | 62 | static struct bt_sock_list l2cap_sk_list = { |
63 | .lock = RW_LOCK_UNLOCKED | 63 | .lock = RW_LOCK_UNLOCKED |
@@ -767,8 +767,9 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
767 | 767 | ||
768 | BT_DBG("sock %p, sk %p", sock, sk); | 768 | BT_DBG("sock %p, sk %p", sock, sk); |
769 | 769 | ||
770 | if (sk->sk_err) | 770 | err = sock_error(sk); |
771 | return sock_error(sk); | 771 | if (err) |
772 | return err; | ||
772 | 773 | ||
773 | if (msg->msg_flags & MSG_OOB) | 774 | if (msg->msg_flags & MSG_OOB) |
774 | return -EOPNOTSUPP; | 775 | return -EOPNOTSUPP; |
@@ -2160,7 +2161,7 @@ static ssize_t l2cap_sysfs_show(struct class *dev, char *buf) | |||
2160 | 2161 | ||
2161 | static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL); | 2162 | static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL); |
2162 | 2163 | ||
2163 | static struct proto_ops l2cap_sock_ops = { | 2164 | static const struct proto_ops l2cap_sock_ops = { |
2164 | .family = PF_BLUETOOTH, | 2165 | .family = PF_BLUETOOTH, |
2165 | .owner = THIS_MODULE, | 2166 | .owner = THIS_MODULE, |
2166 | .release = l2cap_sock_release, | 2167 | .release = l2cap_sock_release, |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 6c34261b232e..757d2dd3b02f 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -58,7 +58,7 @@ | |||
58 | #define BT_DBG(D...) | 58 | #define BT_DBG(D...) |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | static struct proto_ops rfcomm_sock_ops; | 61 | static const struct proto_ops rfcomm_sock_ops; |
62 | 62 | ||
63 | static struct bt_sock_list rfcomm_sk_list = { | 63 | static struct bt_sock_list rfcomm_sk_list = { |
64 | .lock = RW_LOCK_UNLOCKED | 64 | .lock = RW_LOCK_UNLOCKED |
@@ -907,7 +907,7 @@ static ssize_t rfcomm_sock_sysfs_show(struct class *dev, char *buf) | |||
907 | 907 | ||
908 | static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL); | 908 | static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL); |
909 | 909 | ||
910 | static struct proto_ops rfcomm_sock_ops = { | 910 | static const struct proto_ops rfcomm_sock_ops = { |
911 | .family = PF_BLUETOOTH, | 911 | .family = PF_BLUETOOTH, |
912 | .owner = THIS_MODULE, | 912 | .owner = THIS_MODULE, |
913 | .release = rfcomm_sock_release, | 913 | .release = rfcomm_sock_release, |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 9cb00dc6c08c..6b61323ce23c 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -56,7 +56,7 @@ | |||
56 | 56 | ||
57 | #define VERSION "0.5" | 57 | #define VERSION "0.5" |
58 | 58 | ||
59 | static struct proto_ops sco_sock_ops; | 59 | static const struct proto_ops sco_sock_ops; |
60 | 60 | ||
61 | static struct bt_sock_list sco_sk_list = { | 61 | static struct bt_sock_list sco_sk_list = { |
62 | .lock = RW_LOCK_UNLOCKED | 62 | .lock = RW_LOCK_UNLOCKED |
@@ -637,8 +637,9 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
637 | 637 | ||
638 | BT_DBG("sock %p, sk %p", sock, sk); | 638 | BT_DBG("sock %p, sk %p", sock, sk); |
639 | 639 | ||
640 | if (sk->sk_err) | 640 | err = sock_error(sk); |
641 | return sock_error(sk); | 641 | if (err) |
642 | return err; | ||
642 | 643 | ||
643 | if (msg->msg_flags & MSG_OOB) | 644 | if (msg->msg_flags & MSG_OOB) |
644 | return -EOPNOTSUPP; | 645 | return -EOPNOTSUPP; |
@@ -913,7 +914,7 @@ static ssize_t sco_sysfs_show(struct class *dev, char *buf) | |||
913 | 914 | ||
914 | static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL); | 915 | static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL); |
915 | 916 | ||
916 | static struct proto_ops sco_sock_ops = { | 917 | static const struct proto_ops sco_sock_ops = { |
917 | .family = PF_BLUETOOTH, | 918 | .family = PF_BLUETOOTH, |
918 | .owner = THIS_MODULE, | 919 | .owner = THIS_MODULE, |
919 | .release = sco_sock_release, | 920 | .release = sco_sock_release, |
diff --git a/net/bridge/br.c b/net/bridge/br.c index f8f184942aaf..188cc1ac49eb 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c | |||
@@ -67,3 +67,4 @@ EXPORT_SYMBOL(br_should_route_hook); | |||
67 | module_init(br_init) | 67 | module_init(br_init) |
68 | module_exit(br_deinit) | 68 | module_exit(br_deinit) |
69 | MODULE_LICENSE("GPL"); | 69 | MODULE_LICENSE("GPL"); |
70 | MODULE_VERSION(BR_VERSION); | ||
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index f564ee99782d..0b33a7b3a00c 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
@@ -15,7 +15,9 @@ | |||
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/netdevice.h> | 17 | #include <linux/netdevice.h> |
18 | #include <linux/module.h> | 18 | #include <linux/etherdevice.h> |
19 | #include <linux/ethtool.h> | ||
20 | |||
19 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
20 | #include "br_private.h" | 22 | #include "br_private.h" |
21 | 23 | ||
@@ -82,6 +84,87 @@ static int br_change_mtu(struct net_device *dev, int new_mtu) | |||
82 | return 0; | 84 | return 0; |
83 | } | 85 | } |
84 | 86 | ||
87 | /* Allow setting mac address of pseudo-bridge to be same as | ||
88 | * any of the bound interfaces | ||
89 | */ | ||
90 | static int br_set_mac_address(struct net_device *dev, void *p) | ||
91 | { | ||
92 | struct net_bridge *br = netdev_priv(dev); | ||
93 | struct sockaddr *addr = p; | ||
94 | struct net_bridge_port *port; | ||
95 | int err = -EADDRNOTAVAIL; | ||
96 | |||
97 | spin_lock_bh(&br->lock); | ||
98 | list_for_each_entry(port, &br->port_list, list) { | ||
99 | if (!compare_ether_addr(port->dev->dev_addr, addr->sa_data)) { | ||
100 | br_stp_change_bridge_id(br, addr->sa_data); | ||
101 | err = 0; | ||
102 | break; | ||
103 | } | ||
104 | } | ||
105 | spin_unlock_bh(&br->lock); | ||
106 | |||
107 | return err; | ||
108 | } | ||
109 | |||
110 | static void br_getinfo(struct net_device *dev, struct ethtool_drvinfo *info) | ||
111 | { | ||
112 | strcpy(info->driver, "bridge"); | ||
113 | strcpy(info->version, BR_VERSION); | ||
114 | strcpy(info->fw_version, "N/A"); | ||
115 | strcpy(info->bus_info, "N/A"); | ||
116 | } | ||
117 | |||
118 | static int br_set_sg(struct net_device *dev, u32 data) | ||
119 | { | ||
120 | struct net_bridge *br = netdev_priv(dev); | ||
121 | |||
122 | if (data) | ||
123 | br->feature_mask |= NETIF_F_SG; | ||
124 | else | ||
125 | br->feature_mask &= ~NETIF_F_SG; | ||
126 | |||
127 | br_features_recompute(br); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static int br_set_tso(struct net_device *dev, u32 data) | ||
132 | { | ||
133 | struct net_bridge *br = netdev_priv(dev); | ||
134 | |||
135 | if (data) | ||
136 | br->feature_mask |= NETIF_F_TSO; | ||
137 | else | ||
138 | br->feature_mask &= ~NETIF_F_TSO; | ||
139 | |||
140 | br_features_recompute(br); | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static int br_set_tx_csum(struct net_device *dev, u32 data) | ||
145 | { | ||
146 | struct net_bridge *br = netdev_priv(dev); | ||
147 | |||
148 | if (data) | ||
149 | br->feature_mask |= NETIF_F_IP_CSUM; | ||
150 | else | ||
151 | br->feature_mask &= ~NETIF_F_IP_CSUM; | ||
152 | |||
153 | br_features_recompute(br); | ||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static struct ethtool_ops br_ethtool_ops = { | ||
158 | .get_drvinfo = br_getinfo, | ||
159 | .get_link = ethtool_op_get_link, | ||
160 | .get_sg = ethtool_op_get_sg, | ||
161 | .set_sg = br_set_sg, | ||
162 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
163 | .set_tx_csum = br_set_tx_csum, | ||
164 | .get_tso = ethtool_op_get_tso, | ||
165 | .set_tso = br_set_tso, | ||
166 | }; | ||
167 | |||
85 | void br_dev_setup(struct net_device *dev) | 168 | void br_dev_setup(struct net_device *dev) |
86 | { | 169 | { |
87 | memset(dev->dev_addr, 0, ETH_ALEN); | 170 | memset(dev->dev_addr, 0, ETH_ALEN); |
@@ -96,8 +179,12 @@ void br_dev_setup(struct net_device *dev) | |||
96 | dev->change_mtu = br_change_mtu; | 179 | dev->change_mtu = br_change_mtu; |
97 | dev->destructor = free_netdev; | 180 | dev->destructor = free_netdev; |
98 | SET_MODULE_OWNER(dev); | 181 | SET_MODULE_OWNER(dev); |
182 | SET_ETHTOOL_OPS(dev, &br_ethtool_ops); | ||
99 | dev->stop = br_dev_stop; | 183 | dev->stop = br_dev_stop; |
100 | dev->tx_queue_len = 0; | 184 | dev->tx_queue_len = 0; |
101 | dev->set_mac_address = NULL; | 185 | dev->set_mac_address = br_set_mac_address; |
102 | dev->priv_flags = IFF_EBRIDGE; | 186 | dev->priv_flags = IFF_EBRIDGE; |
187 | |||
188 | dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | ||
189 | | NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_IP_CSUM; | ||
103 | } | 190 | } |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 975abe254b7a..11321197338e 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -32,9 +32,8 @@ | |||
32 | * ethtool, use ethtool_ops. Also, since driver might sleep need to | 32 | * ethtool, use ethtool_ops. Also, since driver might sleep need to |
33 | * not be holding any locks. | 33 | * not be holding any locks. |
34 | */ | 34 | */ |
35 | static int br_initial_port_cost(struct net_device *dev) | 35 | static int port_cost(struct net_device *dev) |
36 | { | 36 | { |
37 | |||
38 | struct ethtool_cmd ecmd = { ETHTOOL_GSET }; | 37 | struct ethtool_cmd ecmd = { ETHTOOL_GSET }; |
39 | struct ifreq ifr; | 38 | struct ifreq ifr; |
40 | mm_segment_t old_fs; | 39 | mm_segment_t old_fs; |
@@ -58,10 +57,6 @@ static int br_initial_port_cost(struct net_device *dev) | |||
58 | return 2; | 57 | return 2; |
59 | case SPEED_10: | 58 | case SPEED_10: |
60 | return 100; | 59 | return 100; |
61 | default: | ||
62 | pr_info("bridge: can't decode speed from %s: %d\n", | ||
63 | dev->name, ecmd.speed); | ||
64 | return 100; | ||
65 | } | 60 | } |
66 | } | 61 | } |
67 | 62 | ||
@@ -75,6 +70,35 @@ static int br_initial_port_cost(struct net_device *dev) | |||
75 | return 100; /* assume old 10Mbps */ | 70 | return 100; /* assume old 10Mbps */ |
76 | } | 71 | } |
77 | 72 | ||
73 | |||
74 | /* | ||
75 | * Check for port carrier transistions. | ||
76 | * Called from work queue to allow for calling functions that | ||
77 | * might sleep (such as speed check), and to debounce. | ||
78 | */ | ||
79 | static void port_carrier_check(void *arg) | ||
80 | { | ||
81 | struct net_bridge_port *p = arg; | ||
82 | |||
83 | rtnl_lock(); | ||
84 | if (netif_carrier_ok(p->dev)) { | ||
85 | u32 cost = port_cost(p->dev); | ||
86 | |||
87 | spin_lock_bh(&p->br->lock); | ||
88 | if (p->state == BR_STATE_DISABLED) { | ||
89 | p->path_cost = cost; | ||
90 | br_stp_enable_port(p); | ||
91 | } | ||
92 | spin_unlock_bh(&p->br->lock); | ||
93 | } else { | ||
94 | spin_lock_bh(&p->br->lock); | ||
95 | if (p->state != BR_STATE_DISABLED) | ||
96 | br_stp_disable_port(p); | ||
97 | spin_unlock_bh(&p->br->lock); | ||
98 | } | ||
99 | rtnl_unlock(); | ||
100 | } | ||
101 | |||
78 | static void destroy_nbp(struct net_bridge_port *p) | 102 | static void destroy_nbp(struct net_bridge_port *p) |
79 | { | 103 | { |
80 | struct net_device *dev = p->dev; | 104 | struct net_device *dev = p->dev; |
@@ -102,6 +126,9 @@ static void del_nbp(struct net_bridge_port *p) | |||
102 | dev->br_port = NULL; | 126 | dev->br_port = NULL; |
103 | dev_set_promiscuity(dev, -1); | 127 | dev_set_promiscuity(dev, -1); |
104 | 128 | ||
129 | cancel_delayed_work(&p->carrier_check); | ||
130 | flush_scheduled_work(); | ||
131 | |||
105 | spin_lock_bh(&br->lock); | 132 | spin_lock_bh(&br->lock); |
106 | br_stp_disable_port(p); | 133 | br_stp_disable_port(p); |
107 | spin_unlock_bh(&br->lock); | 134 | spin_unlock_bh(&br->lock); |
@@ -155,6 +182,7 @@ static struct net_device *new_bridge_dev(const char *name) | |||
155 | br->bridge_id.prio[1] = 0x00; | 182 | br->bridge_id.prio[1] = 0x00; |
156 | memset(br->bridge_id.addr, 0, ETH_ALEN); | 183 | memset(br->bridge_id.addr, 0, ETH_ALEN); |
157 | 184 | ||
185 | br->feature_mask = dev->features; | ||
158 | br->stp_enabled = 0; | 186 | br->stp_enabled = 0; |
159 | br->designated_root = br->bridge_id; | 187 | br->designated_root = br->bridge_id; |
160 | br->root_path_cost = 0; | 188 | br->root_path_cost = 0; |
@@ -195,10 +223,9 @@ static int find_portno(struct net_bridge *br) | |||
195 | return (index >= BR_MAX_PORTS) ? -EXFULL : index; | 223 | return (index >= BR_MAX_PORTS) ? -EXFULL : index; |
196 | } | 224 | } |
197 | 225 | ||
198 | /* called with RTNL */ | 226 | /* called with RTNL but without bridge lock */ |
199 | static struct net_bridge_port *new_nbp(struct net_bridge *br, | 227 | static struct net_bridge_port *new_nbp(struct net_bridge *br, |
200 | struct net_device *dev, | 228 | struct net_device *dev) |
201 | unsigned long cost) | ||
202 | { | 229 | { |
203 | int index; | 230 | int index; |
204 | struct net_bridge_port *p; | 231 | struct net_bridge_port *p; |
@@ -215,12 +242,13 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, | |||
215 | p->br = br; | 242 | p->br = br; |
216 | dev_hold(dev); | 243 | dev_hold(dev); |
217 | p->dev = dev; | 244 | p->dev = dev; |
218 | p->path_cost = cost; | 245 | p->path_cost = port_cost(dev); |
219 | p->priority = 0x8000 >> BR_PORT_BITS; | 246 | p->priority = 0x8000 >> BR_PORT_BITS; |
220 | dev->br_port = p; | 247 | dev->br_port = p; |
221 | p->port_no = index; | 248 | p->port_no = index; |
222 | br_init_port(p); | 249 | br_init_port(p); |
223 | p->state = BR_STATE_DISABLED; | 250 | p->state = BR_STATE_DISABLED; |
251 | INIT_WORK(&p->carrier_check, port_carrier_check, p); | ||
224 | kobject_init(&p->kobj); | 252 | kobject_init(&p->kobj); |
225 | 253 | ||
226 | return p; | 254 | return p; |
@@ -322,9 +350,8 @@ void br_features_recompute(struct net_bridge *br) | |||
322 | struct net_bridge_port *p; | 350 | struct net_bridge_port *p; |
323 | unsigned long features, checksum; | 351 | unsigned long features, checksum; |
324 | 352 | ||
325 | features = NETIF_F_SG | NETIF_F_FRAGLIST | 353 | features = br->feature_mask &~ NETIF_F_IP_CSUM; |
326 | | NETIF_F_HIGHDMA | NETIF_F_TSO; | 354 | checksum = br->feature_mask & NETIF_F_IP_CSUM; |
327 | checksum = NETIF_F_IP_CSUM; /* least commmon subset */ | ||
328 | 355 | ||
329 | list_for_each_entry(p, &br->port_list, list) { | 356 | list_for_each_entry(p, &br->port_list, list) { |
330 | if (!(p->dev->features | 357 | if (!(p->dev->features |
@@ -351,7 +378,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
351 | if (dev->br_port != NULL) | 378 | if (dev->br_port != NULL) |
352 | return -EBUSY; | 379 | return -EBUSY; |
353 | 380 | ||
354 | if (IS_ERR(p = new_nbp(br, dev, br_initial_port_cost(dev)))) | 381 | if (IS_ERR(p = new_nbp(br, dev))) |
355 | return PTR_ERR(p); | 382 | return PTR_ERR(p); |
356 | 383 | ||
357 | if ((err = br_fdb_insert(br, p, dev->dev_addr))) | 384 | if ((err = br_fdb_insert(br, p, dev->dev_addr))) |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index b88220a64cd8..c387852f753a 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -53,6 +53,11 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
53 | /* insert into forwarding database after filtering to avoid spoofing */ | 53 | /* insert into forwarding database after filtering to avoid spoofing */ |
54 | br_fdb_update(p->br, p, eth_hdr(skb)->h_source); | 54 | br_fdb_update(p->br, p, eth_hdr(skb)->h_source); |
55 | 55 | ||
56 | if (p->state == BR_STATE_LEARNING) { | ||
57 | kfree_skb(skb); | ||
58 | goto out; | ||
59 | } | ||
60 | |||
56 | if (br->dev->flags & IFF_PROMISC) { | 61 | if (br->dev->flags & IFF_PROMISC) { |
57 | struct sk_buff *skb2; | 62 | struct sk_buff *skb2; |
58 | 63 | ||
@@ -107,9 +112,6 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb) | |||
107 | if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) | 112 | if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) |
108 | goto err; | 113 | goto err; |
109 | 114 | ||
110 | if (p->state == BR_STATE_LEARNING) | ||
111 | br_fdb_update(p->br, p, eth_hdr(skb)->h_source); | ||
112 | |||
113 | if (p->br->stp_enabled && | 115 | if (p->br->stp_enabled && |
114 | !memcmp(dest, bridge_ula, 5) && | 116 | !memcmp(dest, bridge_ula, 5) && |
115 | !(dest[5] & 0xF0)) { | 117 | !(dest[5] & 0xF0)) { |
@@ -118,9 +120,10 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb) | |||
118 | NULL, br_stp_handle_bpdu); | 120 | NULL, br_stp_handle_bpdu); |
119 | return 1; | 121 | return 1; |
120 | } | 122 | } |
123 | goto err; | ||
121 | } | 124 | } |
122 | 125 | ||
123 | else if (p->state == BR_STATE_FORWARDING) { | 126 | if (p->state == BR_STATE_FORWARDING || p->state == BR_STATE_LEARNING) { |
124 | if (br_should_route_hook) { | 127 | if (br_should_route_hook) { |
125 | if (br_should_route_hook(pskb)) | 128 | if (br_should_route_hook(pskb)) |
126 | return 0; | 129 | return 0; |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index d8e36b775125..223f8270daee 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/ip.h> | 26 | #include <linux/ip.h> |
27 | #include <linux/netdevice.h> | 27 | #include <linux/netdevice.h> |
28 | #include <linux/skbuff.h> | 28 | #include <linux/skbuff.h> |
29 | #include <linux/if_arp.h> | ||
29 | #include <linux/if_ether.h> | 30 | #include <linux/if_ether.h> |
30 | #include <linux/if_vlan.h> | 31 | #include <linux/if_vlan.h> |
31 | #include <linux/netfilter_bridge.h> | 32 | #include <linux/netfilter_bridge.h> |
@@ -33,8 +34,11 @@ | |||
33 | #include <linux/netfilter_ipv6.h> | 34 | #include <linux/netfilter_ipv6.h> |
34 | #include <linux/netfilter_arp.h> | 35 | #include <linux/netfilter_arp.h> |
35 | #include <linux/in_route.h> | 36 | #include <linux/in_route.h> |
37 | |||
36 | #include <net/ip.h> | 38 | #include <net/ip.h> |
37 | #include <net/ipv6.h> | 39 | #include <net/ipv6.h> |
40 | #include <net/route.h> | ||
41 | |||
38 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
39 | #include <asm/checksum.h> | 43 | #include <asm/checksum.h> |
40 | #include "br_private.h" | 44 | #include "br_private.h" |
@@ -295,7 +299,7 @@ static int check_hbh_len(struct sk_buff *skb) | |||
295 | len -= 2; | 299 | len -= 2; |
296 | 300 | ||
297 | while (len > 0) { | 301 | while (len > 0) { |
298 | int optlen = raw[off+1]+2; | 302 | int optlen = skb->nh.raw[off+1]+2; |
299 | 303 | ||
300 | switch (skb->nh.raw[off]) { | 304 | switch (skb->nh.raw[off]) { |
301 | case IPV6_TLV_PAD0: | 305 | case IPV6_TLV_PAD0: |
@@ -308,18 +312,15 @@ static int check_hbh_len(struct sk_buff *skb) | |||
308 | case IPV6_TLV_JUMBO: | 312 | case IPV6_TLV_JUMBO: |
309 | if (skb->nh.raw[off+1] != 4 || (off&3) != 2) | 313 | if (skb->nh.raw[off+1] != 4 || (off&3) != 2) |
310 | goto bad; | 314 | goto bad; |
311 | |||
312 | pkt_len = ntohl(*(u32*)(skb->nh.raw+off+2)); | 315 | pkt_len = ntohl(*(u32*)(skb->nh.raw+off+2)); |
313 | 316 | if (pkt_len <= IPV6_MAXPLEN || | |
317 | skb->nh.ipv6h->payload_len) | ||
318 | goto bad; | ||
314 | if (pkt_len > skb->len - sizeof(struct ipv6hdr)) | 319 | if (pkt_len > skb->len - sizeof(struct ipv6hdr)) |
315 | goto bad; | 320 | goto bad; |
316 | if (pkt_len + sizeof(struct ipv6hdr) < skb->len) { | 321 | if (pskb_trim_rcsum(skb, |
317 | if (__pskb_trim(skb, | 322 | pkt_len+sizeof(struct ipv6hdr))) |
318 | pkt_len + sizeof(struct ipv6hdr))) | 323 | goto bad; |
319 | goto bad; | ||
320 | if (skb->ip_summed == CHECKSUM_HW) | ||
321 | skb->ip_summed = CHECKSUM_NONE; | ||
322 | } | ||
323 | break; | 324 | break; |
324 | default: | 325 | default: |
325 | if (optlen > len) | 326 | if (optlen > len) |
@@ -372,6 +373,7 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook, | |||
372 | if (hdr->nexthdr == NEXTHDR_HOP && check_hbh_len(skb)) | 373 | if (hdr->nexthdr == NEXTHDR_HOP && check_hbh_len(skb)) |
373 | goto inhdr_error; | 374 | goto inhdr_error; |
374 | 375 | ||
376 | nf_bridge_put(skb->nf_bridge); | ||
375 | if ((nf_bridge = nf_bridge_alloc(skb)) == NULL) | 377 | if ((nf_bridge = nf_bridge_alloc(skb)) == NULL) |
376 | return NF_DROP; | 378 | return NF_DROP; |
377 | setup_pre_routing(skb); | 379 | setup_pre_routing(skb); |
@@ -455,6 +457,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, | |||
455 | skb->ip_summed = CHECKSUM_NONE; | 457 | skb->ip_summed = CHECKSUM_NONE; |
456 | } | 458 | } |
457 | 459 | ||
460 | nf_bridge_put(skb->nf_bridge); | ||
458 | if ((nf_bridge = nf_bridge_alloc(skb)) == NULL) | 461 | if ((nf_bridge = nf_bridge_alloc(skb)) == NULL) |
459 | return NF_DROP; | 462 | return NF_DROP; |
460 | setup_pre_routing(skb); | 463 | setup_pre_routing(skb); |
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c index 917311c6828b..a43a9c1d50d7 100644 --- a/net/bridge/br_notify.c +++ b/net/bridge/br_notify.c | |||
@@ -52,17 +52,9 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v | |||
52 | br_stp_recalculate_bridge_id(br); | 52 | br_stp_recalculate_bridge_id(br); |
53 | break; | 53 | break; |
54 | 54 | ||
55 | case NETDEV_CHANGE: /* device is up but carrier changed */ | 55 | case NETDEV_CHANGE: |
56 | if (!(br->dev->flags & IFF_UP)) | 56 | if (br->dev->flags & IFF_UP) |
57 | break; | 57 | schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE); |
58 | |||
59 | if (netif_carrier_ok(dev)) { | ||
60 | if (p->state == BR_STATE_DISABLED) | ||
61 | br_stp_enable_port(p); | ||
62 | } else { | ||
63 | if (p->state != BR_STATE_DISABLED) | ||
64 | br_stp_disable_port(p); | ||
65 | } | ||
66 | break; | 58 | break; |
67 | 59 | ||
68 | case NETDEV_FEAT_CHANGE: | 60 | case NETDEV_FEAT_CHANGE: |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index bdf95a74d8cd..c5bd631ffcd5 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -27,6 +27,10 @@ | |||
27 | #define BR_PORT_BITS 10 | 27 | #define BR_PORT_BITS 10 |
28 | #define BR_MAX_PORTS (1<<BR_PORT_BITS) | 28 | #define BR_MAX_PORTS (1<<BR_PORT_BITS) |
29 | 29 | ||
30 | #define BR_PORT_DEBOUNCE (HZ/10) | ||
31 | |||
32 | #define BR_VERSION "2.1" | ||
33 | |||
30 | typedef struct bridge_id bridge_id; | 34 | typedef struct bridge_id bridge_id; |
31 | typedef struct mac_addr mac_addr; | 35 | typedef struct mac_addr mac_addr; |
32 | typedef __u16 port_id; | 36 | typedef __u16 port_id; |
@@ -78,6 +82,7 @@ struct net_bridge_port | |||
78 | struct timer_list hold_timer; | 82 | struct timer_list hold_timer; |
79 | struct timer_list message_age_timer; | 83 | struct timer_list message_age_timer; |
80 | struct kobject kobj; | 84 | struct kobject kobj; |
85 | struct work_struct carrier_check; | ||
81 | struct rcu_head rcu; | 86 | struct rcu_head rcu; |
82 | }; | 87 | }; |
83 | 88 | ||
@@ -90,6 +95,7 @@ struct net_bridge | |||
90 | spinlock_t hash_lock; | 95 | spinlock_t hash_lock; |
91 | struct hlist_head hash[BR_HASH_SIZE]; | 96 | struct hlist_head hash[BR_HASH_SIZE]; |
92 | struct list_head age_list; | 97 | struct list_head age_list; |
98 | unsigned long feature_mask; | ||
93 | 99 | ||
94 | /* STP */ | 100 | /* STP */ |
95 | bridge_id designated_root; | 101 | bridge_id designated_root; |
@@ -201,6 +207,7 @@ extern void br_stp_disable_bridge(struct net_bridge *br); | |||
201 | extern void br_stp_enable_port(struct net_bridge_port *p); | 207 | extern void br_stp_enable_port(struct net_bridge_port *p); |
202 | extern void br_stp_disable_port(struct net_bridge_port *p); | 208 | extern void br_stp_disable_port(struct net_bridge_port *p); |
203 | extern void br_stp_recalculate_bridge_id(struct net_bridge *br); | 209 | extern void br_stp_recalculate_bridge_id(struct net_bridge *br); |
210 | extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a); | ||
204 | extern void br_stp_set_bridge_priority(struct net_bridge *br, | 211 | extern void br_stp_set_bridge_priority(struct net_bridge *br, |
205 | u16 newprio); | 212 | u16 newprio); |
206 | extern void br_stp_set_port_priority(struct net_bridge_port *p, | 213 | extern void br_stp_set_port_priority(struct net_bridge_port *p, |
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index ac09b6a23523..cc047f7fb6ef 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c | |||
@@ -120,8 +120,7 @@ void br_stp_disable_port(struct net_bridge_port *p) | |||
120 | } | 120 | } |
121 | 121 | ||
122 | /* called under bridge lock */ | 122 | /* called under bridge lock */ |
123 | static void br_stp_change_bridge_id(struct net_bridge *br, | 123 | void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr) |
124 | const unsigned char *addr) | ||
125 | { | 124 | { |
126 | unsigned char oldaddr[6]; | 125 | unsigned char oldaddr[6]; |
127 | struct net_bridge_port *p; | 126 | struct net_bridge_port *p; |
@@ -158,7 +157,7 @@ void br_stp_recalculate_bridge_id(struct net_bridge *br) | |||
158 | 157 | ||
159 | list_for_each_entry(p, &br->port_list, list) { | 158 | list_for_each_entry(p, &br->port_list, list) { |
160 | if (addr == br_mac_zero || | 159 | if (addr == br_mac_zero || |
161 | compare_ether_addr(p->dev->dev_addr, addr) < 0) | 160 | memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0) |
162 | addr = p->dev->dev_addr; | 161 | addr = p->dev->dev_addr; |
163 | 162 | ||
164 | } | 163 | } |
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig index c70b3be23026..b84fc6075fe1 100644 --- a/net/bridge/netfilter/Kconfig +++ b/net/bridge/netfilter/Kconfig | |||
@@ -196,9 +196,13 @@ config BRIDGE_EBT_LOG | |||
196 | To compile it as a module, choose M here. If unsure, say N. | 196 | To compile it as a module, choose M here. If unsure, say N. |
197 | 197 | ||
198 | config BRIDGE_EBT_ULOG | 198 | config BRIDGE_EBT_ULOG |
199 | tristate "ebt: ulog support" | 199 | tristate "ebt: ulog support (OBSOLETE)" |
200 | depends on BRIDGE_NF_EBTABLES | 200 | depends on BRIDGE_NF_EBTABLES |
201 | help | 201 | help |
202 | This option enables the old bridge-specific "ebt_ulog" implementation | ||
203 | which has been obsoleted by the new "nfnetlink_log" code (see | ||
204 | CONFIG_NETFILTER_NETLINK_LOG). | ||
205 | |||
202 | This option adds the ulog watcher, that you can use in any rule | 206 | This option adds the ulog watcher, that you can use in any rule |
203 | in any ebtables table. The packet is passed to a userspace | 207 | in any ebtables table. The packet is passed to a userspace |
204 | logging daemon using netlink multicast sockets. This differs | 208 | logging daemon using netlink multicast sockets. This differs |
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index 662975be3d1d..9f6e0193ae10 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c | |||
@@ -3,13 +3,16 @@ | |||
3 | * | 3 | * |
4 | * Authors: | 4 | * Authors: |
5 | * Bart De Schuymer <bdschuym@pandora.be> | 5 | * Bart De Schuymer <bdschuym@pandora.be> |
6 | * Harald Welte <laforge@netfilter.org> | ||
6 | * | 7 | * |
7 | * April, 2002 | 8 | * April, 2002 |
8 | * | 9 | * |
9 | */ | 10 | */ |
10 | 11 | ||
12 | #include <linux/in.h> | ||
11 | #include <linux/netfilter_bridge/ebtables.h> | 13 | #include <linux/netfilter_bridge/ebtables.h> |
12 | #include <linux/netfilter_bridge/ebt_log.h> | 14 | #include <linux/netfilter_bridge/ebt_log.h> |
15 | #include <linux/netfilter.h> | ||
13 | #include <linux/module.h> | 16 | #include <linux/module.h> |
14 | #include <linux/ip.h> | 17 | #include <linux/ip.h> |
15 | #include <linux/if_arp.h> | 18 | #include <linux/if_arp.h> |
@@ -55,27 +58,30 @@ static void print_MAC(unsigned char *p) | |||
55 | } | 58 | } |
56 | 59 | ||
57 | #define myNIPQUAD(a) a[0], a[1], a[2], a[3] | 60 | #define myNIPQUAD(a) a[0], a[1], a[2], a[3] |
58 | static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | 61 | static void |
59 | const struct net_device *in, const struct net_device *out, | 62 | ebt_log_packet(unsigned int pf, unsigned int hooknum, |
60 | const void *data, unsigned int datalen) | 63 | const struct sk_buff *skb, const struct net_device *in, |
64 | const struct net_device *out, const struct nf_loginfo *loginfo, | ||
65 | const char *prefix) | ||
61 | { | 66 | { |
62 | struct ebt_log_info *info = (struct ebt_log_info *)data; | 67 | unsigned int bitmask; |
63 | char level_string[4] = "< >"; | ||
64 | 68 | ||
65 | level_string[1] = '0' + info->loglevel; | ||
66 | spin_lock_bh(&ebt_log_lock); | 69 | spin_lock_bh(&ebt_log_lock); |
67 | printk(level_string); | 70 | printk("<%c>%s IN=%s OUT=%s MAC source = ", '0' + loginfo->u.log.level, |
68 | printk("%s IN=%s OUT=%s ", info->prefix, in ? in->name : "", | 71 | prefix, in ? in->name : "", out ? out->name : ""); |
69 | out ? out->name : ""); | ||
70 | 72 | ||
71 | printk("MAC source = "); | ||
72 | print_MAC(eth_hdr(skb)->h_source); | 73 | print_MAC(eth_hdr(skb)->h_source); |
73 | printk("MAC dest = "); | 74 | printk("MAC dest = "); |
74 | print_MAC(eth_hdr(skb)->h_dest); | 75 | print_MAC(eth_hdr(skb)->h_dest); |
75 | 76 | ||
76 | printk("proto = 0x%04x", ntohs(eth_hdr(skb)->h_proto)); | 77 | printk("proto = 0x%04x", ntohs(eth_hdr(skb)->h_proto)); |
77 | 78 | ||
78 | if ((info->bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto == | 79 | if (loginfo->type == NF_LOG_TYPE_LOG) |
80 | bitmask = loginfo->u.log.logflags; | ||
81 | else | ||
82 | bitmask = NF_LOG_MASK; | ||
83 | |||
84 | if ((bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto == | ||
79 | htons(ETH_P_IP)){ | 85 | htons(ETH_P_IP)){ |
80 | struct iphdr _iph, *ih; | 86 | struct iphdr _iph, *ih; |
81 | 87 | ||
@@ -84,10 +90,9 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | |||
84 | printk(" INCOMPLETE IP header"); | 90 | printk(" INCOMPLETE IP header"); |
85 | goto out; | 91 | goto out; |
86 | } | 92 | } |
87 | printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,", | 93 | printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u, IP " |
88 | NIPQUAD(ih->saddr), NIPQUAD(ih->daddr)); | 94 | "tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr), |
89 | printk(" IP tos=0x%02X, IP proto=%d", ih->tos, | 95 | NIPQUAD(ih->daddr), ih->tos, ih->protocol); |
90 | ih->protocol); | ||
91 | if (ih->protocol == IPPROTO_TCP || | 96 | if (ih->protocol == IPPROTO_TCP || |
92 | ih->protocol == IPPROTO_UDP) { | 97 | ih->protocol == IPPROTO_UDP) { |
93 | struct tcpudphdr _ports, *pptr; | 98 | struct tcpudphdr _ports, *pptr; |
@@ -104,7 +109,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | |||
104 | goto out; | 109 | goto out; |
105 | } | 110 | } |
106 | 111 | ||
107 | if ((info->bitmask & EBT_LOG_ARP) && | 112 | if ((bitmask & EBT_LOG_ARP) && |
108 | ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) || | 113 | ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) || |
109 | (eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) { | 114 | (eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) { |
110 | struct arphdr _arph, *ah; | 115 | struct arphdr _arph, *ah; |
@@ -144,6 +149,21 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | |||
144 | out: | 149 | out: |
145 | printk("\n"); | 150 | printk("\n"); |
146 | spin_unlock_bh(&ebt_log_lock); | 151 | spin_unlock_bh(&ebt_log_lock); |
152 | |||
153 | } | ||
154 | |||
155 | static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, | ||
156 | const struct net_device *in, const struct net_device *out, | ||
157 | const void *data, unsigned int datalen) | ||
158 | { | ||
159 | struct ebt_log_info *info = (struct ebt_log_info *)data; | ||
160 | struct nf_loginfo li; | ||
161 | |||
162 | li.type = NF_LOG_TYPE_LOG; | ||
163 | li.u.log.level = info->loglevel; | ||
164 | li.u.log.logflags = info->bitmask; | ||
165 | |||
166 | nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, info->prefix); | ||
147 | } | 167 | } |
148 | 168 | ||
149 | static struct ebt_watcher log = | 169 | static struct ebt_watcher log = |
@@ -154,13 +174,32 @@ static struct ebt_watcher log = | |||
154 | .me = THIS_MODULE, | 174 | .me = THIS_MODULE, |
155 | }; | 175 | }; |
156 | 176 | ||
177 | static struct nf_logger ebt_log_logger = { | ||
178 | .name = "ebt_log", | ||
179 | .logfn = &ebt_log_packet, | ||
180 | .me = THIS_MODULE, | ||
181 | }; | ||
182 | |||
157 | static int __init init(void) | 183 | static int __init init(void) |
158 | { | 184 | { |
159 | return ebt_register_watcher(&log); | 185 | int ret; |
186 | |||
187 | ret = ebt_register_watcher(&log); | ||
188 | if (ret < 0) | ||
189 | return ret; | ||
190 | if (nf_log_register(PF_BRIDGE, &ebt_log_logger) < 0) { | ||
191 | printk(KERN_WARNING "ebt_log: not logging via system console " | ||
192 | "since somebody else already registered for PF_INET\n"); | ||
193 | /* we cannot make module load fail here, since otherwise | ||
194 | * ebtables userspace would abort */ | ||
195 | } | ||
196 | |||
197 | return 0; | ||
160 | } | 198 | } |
161 | 199 | ||
162 | static void __exit fini(void) | 200 | static void __exit fini(void) |
163 | { | 201 | { |
202 | nf_log_unregister_logger(&ebt_log_logger); | ||
164 | ebt_unregister_watcher(&log); | 203 | ebt_unregister_watcher(&log); |
165 | } | 204 | } |
166 | 205 | ||
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index aae26ae2e61f..ce617b3dbbb8 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Authors: | 4 | * Authors: |
5 | * Bart De Schuymer <bdschuym@pandora.be> | 5 | * Bart De Schuymer <bdschuym@pandora.be> |
6 | * Harald Welte <laforge@netfilter.org> | ||
6 | * | 7 | * |
7 | * November, 2004 | 8 | * November, 2004 |
8 | * | 9 | * |
@@ -115,14 +116,13 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size) | |||
115 | return skb; | 116 | return skb; |
116 | } | 117 | } |
117 | 118 | ||
118 | static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr, | 119 | static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb, |
119 | const struct net_device *in, const struct net_device *out, | 120 | const struct net_device *in, const struct net_device *out, |
120 | const void *data, unsigned int datalen) | 121 | const struct ebt_ulog_info *uloginfo, const char *prefix) |
121 | { | 122 | { |
122 | ebt_ulog_packet_msg_t *pm; | 123 | ebt_ulog_packet_msg_t *pm; |
123 | size_t size, copy_len; | 124 | size_t size, copy_len; |
124 | struct nlmsghdr *nlh; | 125 | struct nlmsghdr *nlh; |
125 | struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data; | ||
126 | unsigned int group = uloginfo->nlgroup; | 126 | unsigned int group = uloginfo->nlgroup; |
127 | ebt_ulog_buff_t *ub = &ulog_buffers[group]; | 127 | ebt_ulog_buff_t *ub = &ulog_buffers[group]; |
128 | spinlock_t *lock = &ub->lock; | 128 | spinlock_t *lock = &ub->lock; |
@@ -216,6 +216,39 @@ alloc_failure: | |||
216 | goto unlock; | 216 | goto unlock; |
217 | } | 217 | } |
218 | 218 | ||
219 | /* this function is registered with the netfilter core */ | ||
220 | static void ebt_log_packet(unsigned int pf, unsigned int hooknum, | ||
221 | const struct sk_buff *skb, const struct net_device *in, | ||
222 | const struct net_device *out, const struct nf_loginfo *li, | ||
223 | const char *prefix) | ||
224 | { | ||
225 | struct ebt_ulog_info loginfo; | ||
226 | |||
227 | if (!li || li->type != NF_LOG_TYPE_ULOG) { | ||
228 | loginfo.nlgroup = EBT_ULOG_DEFAULT_NLGROUP; | ||
229 | loginfo.cprange = 0; | ||
230 | loginfo.qthreshold = EBT_ULOG_DEFAULT_QTHRESHOLD; | ||
231 | loginfo.prefix[0] = '\0'; | ||
232 | } else { | ||
233 | loginfo.nlgroup = li->u.ulog.group; | ||
234 | loginfo.cprange = li->u.ulog.copy_len; | ||
235 | loginfo.qthreshold = li->u.ulog.qthreshold; | ||
236 | strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix)); | ||
237 | } | ||
238 | |||
239 | ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); | ||
240 | } | ||
241 | |||
242 | static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr, | ||
243 | const struct net_device *in, const struct net_device *out, | ||
244 | const void *data, unsigned int datalen) | ||
245 | { | ||
246 | struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data; | ||
247 | |||
248 | ebt_ulog_packet(hooknr, skb, in, out, uloginfo, NULL); | ||
249 | } | ||
250 | |||
251 | |||
219 | static int ebt_ulog_check(const char *tablename, unsigned int hookmask, | 252 | static int ebt_ulog_check(const char *tablename, unsigned int hookmask, |
220 | const struct ebt_entry *e, void *data, unsigned int datalen) | 253 | const struct ebt_entry *e, void *data, unsigned int datalen) |
221 | { | 254 | { |
@@ -240,6 +273,12 @@ static struct ebt_watcher ulog = { | |||
240 | .me = THIS_MODULE, | 273 | .me = THIS_MODULE, |
241 | }; | 274 | }; |
242 | 275 | ||
276 | static struct nf_logger ebt_ulog_logger = { | ||
277 | .name = EBT_ULOG_WATCHER, | ||
278 | .logfn = &ebt_log_packet, | ||
279 | .me = THIS_MODULE, | ||
280 | }; | ||
281 | |||
243 | static int __init init(void) | 282 | static int __init init(void) |
244 | { | 283 | { |
245 | int i, ret = 0; | 284 | int i, ret = 0; |
@@ -265,6 +304,13 @@ static int __init init(void) | |||
265 | else if ((ret = ebt_register_watcher(&ulog))) | 304 | else if ((ret = ebt_register_watcher(&ulog))) |
266 | sock_release(ebtulognl->sk_socket); | 305 | sock_release(ebtulognl->sk_socket); |
267 | 306 | ||
307 | if (nf_log_register(PF_BRIDGE, &ebt_ulog_logger) < 0) { | ||
308 | printk(KERN_WARNING "ebt_ulog: not logging via ulog " | ||
309 | "since somebody else already registered for PF_BRIDGE\n"); | ||
310 | /* we cannot make module load fail here, since otherwise | ||
311 | * ebtables userspace would abort */ | ||
312 | } | ||
313 | |||
268 | return ret; | 314 | return ret; |
269 | } | 315 | } |
270 | 316 | ||
@@ -273,6 +319,7 @@ static void __exit fini(void) | |||
273 | ebt_ulog_buff_t *ub; | 319 | ebt_ulog_buff_t *ub; |
274 | int i; | 320 | int i; |
275 | 321 | ||
322 | nf_log_unregister_logger(&ebt_ulog_logger); | ||
276 | ebt_unregister_watcher(&ulog); | 323 | ebt_unregister_watcher(&ulog); |
277 | for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) { | 324 | for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) { |
278 | ub = &ulog_buffers[i]; | 325 | ub = &ulog_buffers[i]; |
diff --git a/net/core/datagram.c b/net/core/datagram.c index 1bcfef51ac58..f8d322e1ea92 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/rtnetlink.h> | 47 | #include <linux/rtnetlink.h> |
48 | #include <linux/poll.h> | 48 | #include <linux/poll.h> |
49 | #include <linux/highmem.h> | 49 | #include <linux/highmem.h> |
50 | #include <linux/spinlock.h> | ||
50 | 51 | ||
51 | #include <net/protocol.h> | 52 | #include <net/protocol.h> |
52 | #include <linux/skbuff.h> | 53 | #include <linux/skbuff.h> |
@@ -200,6 +201,41 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb) | |||
200 | } | 201 | } |
201 | 202 | ||
202 | /** | 203 | /** |
204 | * skb_kill_datagram - Free a datagram skbuff forcibly | ||
205 | * @sk: socket | ||
206 | * @skb: datagram skbuff | ||
207 | * @flags: MSG_ flags | ||
208 | * | ||
209 | * This function frees a datagram skbuff that was received by | ||
210 | * skb_recv_datagram. The flags argument must match the one | ||
211 | * used for skb_recv_datagram. | ||
212 | * | ||
213 | * If the MSG_PEEK flag is set, and the packet is still on the | ||
214 | * receive queue of the socket, it will be taken off the queue | ||
215 | * before it is freed. | ||
216 | * | ||
217 | * This function currently only disables BH when acquiring the | ||
218 | * sk_receive_queue lock. Therefore it must not be used in a | ||
219 | * context where that lock is acquired in an IRQ context. | ||
220 | */ | ||
221 | |||
222 | void skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags) | ||
223 | { | ||
224 | if (flags & MSG_PEEK) { | ||
225 | spin_lock_bh(&sk->sk_receive_queue.lock); | ||
226 | if (skb == skb_peek(&sk->sk_receive_queue)) { | ||
227 | __skb_unlink(skb, &sk->sk_receive_queue); | ||
228 | atomic_dec(&skb->users); | ||
229 | } | ||
230 | spin_unlock_bh(&sk->sk_receive_queue.lock); | ||
231 | } | ||
232 | |||
233 | kfree_skb(skb); | ||
234 | } | ||
235 | |||
236 | EXPORT_SYMBOL(skb_kill_datagram); | ||
237 | |||
238 | /** | ||
203 | * skb_copy_datagram_iovec - Copy a datagram to an iovec. | 239 | * skb_copy_datagram_iovec - Copy a datagram to an iovec. |
204 | * @skb: buffer to copy | 240 | * @skb: buffer to copy |
205 | * @offset: offset in the buffer to start copying from | 241 | * @offset: offset in the buffer to start copying from |
diff --git a/net/core/dev.c b/net/core/dev.c index a5efc9ae010b..29ba109d3e54 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3276,7 +3276,6 @@ EXPORT_SYMBOL(dev_close); | |||
3276 | EXPORT_SYMBOL(dev_get_by_flags); | 3276 | EXPORT_SYMBOL(dev_get_by_flags); |
3277 | EXPORT_SYMBOL(dev_get_by_index); | 3277 | EXPORT_SYMBOL(dev_get_by_index); |
3278 | EXPORT_SYMBOL(dev_get_by_name); | 3278 | EXPORT_SYMBOL(dev_get_by_name); |
3279 | EXPORT_SYMBOL(dev_ioctl); | ||
3280 | EXPORT_SYMBOL(dev_open); | 3279 | EXPORT_SYMBOL(dev_open); |
3281 | EXPORT_SYMBOL(dev_queue_xmit); | 3280 | EXPORT_SYMBOL(dev_queue_xmit); |
3282 | EXPORT_SYMBOL(dev_remove_pack); | 3281 | EXPORT_SYMBOL(dev_remove_pack); |
diff --git a/net/core/filter.c b/net/core/filter.c index 2841bfce29d6..8964d3445588 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -13,6 +13,7 @@ | |||
13 | * 2 of the License, or (at your option) any later version. | 13 | * 2 of the License, or (at your option) any later version. |
14 | * | 14 | * |
15 | * Andi Kleen - Fix a few bad bugs and races. | 15 | * Andi Kleen - Fix a few bad bugs and races. |
16 | * Kris Katterjohn - Added many additional checks in sk_chk_filter() | ||
16 | */ | 17 | */ |
17 | 18 | ||
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
@@ -250,7 +251,7 @@ load_b: | |||
250 | mem[fentry->k] = X; | 251 | mem[fentry->k] = X; |
251 | continue; | 252 | continue; |
252 | default: | 253 | default: |
253 | /* Invalid instruction counts as RET */ | 254 | WARN_ON(1); |
254 | return 0; | 255 | return 0; |
255 | } | 256 | } |
256 | 257 | ||
@@ -283,8 +284,8 @@ load_b: | |||
283 | * | 284 | * |
284 | * Check the user's filter code. If we let some ugly | 285 | * Check the user's filter code. If we let some ugly |
285 | * filter code slip through kaboom! The filter must contain | 286 | * filter code slip through kaboom! The filter must contain |
286 | * no references or jumps that are out of range, no illegal instructions | 287 | * no references or jumps that are out of range, no illegal |
287 | * and no backward jumps. It must end with a RET instruction | 288 | * instructions, and must end with a RET instruction. |
288 | * | 289 | * |
289 | * Returns 0 if the rule set is legal or a negative errno code if not. | 290 | * Returns 0 if the rule set is legal or a negative errno code if not. |
290 | */ | 291 | */ |
@@ -293,45 +294,92 @@ int sk_chk_filter(struct sock_filter *filter, int flen) | |||
293 | struct sock_filter *ftest; | 294 | struct sock_filter *ftest; |
294 | int pc; | 295 | int pc; |
295 | 296 | ||
296 | if (((unsigned int)flen >= (~0U / sizeof(struct sock_filter))) || flen == 0) | 297 | if (flen == 0 || flen > BPF_MAXINSNS) |
297 | return -EINVAL; | 298 | return -EINVAL; |
298 | 299 | ||
299 | /* check the filter code now */ | 300 | /* check the filter code now */ |
300 | for (pc = 0; pc < flen; pc++) { | 301 | for (pc = 0; pc < flen; pc++) { |
301 | /* all jumps are forward as they are not signed */ | 302 | /* all jumps are forward as they are not signed */ |
302 | ftest = &filter[pc]; | 303 | ftest = &filter[pc]; |
303 | if (BPF_CLASS(ftest->code) == BPF_JMP) { | ||
304 | /* but they mustn't jump off the end */ | ||
305 | if (BPF_OP(ftest->code) == BPF_JA) { | ||
306 | /* | ||
307 | * Note, the large ftest->k might cause loops. | ||
308 | * Compare this with conditional jumps below, | ||
309 | * where offsets are limited. --ANK (981016) | ||
310 | */ | ||
311 | if (ftest->k >= (unsigned)(flen-pc-1)) | ||
312 | return -EINVAL; | ||
313 | } else { | ||
314 | /* for conditionals both must be safe */ | ||
315 | if (pc + ftest->jt +1 >= flen || | ||
316 | pc + ftest->jf +1 >= flen) | ||
317 | return -EINVAL; | ||
318 | } | ||
319 | } | ||
320 | 304 | ||
321 | /* check for division by zero -Kris Katterjohn 2005-10-30 */ | 305 | /* Only allow valid instructions */ |
322 | if (ftest->code == (BPF_ALU|BPF_DIV|BPF_K) && ftest->k == 0) | 306 | switch (ftest->code) { |
323 | return -EINVAL; | 307 | case BPF_ALU|BPF_ADD|BPF_K: |
308 | case BPF_ALU|BPF_ADD|BPF_X: | ||
309 | case BPF_ALU|BPF_SUB|BPF_K: | ||
310 | case BPF_ALU|BPF_SUB|BPF_X: | ||
311 | case BPF_ALU|BPF_MUL|BPF_K: | ||
312 | case BPF_ALU|BPF_MUL|BPF_X: | ||
313 | case BPF_ALU|BPF_DIV|BPF_X: | ||
314 | case BPF_ALU|BPF_AND|BPF_K: | ||
315 | case BPF_ALU|BPF_AND|BPF_X: | ||
316 | case BPF_ALU|BPF_OR|BPF_K: | ||
317 | case BPF_ALU|BPF_OR|BPF_X: | ||
318 | case BPF_ALU|BPF_LSH|BPF_K: | ||
319 | case BPF_ALU|BPF_LSH|BPF_X: | ||
320 | case BPF_ALU|BPF_RSH|BPF_K: | ||
321 | case BPF_ALU|BPF_RSH|BPF_X: | ||
322 | case BPF_ALU|BPF_NEG: | ||
323 | case BPF_LD|BPF_W|BPF_ABS: | ||
324 | case BPF_LD|BPF_H|BPF_ABS: | ||
325 | case BPF_LD|BPF_B|BPF_ABS: | ||
326 | case BPF_LD|BPF_W|BPF_LEN: | ||
327 | case BPF_LD|BPF_W|BPF_IND: | ||
328 | case BPF_LD|BPF_H|BPF_IND: | ||
329 | case BPF_LD|BPF_B|BPF_IND: | ||
330 | case BPF_LD|BPF_IMM: | ||
331 | case BPF_LDX|BPF_W|BPF_LEN: | ||
332 | case BPF_LDX|BPF_B|BPF_MSH: | ||
333 | case BPF_LDX|BPF_IMM: | ||
334 | case BPF_MISC|BPF_TAX: | ||
335 | case BPF_MISC|BPF_TXA: | ||
336 | case BPF_RET|BPF_K: | ||
337 | case BPF_RET|BPF_A: | ||
338 | break; | ||
339 | |||
340 | /* Some instructions need special checks */ | ||
324 | 341 | ||
325 | /* check that memory operations use valid addresses. */ | 342 | case BPF_ALU|BPF_DIV|BPF_K: |
326 | if (ftest->k >= BPF_MEMWORDS) { | 343 | /* check for division by zero */ |
327 | /* but it might not be a memory operation... */ | 344 | if (ftest->k == 0) |
328 | switch (ftest->code) { | ||
329 | case BPF_ST: | ||
330 | case BPF_STX: | ||
331 | case BPF_LD|BPF_MEM: | ||
332 | case BPF_LDX|BPF_MEM: | ||
333 | return -EINVAL; | 345 | return -EINVAL; |
334 | } | 346 | break; |
347 | |||
348 | case BPF_LD|BPF_MEM: | ||
349 | case BPF_LDX|BPF_MEM: | ||
350 | case BPF_ST: | ||
351 | case BPF_STX: | ||
352 | /* check for invalid memory addresses */ | ||
353 | if (ftest->k >= BPF_MEMWORDS) | ||
354 | return -EINVAL; | ||
355 | break; | ||
356 | |||
357 | case BPF_JMP|BPF_JA: | ||
358 | /* | ||
359 | * Note, the large ftest->k might cause loops. | ||
360 | * Compare this with conditional jumps below, | ||
361 | * where offsets are limited. --ANK (981016) | ||
362 | */ | ||
363 | if (ftest->k >= (unsigned)(flen-pc-1)) | ||
364 | return -EINVAL; | ||
365 | break; | ||
366 | |||
367 | case BPF_JMP|BPF_JEQ|BPF_K: | ||
368 | case BPF_JMP|BPF_JEQ|BPF_X: | ||
369 | case BPF_JMP|BPF_JGE|BPF_K: | ||
370 | case BPF_JMP|BPF_JGE|BPF_X: | ||
371 | case BPF_JMP|BPF_JGT|BPF_K: | ||
372 | case BPF_JMP|BPF_JGT|BPF_X: | ||
373 | case BPF_JMP|BPF_JSET|BPF_K: | ||
374 | case BPF_JMP|BPF_JSET|BPF_X: | ||
375 | /* for conditionals both must be safe */ | ||
376 | if (pc + ftest->jt + 1 >= flen || | ||
377 | pc + ftest->jf + 1 >= flen) | ||
378 | return -EINVAL; | ||
379 | break; | ||
380 | |||
381 | default: | ||
382 | return -EINVAL; | ||
335 | } | 383 | } |
336 | } | 384 | } |
337 | 385 | ||
@@ -360,7 +408,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) | |||
360 | int err; | 408 | int err; |
361 | 409 | ||
362 | /* Make sure new filter is there and in the right amounts. */ | 410 | /* Make sure new filter is there and in the right amounts. */ |
363 | if (fprog->filter == NULL || fprog->len > BPF_MAXINSNS) | 411 | if (fprog->filter == NULL) |
364 | return -EINVAL; | 412 | return -EINVAL; |
365 | 413 | ||
366 | fp = sock_kmalloc(sk, fsize+sizeof(*fp), GFP_KERNEL); | 414 | fp = sock_kmalloc(sk, fsize+sizeof(*fp), GFP_KERNEL); |
diff --git a/net/core/flow.c b/net/core/flow.c index 7e95b39de9fd..c4f25385029f 100644 --- a/net/core/flow.c +++ b/net/core/flow.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <net/flow.h> | 23 | #include <net/flow.h> |
24 | #include <asm/atomic.h> | 24 | #include <asm/atomic.h> |
25 | #include <asm/semaphore.h> | 25 | #include <asm/semaphore.h> |
26 | #include <linux/security.h> | ||
26 | 27 | ||
27 | struct flow_cache_entry { | 28 | struct flow_cache_entry { |
28 | struct flow_cache_entry *next; | 29 | struct flow_cache_entry *next; |
@@ -30,6 +31,7 @@ struct flow_cache_entry { | |||
30 | u8 dir; | 31 | u8 dir; |
31 | struct flowi key; | 32 | struct flowi key; |
32 | u32 genid; | 33 | u32 genid; |
34 | u32 sk_sid; | ||
33 | void *object; | 35 | void *object; |
34 | atomic_t *object_ref; | 36 | atomic_t *object_ref; |
35 | }; | 37 | }; |
@@ -162,7 +164,7 @@ static int flow_key_compare(struct flowi *key1, struct flowi *key2) | |||
162 | return 0; | 164 | return 0; |
163 | } | 165 | } |
164 | 166 | ||
165 | void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, | 167 | void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir, |
166 | flow_resolve_t resolver) | 168 | flow_resolve_t resolver) |
167 | { | 169 | { |
168 | struct flow_cache_entry *fle, **head; | 170 | struct flow_cache_entry *fle, **head; |
@@ -186,6 +188,7 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, | |||
186 | for (fle = *head; fle; fle = fle->next) { | 188 | for (fle = *head; fle; fle = fle->next) { |
187 | if (fle->family == family && | 189 | if (fle->family == family && |
188 | fle->dir == dir && | 190 | fle->dir == dir && |
191 | fle->sk_sid == sk_sid && | ||
189 | flow_key_compare(key, &fle->key) == 0) { | 192 | flow_key_compare(key, &fle->key) == 0) { |
190 | if (fle->genid == atomic_read(&flow_cache_genid)) { | 193 | if (fle->genid == atomic_read(&flow_cache_genid)) { |
191 | void *ret = fle->object; | 194 | void *ret = fle->object; |
@@ -210,6 +213,7 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, | |||
210 | *head = fle; | 213 | *head = fle; |
211 | fle->family = family; | 214 | fle->family = family; |
212 | fle->dir = dir; | 215 | fle->dir = dir; |
216 | fle->sk_sid = sk_sid; | ||
213 | memcpy(&fle->key, key, sizeof(*key)); | 217 | memcpy(&fle->key, key, sizeof(*key)); |
214 | fle->object = NULL; | 218 | fle->object = NULL; |
215 | flow_count(cpu)++; | 219 | flow_count(cpu)++; |
@@ -221,7 +225,7 @@ nocache: | |||
221 | void *obj; | 225 | void *obj; |
222 | atomic_t *obj_ref; | 226 | atomic_t *obj_ref; |
223 | 227 | ||
224 | resolver(key, family, dir, &obj, &obj_ref); | 228 | resolver(key, sk_sid, family, dir, &obj, &obj_ref); |
225 | 229 | ||
226 | if (fle) { | 230 | if (fle) { |
227 | fle->genid = atomic_read(&flow_cache_genid); | 231 | fle->genid = atomic_read(&flow_cache_genid); |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 49424a42a2c0..281a632fa6a6 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/netdevice.h> | 13 | #include <linux/netdevice.h> |
14 | #include <linux/etherdevice.h> | 14 | #include <linux/etherdevice.h> |
15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
16 | #include <linux/if_arp.h> | ||
16 | #include <linux/inetdevice.h> | 17 | #include <linux/inetdevice.h> |
17 | #include <linux/inet.h> | 18 | #include <linux/inet.h> |
18 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 7fc3e9e28c34..06cad2d63e8a 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -487,9 +487,9 @@ static unsigned int fmt_ip6(char *s,const char ip[16]); | |||
487 | 487 | ||
488 | /* Module parameters, defaults. */ | 488 | /* Module parameters, defaults. */ |
489 | static int pg_count_d = 1000; /* 1000 pkts by default */ | 489 | static int pg_count_d = 1000; /* 1000 pkts by default */ |
490 | static int pg_delay_d = 0; | 490 | static int pg_delay_d; |
491 | static int pg_clone_skb_d = 0; | 491 | static int pg_clone_skb_d; |
492 | static int debug = 0; | 492 | static int debug; |
493 | 493 | ||
494 | static DECLARE_MUTEX(pktgen_sem); | 494 | static DECLARE_MUTEX(pktgen_sem); |
495 | static struct pktgen_thread *pktgen_threads = NULL; | 495 | static struct pktgen_thread *pktgen_threads = NULL; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 83fee37de38e..070f91cfde59 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -135,17 +135,13 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here) | |||
135 | struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | 135 | struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, |
136 | int fclone) | 136 | int fclone) |
137 | { | 137 | { |
138 | struct skb_shared_info *shinfo; | ||
138 | struct sk_buff *skb; | 139 | struct sk_buff *skb; |
139 | u8 *data; | 140 | u8 *data; |
140 | 141 | ||
141 | /* Get the HEAD */ | 142 | /* Get the HEAD */ |
142 | if (fclone) | 143 | skb = kmem_cache_alloc(fclone ? skbuff_fclone_cache : skbuff_head_cache, |
143 | skb = kmem_cache_alloc(skbuff_fclone_cache, | 144 | gfp_mask & ~__GFP_DMA); |
144 | gfp_mask & ~__GFP_DMA); | ||
145 | else | ||
146 | skb = kmem_cache_alloc(skbuff_head_cache, | ||
147 | gfp_mask & ~__GFP_DMA); | ||
148 | |||
149 | if (!skb) | 145 | if (!skb) |
150 | goto out; | 146 | goto out; |
151 | 147 | ||
@@ -162,6 +158,16 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
162 | skb->data = data; | 158 | skb->data = data; |
163 | skb->tail = data; | 159 | skb->tail = data; |
164 | skb->end = data + size; | 160 | skb->end = data + size; |
161 | /* make sure we initialize shinfo sequentially */ | ||
162 | shinfo = skb_shinfo(skb); | ||
163 | atomic_set(&shinfo->dataref, 1); | ||
164 | shinfo->nr_frags = 0; | ||
165 | shinfo->tso_size = 0; | ||
166 | shinfo->tso_segs = 0; | ||
167 | shinfo->ufo_size = 0; | ||
168 | shinfo->ip6_frag_id = 0; | ||
169 | shinfo->frag_list = NULL; | ||
170 | |||
165 | if (fclone) { | 171 | if (fclone) { |
166 | struct sk_buff *child = skb + 1; | 172 | struct sk_buff *child = skb + 1; |
167 | atomic_t *fclone_ref = (atomic_t *) (child + 1); | 173 | atomic_t *fclone_ref = (atomic_t *) (child + 1); |
@@ -171,13 +177,6 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
171 | 177 | ||
172 | child->fclone = SKB_FCLONE_UNAVAILABLE; | 178 | child->fclone = SKB_FCLONE_UNAVAILABLE; |
173 | } | 179 | } |
174 | atomic_set(&(skb_shinfo(skb)->dataref), 1); | ||
175 | skb_shinfo(skb)->nr_frags = 0; | ||
176 | skb_shinfo(skb)->tso_size = 0; | ||
177 | skb_shinfo(skb)->tso_segs = 0; | ||
178 | skb_shinfo(skb)->frag_list = NULL; | ||
179 | skb_shinfo(skb)->ufo_size = 0; | ||
180 | skb_shinfo(skb)->ip6_frag_id = 0; | ||
181 | out: | 180 | out: |
182 | return skb; | 181 | return skb; |
183 | nodata: | 182 | nodata: |
diff --git a/net/core/sock.c b/net/core/sock.c index 13cc3be4f056..6465b0e4c8cb 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1488,7 +1488,7 @@ int proto_register(struct proto *prot, int alloc_slab) | |||
1488 | } | 1488 | } |
1489 | } | 1489 | } |
1490 | 1490 | ||
1491 | if (prot->twsk_obj_size) { | 1491 | if (prot->twsk_prot != NULL) { |
1492 | static const char mask[] = "tw_sock_%s"; | 1492 | static const char mask[] = "tw_sock_%s"; |
1493 | 1493 | ||
1494 | timewait_sock_slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL); | 1494 | timewait_sock_slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL); |
@@ -1497,11 +1497,12 @@ int proto_register(struct proto *prot, int alloc_slab) | |||
1497 | goto out_free_request_sock_slab; | 1497 | goto out_free_request_sock_slab; |
1498 | 1498 | ||
1499 | sprintf(timewait_sock_slab_name, mask, prot->name); | 1499 | sprintf(timewait_sock_slab_name, mask, prot->name); |
1500 | prot->twsk_slab = kmem_cache_create(timewait_sock_slab_name, | 1500 | prot->twsk_prot->twsk_slab = |
1501 | prot->twsk_obj_size, | 1501 | kmem_cache_create(timewait_sock_slab_name, |
1502 | 0, SLAB_HWCACHE_ALIGN, | 1502 | prot->twsk_prot->twsk_obj_size, |
1503 | NULL, NULL); | 1503 | 0, SLAB_HWCACHE_ALIGN, |
1504 | if (prot->twsk_slab == NULL) | 1504 | NULL, NULL); |
1505 | if (prot->twsk_prot->twsk_slab == NULL) | ||
1505 | goto out_free_timewait_sock_slab_name; | 1506 | goto out_free_timewait_sock_slab_name; |
1506 | } | 1507 | } |
1507 | } | 1508 | } |
@@ -1548,12 +1549,12 @@ void proto_unregister(struct proto *prot) | |||
1548 | prot->rsk_prot->slab = NULL; | 1549 | prot->rsk_prot->slab = NULL; |
1549 | } | 1550 | } |
1550 | 1551 | ||
1551 | if (prot->twsk_slab != NULL) { | 1552 | if (prot->twsk_prot != NULL && prot->twsk_prot->twsk_slab != NULL) { |
1552 | const char *name = kmem_cache_name(prot->twsk_slab); | 1553 | const char *name = kmem_cache_name(prot->twsk_prot->twsk_slab); |
1553 | 1554 | ||
1554 | kmem_cache_destroy(prot->twsk_slab); | 1555 | kmem_cache_destroy(prot->twsk_prot->twsk_slab); |
1555 | kfree(name); | 1556 | kfree(name); |
1556 | prot->twsk_slab = NULL; | 1557 | prot->twsk_prot->twsk_slab = NULL; |
1557 | } | 1558 | } |
1558 | } | 1559 | } |
1559 | 1560 | ||
diff --git a/net/core/stream.c b/net/core/stream.c index 15bfd03e8024..35e25259fd95 100644 --- a/net/core/stream.c +++ b/net/core/stream.c | |||
@@ -55,8 +55,9 @@ int sk_stream_wait_connect(struct sock *sk, long *timeo_p) | |||
55 | int done; | 55 | int done; |
56 | 56 | ||
57 | do { | 57 | do { |
58 | if (sk->sk_err) | 58 | int err = sock_error(sk); |
59 | return sock_error(sk); | 59 | if (err) |
60 | return err; | ||
60 | if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) | 61 | if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) |
61 | return -EPIPE; | 62 | return -EPIPE; |
62 | if (!*timeo_p) | 63 | if (!*timeo_p) |
@@ -67,6 +68,7 @@ int sk_stream_wait_connect(struct sock *sk, long *timeo_p) | |||
67 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 68 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); |
68 | sk->sk_write_pending++; | 69 | sk->sk_write_pending++; |
69 | done = sk_wait_event(sk, timeo_p, | 70 | done = sk_wait_event(sk, timeo_p, |
71 | !sk->sk_err && | ||
70 | !((1 << sk->sk_state) & | 72 | !((1 << sk->sk_state) & |
71 | ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT))); | 73 | ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT))); |
72 | finish_wait(sk->sk_sleep, &wait); | 74 | finish_wait(sk->sk_sleep, &wait); |
@@ -137,7 +139,9 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) | |||
137 | 139 | ||
138 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); | 140 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); |
139 | sk->sk_write_pending++; | 141 | sk->sk_write_pending++; |
140 | sk_wait_event(sk, ¤t_timeo, sk_stream_memory_free(sk) && | 142 | sk_wait_event(sk, ¤t_timeo, !sk->sk_err && |
143 | !(sk->sk_shutdown & SEND_SHUTDOWN) && | ||
144 | sk_stream_memory_free(sk) && | ||
141 | vm_wait); | 145 | vm_wait); |
142 | sk->sk_write_pending--; | 146 | sk->sk_write_pending--; |
143 | 147 | ||
diff --git a/net/dccp/Makefile b/net/dccp/Makefile index 344a8da153fc..87b27fff6e3b 100644 --- a/net/dccp/Makefile +++ b/net/dccp/Makefile | |||
@@ -1,3 +1,7 @@ | |||
1 | obj-$(CONFIG_IPV6) += dccp_ipv6.o | ||
2 | |||
3 | dccp_ipv6-y := ipv6.o | ||
4 | |||
1 | obj-$(CONFIG_IP_DCCP) += dccp.o | 5 | obj-$(CONFIG_IP_DCCP) += dccp.o |
2 | 6 | ||
3 | dccp-y := ccid.o input.o ipv4.o minisocks.o options.o output.o proto.o \ | 7 | dccp-y := ccid.o input.o ipv4.o minisocks.o options.o output.o proto.o \ |
diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index c9a62cca22fc..ce9cb77c5c29 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c | |||
@@ -55,8 +55,8 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) | |||
55 | from = av->dccpav_buf + av->dccpav_buf_head; | 55 | from = av->dccpav_buf + av->dccpav_buf_head; |
56 | 56 | ||
57 | /* Check if buf_head wraps */ | 57 | /* Check if buf_head wraps */ |
58 | if (av->dccpav_buf_head + len > av->dccpav_vec_len) { | 58 | if ((int)av->dccpav_buf_head + len > av->dccpav_vec_len) { |
59 | const u32 tailsize = (av->dccpav_vec_len - av->dccpav_buf_head); | 59 | const u32 tailsize = av->dccpav_vec_len - av->dccpav_buf_head; |
60 | 60 | ||
61 | memcpy(to, from, tailsize); | 61 | memcpy(to, from, tailsize); |
62 | to += tailsize; | 62 | to += tailsize; |
@@ -93,8 +93,14 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) | |||
93 | struct dccp_ackvec *dccp_ackvec_alloc(const unsigned int len, | 93 | struct dccp_ackvec *dccp_ackvec_alloc(const unsigned int len, |
94 | const gfp_t priority) | 94 | const gfp_t priority) |
95 | { | 95 | { |
96 | struct dccp_ackvec *av = kmalloc(sizeof(*av) + len, priority); | 96 | struct dccp_ackvec *av; |
97 | 97 | ||
98 | BUG_ON(len == 0); | ||
99 | |||
100 | if (len > DCCP_MAX_ACKVEC_LEN) | ||
101 | return NULL; | ||
102 | |||
103 | av = kmalloc(sizeof(*av) + len, priority); | ||
98 | if (av != NULL) { | 104 | if (av != NULL) { |
99 | av->dccpav_buf_len = len; | 105 | av->dccpav_buf_len = len; |
100 | av->dccpav_buf_head = | 106 | av->dccpav_buf_head = |
@@ -117,13 +123,13 @@ void dccp_ackvec_free(struct dccp_ackvec *av) | |||
117 | } | 123 | } |
118 | 124 | ||
119 | static inline u8 dccp_ackvec_state(const struct dccp_ackvec *av, | 125 | static inline u8 dccp_ackvec_state(const struct dccp_ackvec *av, |
120 | const unsigned int index) | 126 | const u8 index) |
121 | { | 127 | { |
122 | return av->dccpav_buf[index] & DCCP_ACKVEC_STATE_MASK; | 128 | return av->dccpav_buf[index] & DCCP_ACKVEC_STATE_MASK; |
123 | } | 129 | } |
124 | 130 | ||
125 | static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av, | 131 | static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av, |
126 | const unsigned int index) | 132 | const u8 index) |
127 | { | 133 | { |
128 | return av->dccpav_buf[index] & DCCP_ACKVEC_LEN_MASK; | 134 | return av->dccpav_buf[index] & DCCP_ACKVEC_LEN_MASK; |
129 | } | 135 | } |
@@ -135,7 +141,7 @@ static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av, | |||
135 | */ | 141 | */ |
136 | static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av, | 142 | static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av, |
137 | const unsigned int packets, | 143 | const unsigned int packets, |
138 | const unsigned char state) | 144 | const unsigned char state) |
139 | { | 145 | { |
140 | unsigned int gap; | 146 | unsigned int gap; |
141 | signed long new_head; | 147 | signed long new_head; |
@@ -223,7 +229,7 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, | |||
223 | * could reduce the complexity of this scan.) | 229 | * could reduce the complexity of this scan.) |
224 | */ | 230 | */ |
225 | u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno); | 231 | u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno); |
226 | unsigned int index = av->dccpav_buf_head; | 232 | u8 index = av->dccpav_buf_head; |
227 | 233 | ||
228 | while (1) { | 234 | while (1) { |
229 | const u8 len = dccp_ackvec_len(av, index); | 235 | const u8 len = dccp_ackvec_len(av, index); |
@@ -291,7 +297,7 @@ void dccp_ackvec_print(const struct dccp_ackvec *av) | |||
291 | } | 297 | } |
292 | #endif | 298 | #endif |
293 | 299 | ||
294 | static void dccp_ackvec_trow_away_ack_record(struct dccp_ackvec *av) | 300 | static void dccp_ackvec_throw_away_ack_record(struct dccp_ackvec *av) |
295 | { | 301 | { |
296 | /* | 302 | /* |
297 | * As we're keeping track of the ack vector size (dccpav_vec_len) and | 303 | * As we're keeping track of the ack vector size (dccpav_vec_len) and |
@@ -301,9 +307,10 @@ static void dccp_ackvec_trow_away_ack_record(struct dccp_ackvec *av) | |||
301 | * draft-ietf-dccp-spec-11.txt Appendix A. -acme | 307 | * draft-ietf-dccp-spec-11.txt Appendix A. -acme |
302 | */ | 308 | */ |
303 | #if 0 | 309 | #if 0 |
304 | av->dccpav_buf_tail = av->dccpav_ack_ptr + 1; | 310 | u32 new_buf_tail = av->dccpav_ack_ptr + 1; |
305 | if (av->dccpav_buf_tail >= av->dccpav_vec_len) | 311 | if (new_buf_tail >= av->dccpav_vec_len) |
306 | av->dccpav_buf_tail -= av->dccpav_vec_len; | 312 | new_buf_tail -= av->dccpav_vec_len; |
313 | av->dccpav_buf_tail = new_buf_tail; | ||
307 | #endif | 314 | #endif |
308 | av->dccpav_vec_len -= av->dccpav_sent_len; | 315 | av->dccpav_vec_len -= av->dccpav_sent_len; |
309 | } | 316 | } |
@@ -326,7 +333,7 @@ void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, struct sock *sk, | |||
326 | debug_prefix, 1, | 333 | debug_prefix, 1, |
327 | (unsigned long long)av->dccpav_ack_seqno, | 334 | (unsigned long long)av->dccpav_ack_seqno, |
328 | (unsigned long long)av->dccpav_ack_ackno); | 335 | (unsigned long long)av->dccpav_ack_ackno); |
329 | dccp_ackvec_trow_away_ack_record(av); | 336 | dccp_ackvec_throw_away_ack_record(av); |
330 | av->dccpav_ack_seqno = DCCP_MAX_SEQNO + 1; | 337 | av->dccpav_ack_seqno = DCCP_MAX_SEQNO + 1; |
331 | } | 338 | } |
332 | } | 339 | } |
@@ -389,7 +396,7 @@ static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av, | |||
389 | av->dccpav_ack_seqno, | 396 | av->dccpav_ack_seqno, |
390 | (unsigned long long) | 397 | (unsigned long long) |
391 | av->dccpav_ack_ackno); | 398 | av->dccpav_ack_ackno); |
392 | dccp_ackvec_trow_away_ack_record(av); | 399 | dccp_ackvec_throw_away_ack_record(av); |
393 | } | 400 | } |
394 | /* | 401 | /* |
395 | * If dccpav_ack_seqno was not received, no problem | 402 | * If dccpav_ack_seqno was not received, no problem |
diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h index d0fd6c60c574..f7dfb5f67b87 100644 --- a/net/dccp/ackvec.h +++ b/net/dccp/ackvec.h | |||
@@ -54,16 +54,16 @@ | |||
54 | * @dccpav_buf - circular buffer of acknowledgeable packets | 54 | * @dccpav_buf - circular buffer of acknowledgeable packets |
55 | */ | 55 | */ |
56 | struct dccp_ackvec { | 56 | struct dccp_ackvec { |
57 | unsigned int dccpav_buf_head; | ||
58 | unsigned int dccpav_buf_tail; | ||
59 | u64 dccpav_buf_ackno; | 57 | u64 dccpav_buf_ackno; |
60 | u64 dccpav_ack_seqno; | 58 | u64 dccpav_ack_seqno; |
61 | u64 dccpav_ack_ackno; | 59 | u64 dccpav_ack_ackno; |
62 | unsigned int dccpav_ack_ptr; | ||
63 | unsigned int dccpav_sent_len; | ||
64 | unsigned int dccpav_vec_len; | ||
65 | unsigned int dccpav_buf_len; | ||
66 | struct timeval dccpav_time; | 60 | struct timeval dccpav_time; |
61 | u8 dccpav_buf_head; | ||
62 | u8 dccpav_buf_tail; | ||
63 | u8 dccpav_ack_ptr; | ||
64 | u8 dccpav_sent_len; | ||
65 | u8 dccpav_vec_len; | ||
66 | u8 dccpav_buf_len; | ||
67 | u8 dccpav_buf_nonce; | 67 | u8 dccpav_buf_nonce; |
68 | u8 dccpav_ack_nonce; | 68 | u8 dccpav_ack_nonce; |
69 | u8 dccpav_buf[0]; | 69 | u8 dccpav_buf[0]; |
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h index c37eeeaf5c6e..de681c6ad081 100644 --- a/net/dccp/ccid.h +++ b/net/dccp/ccid.h | |||
@@ -21,6 +21,8 @@ | |||
21 | 21 | ||
22 | #define CCID_MAX 255 | 22 | #define CCID_MAX 255 |
23 | 23 | ||
24 | struct tcp_info; | ||
25 | |||
24 | struct ccid { | 26 | struct ccid { |
25 | unsigned char ccid_id; | 27 | unsigned char ccid_id; |
26 | const char *ccid_name; | 28 | const char *ccid_name; |
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index f97b85d55ad8..93f26dd6e6cb 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
@@ -59,7 +59,7 @@ extern void dccp_time_wait(struct sock *sk, int state, int timeo); | |||
59 | 59 | ||
60 | #define DCCP_RTO_MAX ((unsigned)(120 * HZ)) /* FIXME: using TCP value */ | 60 | #define DCCP_RTO_MAX ((unsigned)(120 * HZ)) /* FIXME: using TCP value */ |
61 | 61 | ||
62 | extern struct proto dccp_v4_prot; | 62 | extern struct proto dccp_prot; |
63 | 63 | ||
64 | /* is seq1 < seq2 ? */ | 64 | /* is seq1 < seq2 ? */ |
65 | static inline int before48(const u64 seq1, const u64 seq2) | 65 | static inline int before48(const u64 seq1, const u64 seq2) |
@@ -228,6 +228,9 @@ extern int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
228 | extern int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, | 228 | extern int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, |
229 | const struct dccp_hdr *dh, const unsigned len); | 229 | const struct dccp_hdr *dh, const unsigned len); |
230 | 230 | ||
231 | extern int dccp_v4_init_sock(struct sock *sk); | ||
232 | extern int dccp_v4_destroy_sock(struct sock *sk); | ||
233 | |||
231 | extern void dccp_close(struct sock *sk, long timeout); | 234 | extern void dccp_close(struct sock *sk, long timeout); |
232 | extern struct sk_buff *dccp_make_response(struct sock *sk, | 235 | extern struct sk_buff *dccp_make_response(struct sock *sk, |
233 | struct dst_entry *dst, | 236 | struct dst_entry *dst, |
@@ -238,6 +241,7 @@ extern struct sk_buff *dccp_make_reset(struct sock *sk, | |||
238 | 241 | ||
239 | extern int dccp_connect(struct sock *sk); | 242 | extern int dccp_connect(struct sock *sk); |
240 | extern int dccp_disconnect(struct sock *sk, int flags); | 243 | extern int dccp_disconnect(struct sock *sk, int flags); |
244 | extern void dccp_unhash(struct sock *sk); | ||
241 | extern int dccp_getsockopt(struct sock *sk, int level, int optname, | 245 | extern int dccp_getsockopt(struct sock *sk, int level, int optname, |
242 | char __user *optval, int __user *optlen); | 246 | char __user *optval, int __user *optlen); |
243 | extern int dccp_setsockopt(struct sock *sk, int level, int optname, | 247 | extern int dccp_setsockopt(struct sock *sk, int level, int optname, |
@@ -249,6 +253,13 @@ extern int dccp_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
249 | struct msghdr *msg, size_t len, int nonblock, | 253 | struct msghdr *msg, size_t len, int nonblock, |
250 | int flags, int *addr_len); | 254 | int flags, int *addr_len); |
251 | extern void dccp_shutdown(struct sock *sk, int how); | 255 | extern void dccp_shutdown(struct sock *sk, int how); |
256 | extern int inet_dccp_listen(struct socket *sock, int backlog); | ||
257 | extern unsigned int dccp_poll(struct file *file, struct socket *sock, | ||
258 | poll_table *wait); | ||
259 | extern void dccp_v4_send_check(struct sock *sk, int len, | ||
260 | struct sk_buff *skb); | ||
261 | extern int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, | ||
262 | int addr_len); | ||
252 | 263 | ||
253 | extern int dccp_v4_checksum(const struct sk_buff *skb, | 264 | extern int dccp_v4_checksum(const struct sk_buff *skb, |
254 | const u32 saddr, const u32 daddr); | 265 | const u32 saddr, const u32 daddr); |
@@ -256,6 +267,17 @@ extern int dccp_v4_checksum(const struct sk_buff *skb, | |||
256 | extern int dccp_v4_send_reset(struct sock *sk, | 267 | extern int dccp_v4_send_reset(struct sock *sk, |
257 | enum dccp_reset_codes code); | 268 | enum dccp_reset_codes code); |
258 | extern void dccp_send_close(struct sock *sk, const int active); | 269 | extern void dccp_send_close(struct sock *sk, const int active); |
270 | extern int dccp_invalid_packet(struct sk_buff *skb); | ||
271 | |||
272 | static inline int dccp_bad_service_code(const struct sock *sk, | ||
273 | const __u32 service) | ||
274 | { | ||
275 | const struct dccp_sock *dp = dccp_sk(sk); | ||
276 | |||
277 | if (dp->dccps_service == service) | ||
278 | return 0; | ||
279 | return !dccp_list_has_service(dp->dccps_service_list, service); | ||
280 | } | ||
259 | 281 | ||
260 | struct dccp_skb_cb { | 282 | struct dccp_skb_cb { |
261 | __u8 dccpd_type:4; | 283 | __u8 dccpd_type:4; |
diff --git a/net/dccp/diag.c b/net/dccp/diag.c index f675d8e642d3..3f78c00e3822 100644 --- a/net/dccp/diag.c +++ b/net/dccp/diag.c | |||
@@ -28,7 +28,7 @@ static void dccp_get_info(struct sock *sk, struct tcp_info *info) | |||
28 | info->tcpi_retransmits = icsk->icsk_retransmits; | 28 | info->tcpi_retransmits = icsk->icsk_retransmits; |
29 | info->tcpi_probes = icsk->icsk_probes_out; | 29 | info->tcpi_probes = icsk->icsk_probes_out; |
30 | info->tcpi_backoff = icsk->icsk_backoff; | 30 | info->tcpi_backoff = icsk->icsk_backoff; |
31 | info->tcpi_pmtu = dp->dccps_pmtu_cookie; | 31 | info->tcpi_pmtu = icsk->icsk_pmtu_cookie; |
32 | 32 | ||
33 | if (dp->dccps_options.dccpo_send_ack_vector) | 33 | if (dp->dccps_options.dccpo_send_ack_vector) |
34 | info->tcpi_options |= TCPI_OPT_SACK; | 34 | info->tcpi_options |= TCPI_OPT_SACK; |
diff --git a/net/dccp/input.c b/net/dccp/input.c index 3454d5941900..b6cba72b44e8 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c | |||
@@ -151,29 +151,12 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) | |||
151 | return 0; | 151 | return 0; |
152 | } | 152 | } |
153 | 153 | ||
154 | int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, | 154 | static inline int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb, |
155 | const struct dccp_hdr *dh, const unsigned len) | 155 | const struct dccp_hdr *dh, |
156 | const unsigned len) | ||
156 | { | 157 | { |
157 | struct dccp_sock *dp = dccp_sk(sk); | 158 | struct dccp_sock *dp = dccp_sk(sk); |
158 | 159 | ||
159 | if (dccp_check_seqno(sk, skb)) | ||
160 | goto discard; | ||
161 | |||
162 | if (dccp_parse_options(sk, skb)) | ||
163 | goto discard; | ||
164 | |||
165 | if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) | ||
166 | dccp_event_ack_recv(sk, skb); | ||
167 | |||
168 | if (dp->dccps_options.dccpo_send_ack_vector && | ||
169 | dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, | ||
170 | DCCP_SKB_CB(skb)->dccpd_seq, | ||
171 | DCCP_ACKVEC_STATE_RECEIVED)) | ||
172 | goto discard; | ||
173 | |||
174 | ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); | ||
175 | ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); | ||
176 | |||
177 | switch (dccp_hdr(skb)->dccph_type) { | 160 | switch (dccp_hdr(skb)->dccph_type) { |
178 | case DCCP_PKT_DATAACK: | 161 | case DCCP_PKT_DATAACK: |
179 | case DCCP_PKT_DATA: | 162 | case DCCP_PKT_DATA: |
@@ -250,6 +233,37 @@ discard: | |||
250 | return 0; | 233 | return 0; |
251 | } | 234 | } |
252 | 235 | ||
236 | int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, | ||
237 | const struct dccp_hdr *dh, const unsigned len) | ||
238 | { | ||
239 | struct dccp_sock *dp = dccp_sk(sk); | ||
240 | |||
241 | if (dccp_check_seqno(sk, skb)) | ||
242 | goto discard; | ||
243 | |||
244 | if (dccp_parse_options(sk, skb)) | ||
245 | goto discard; | ||
246 | |||
247 | if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) | ||
248 | dccp_event_ack_recv(sk, skb); | ||
249 | |||
250 | if (dp->dccps_options.dccpo_send_ack_vector && | ||
251 | dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, | ||
252 | DCCP_SKB_CB(skb)->dccpd_seq, | ||
253 | DCCP_ACKVEC_STATE_RECEIVED)) | ||
254 | goto discard; | ||
255 | |||
256 | ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); | ||
257 | ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); | ||
258 | |||
259 | return __dccp_rcv_established(sk, skb, dh, len); | ||
260 | discard: | ||
261 | __kfree_skb(skb); | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | EXPORT_SYMBOL_GPL(dccp_rcv_established); | ||
266 | |||
253 | static int dccp_rcv_request_sent_state_process(struct sock *sk, | 267 | static int dccp_rcv_request_sent_state_process(struct sock *sk, |
254 | struct sk_buff *skb, | 268 | struct sk_buff *skb, |
255 | const struct dccp_hdr *dh, | 269 | const struct dccp_hdr *dh, |
@@ -286,6 +300,12 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk, | |||
286 | goto out_invalid_packet; | 300 | goto out_invalid_packet; |
287 | } | 301 | } |
288 | 302 | ||
303 | if (dp->dccps_options.dccpo_send_ack_vector && | ||
304 | dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, | ||
305 | DCCP_SKB_CB(skb)->dccpd_seq, | ||
306 | DCCP_ACKVEC_STATE_RECEIVED)) | ||
307 | goto out_invalid_packet; /* FIXME: change error code */ | ||
308 | |||
289 | dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq; | 309 | dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq; |
290 | dccp_update_gsr(sk, dp->dccps_isr); | 310 | dccp_update_gsr(sk, dp->dccps_isr); |
291 | /* | 311 | /* |
@@ -309,7 +329,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk, | |||
309 | goto out_invalid_packet; | 329 | goto out_invalid_packet; |
310 | } | 330 | } |
311 | 331 | ||
312 | dccp_sync_mss(sk, dp->dccps_pmtu_cookie); | 332 | dccp_sync_mss(sk, icsk->icsk_pmtu_cookie); |
313 | 333 | ||
314 | /* | 334 | /* |
315 | * Step 10: Process REQUEST state (second part) | 335 | * Step 10: Process REQUEST state (second part) |
@@ -329,7 +349,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk, | |||
329 | dccp_set_state(sk, DCCP_PARTOPEN); | 349 | dccp_set_state(sk, DCCP_PARTOPEN); |
330 | 350 | ||
331 | /* Make sure socket is routed, for correct metrics. */ | 351 | /* Make sure socket is routed, for correct metrics. */ |
332 | inet_sk_rebuild_header(sk); | 352 | icsk->icsk_af_ops->rebuild_header(sk); |
333 | 353 | ||
334 | if (!sock_flag(sk, SOCK_DEAD)) { | 354 | if (!sock_flag(sk, SOCK_DEAD)) { |
335 | sk->sk_state_change(sk); | 355 | sk->sk_state_change(sk); |
@@ -398,9 +418,9 @@ static int dccp_rcv_respond_partopen_state_process(struct sock *sk, | |||
398 | 418 | ||
399 | if (dh->dccph_type == DCCP_PKT_DATAACK || | 419 | if (dh->dccph_type == DCCP_PKT_DATAACK || |
400 | dh->dccph_type == DCCP_PKT_DATA) { | 420 | dh->dccph_type == DCCP_PKT_DATA) { |
401 | dccp_rcv_established(sk, skb, dh, len); | 421 | __dccp_rcv_established(sk, skb, dh, len); |
402 | queued = 1; /* packet was queued | 422 | queued = 1; /* packet was queued |
403 | (by dccp_rcv_established) */ | 423 | (by __dccp_rcv_established) */ |
404 | } | 424 | } |
405 | break; | 425 | break; |
406 | } | 426 | } |
@@ -444,7 +464,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
444 | */ | 464 | */ |
445 | if (sk->sk_state == DCCP_LISTEN) { | 465 | if (sk->sk_state == DCCP_LISTEN) { |
446 | if (dh->dccph_type == DCCP_PKT_REQUEST) { | 466 | if (dh->dccph_type == DCCP_PKT_REQUEST) { |
447 | if (dccp_v4_conn_request(sk, skb) < 0) | 467 | if (inet_csk(sk)->icsk_af_ops->conn_request(sk, |
468 | skb) < 0) | ||
448 | return 1; | 469 | return 1; |
449 | 470 | ||
450 | /* FIXME: do congestion control initialization */ | 471 | /* FIXME: do congestion control initialization */ |
@@ -471,14 +492,14 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
471 | if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) | 492 | if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) |
472 | dccp_event_ack_recv(sk, skb); | 493 | dccp_event_ack_recv(sk, skb); |
473 | 494 | ||
474 | ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); | ||
475 | ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); | ||
476 | |||
477 | if (dp->dccps_options.dccpo_send_ack_vector && | 495 | if (dp->dccps_options.dccpo_send_ack_vector && |
478 | dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, | 496 | dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, |
479 | DCCP_SKB_CB(skb)->dccpd_seq, | 497 | DCCP_SKB_CB(skb)->dccpd_seq, |
480 | DCCP_ACKVEC_STATE_RECEIVED)) | 498 | DCCP_ACKVEC_STATE_RECEIVED)) |
481 | goto discard; | 499 | goto discard; |
500 | |||
501 | ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); | ||
502 | ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); | ||
482 | } | 503 | } |
483 | 504 | ||
484 | /* | 505 | /* |
@@ -566,3 +587,5 @@ discard: | |||
566 | } | 587 | } |
567 | return 0; | 588 | return 0; |
568 | } | 589 | } |
590 | |||
591 | EXPORT_SYMBOL_GPL(dccp_rcv_state_process); | ||
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index ca03521112c5..3f244670764a 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -19,7 +19,9 @@ | |||
19 | 19 | ||
20 | #include <net/icmp.h> | 20 | #include <net/icmp.h> |
21 | #include <net/inet_hashtables.h> | 21 | #include <net/inet_hashtables.h> |
22 | #include <net/inet_sock.h> | ||
22 | #include <net/sock.h> | 23 | #include <net/sock.h> |
24 | #include <net/timewait_sock.h> | ||
23 | #include <net/tcp_states.h> | 25 | #include <net/tcp_states.h> |
24 | #include <net/xfrm.h> | 26 | #include <net/xfrm.h> |
25 | 27 | ||
@@ -37,7 +39,8 @@ EXPORT_SYMBOL_GPL(dccp_hashinfo); | |||
37 | 39 | ||
38 | static int dccp_v4_get_port(struct sock *sk, const unsigned short snum) | 40 | static int dccp_v4_get_port(struct sock *sk, const unsigned short snum) |
39 | { | 41 | { |
40 | return inet_csk_get_port(&dccp_hashinfo, sk, snum); | 42 | return inet_csk_get_port(&dccp_hashinfo, sk, snum, |
43 | inet_csk_bind_conflict); | ||
41 | } | 44 | } |
42 | 45 | ||
43 | static void dccp_v4_hash(struct sock *sk) | 46 | static void dccp_v4_hash(struct sock *sk) |
@@ -45,171 +48,14 @@ static void dccp_v4_hash(struct sock *sk) | |||
45 | inet_hash(&dccp_hashinfo, sk); | 48 | inet_hash(&dccp_hashinfo, sk); |
46 | } | 49 | } |
47 | 50 | ||
48 | static void dccp_v4_unhash(struct sock *sk) | 51 | void dccp_unhash(struct sock *sk) |
49 | { | 52 | { |
50 | inet_unhash(&dccp_hashinfo, sk); | 53 | inet_unhash(&dccp_hashinfo, sk); |
51 | } | 54 | } |
52 | 55 | ||
53 | /* called with local bh disabled */ | 56 | EXPORT_SYMBOL_GPL(dccp_unhash); |
54 | static int __dccp_v4_check_established(struct sock *sk, const __u16 lport, | ||
55 | struct inet_timewait_sock **twp) | ||
56 | { | ||
57 | struct inet_sock *inet = inet_sk(sk); | ||
58 | const u32 daddr = inet->rcv_saddr; | ||
59 | const u32 saddr = inet->daddr; | ||
60 | const int dif = sk->sk_bound_dev_if; | ||
61 | INET_ADDR_COOKIE(acookie, saddr, daddr) | ||
62 | const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport); | ||
63 | unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport); | ||
64 | struct inet_ehash_bucket *head = inet_ehash_bucket(&dccp_hashinfo, hash); | ||
65 | const struct sock *sk2; | ||
66 | const struct hlist_node *node; | ||
67 | struct inet_timewait_sock *tw; | ||
68 | |||
69 | prefetch(head->chain.first); | ||
70 | write_lock(&head->lock); | ||
71 | |||
72 | /* Check TIME-WAIT sockets first. */ | ||
73 | sk_for_each(sk2, node, &(head + dccp_hashinfo.ehash_size)->chain) { | ||
74 | tw = inet_twsk(sk2); | ||
75 | |||
76 | if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) | ||
77 | goto not_unique; | ||
78 | } | ||
79 | tw = NULL; | ||
80 | |||
81 | /* And established part... */ | ||
82 | sk_for_each(sk2, node, &head->chain) { | ||
83 | if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) | ||
84 | goto not_unique; | ||
85 | } | ||
86 | 57 | ||
87 | /* Must record num and sport now. Otherwise we will see | 58 | int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
88 | * in hash table socket with a funny identity. */ | ||
89 | inet->num = lport; | ||
90 | inet->sport = htons(lport); | ||
91 | sk->sk_hash = hash; | ||
92 | BUG_TRAP(sk_unhashed(sk)); | ||
93 | __sk_add_node(sk, &head->chain); | ||
94 | sock_prot_inc_use(sk->sk_prot); | ||
95 | write_unlock(&head->lock); | ||
96 | |||
97 | if (twp != NULL) { | ||
98 | *twp = tw; | ||
99 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); | ||
100 | } else if (tw != NULL) { | ||
101 | /* Silly. Should hash-dance instead... */ | ||
102 | inet_twsk_deschedule(tw, &dccp_death_row); | ||
103 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); | ||
104 | |||
105 | inet_twsk_put(tw); | ||
106 | } | ||
107 | |||
108 | return 0; | ||
109 | |||
110 | not_unique: | ||
111 | write_unlock(&head->lock); | ||
112 | return -EADDRNOTAVAIL; | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * Bind a port for a connect operation and hash it. | ||
117 | */ | ||
118 | static int dccp_v4_hash_connect(struct sock *sk) | ||
119 | { | ||
120 | const unsigned short snum = inet_sk(sk)->num; | ||
121 | struct inet_bind_hashbucket *head; | ||
122 | struct inet_bind_bucket *tb; | ||
123 | int ret; | ||
124 | |||
125 | if (snum == 0) { | ||
126 | int low = sysctl_local_port_range[0]; | ||
127 | int high = sysctl_local_port_range[1]; | ||
128 | int remaining = (high - low) + 1; | ||
129 | int rover = net_random() % (high - low) + low; | ||
130 | struct hlist_node *node; | ||
131 | struct inet_timewait_sock *tw = NULL; | ||
132 | |||
133 | local_bh_disable(); | ||
134 | do { | ||
135 | head = &dccp_hashinfo.bhash[inet_bhashfn(rover, | ||
136 | dccp_hashinfo.bhash_size)]; | ||
137 | spin_lock(&head->lock); | ||
138 | |||
139 | /* Does not bother with rcv_saddr checks, | ||
140 | * because the established check is already | ||
141 | * unique enough. | ||
142 | */ | ||
143 | inet_bind_bucket_for_each(tb, node, &head->chain) { | ||
144 | if (tb->port == rover) { | ||
145 | BUG_TRAP(!hlist_empty(&tb->owners)); | ||
146 | if (tb->fastreuse >= 0) | ||
147 | goto next_port; | ||
148 | if (!__dccp_v4_check_established(sk, | ||
149 | rover, | ||
150 | &tw)) | ||
151 | goto ok; | ||
152 | goto next_port; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | tb = inet_bind_bucket_create(dccp_hashinfo.bind_bucket_cachep, | ||
157 | head, rover); | ||
158 | if (tb == NULL) { | ||
159 | spin_unlock(&head->lock); | ||
160 | break; | ||
161 | } | ||
162 | tb->fastreuse = -1; | ||
163 | goto ok; | ||
164 | |||
165 | next_port: | ||
166 | spin_unlock(&head->lock); | ||
167 | if (++rover > high) | ||
168 | rover = low; | ||
169 | } while (--remaining > 0); | ||
170 | |||
171 | local_bh_enable(); | ||
172 | |||
173 | return -EADDRNOTAVAIL; | ||
174 | |||
175 | ok: | ||
176 | /* All locks still held and bhs disabled */ | ||
177 | inet_bind_hash(sk, tb, rover); | ||
178 | if (sk_unhashed(sk)) { | ||
179 | inet_sk(sk)->sport = htons(rover); | ||
180 | __inet_hash(&dccp_hashinfo, sk, 0); | ||
181 | } | ||
182 | spin_unlock(&head->lock); | ||
183 | |||
184 | if (tw != NULL) { | ||
185 | inet_twsk_deschedule(tw, &dccp_death_row); | ||
186 | inet_twsk_put(tw); | ||
187 | } | ||
188 | |||
189 | ret = 0; | ||
190 | goto out; | ||
191 | } | ||
192 | |||
193 | head = &dccp_hashinfo.bhash[inet_bhashfn(snum, | ||
194 | dccp_hashinfo.bhash_size)]; | ||
195 | tb = inet_csk(sk)->icsk_bind_hash; | ||
196 | spin_lock_bh(&head->lock); | ||
197 | if (sk_head(&tb->owners) == sk && sk->sk_bind_node.next == NULL) { | ||
198 | __inet_hash(&dccp_hashinfo, sk, 0); | ||
199 | spin_unlock_bh(&head->lock); | ||
200 | return 0; | ||
201 | } else { | ||
202 | spin_unlock(&head->lock); | ||
203 | /* No definite answer... Walk to established hash table */ | ||
204 | ret = __dccp_v4_check_established(sk, snum, NULL); | ||
205 | out: | ||
206 | local_bh_enable(); | ||
207 | return ret; | ||
208 | } | ||
209 | } | ||
210 | |||
211 | static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, | ||
212 | int addr_len) | ||
213 | { | 59 | { |
214 | struct inet_sock *inet = inet_sk(sk); | 60 | struct inet_sock *inet = inet_sk(sk); |
215 | struct dccp_sock *dp = dccp_sk(sk); | 61 | struct dccp_sock *dp = dccp_sk(sk); |
@@ -259,9 +105,9 @@ static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, | |||
259 | inet->dport = usin->sin_port; | 105 | inet->dport = usin->sin_port; |
260 | inet->daddr = daddr; | 106 | inet->daddr = daddr; |
261 | 107 | ||
262 | dp->dccps_ext_header_len = 0; | 108 | inet_csk(sk)->icsk_ext_hdr_len = 0; |
263 | if (inet->opt != NULL) | 109 | if (inet->opt != NULL) |
264 | dp->dccps_ext_header_len = inet->opt->optlen; | 110 | inet_csk(sk)->icsk_ext_hdr_len = inet->opt->optlen; |
265 | /* | 111 | /* |
266 | * Socket identity is still unknown (sport may be zero). | 112 | * Socket identity is still unknown (sport may be zero). |
267 | * However we set state to DCCP_REQUESTING and not releasing socket | 113 | * However we set state to DCCP_REQUESTING and not releasing socket |
@@ -269,7 +115,7 @@ static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, | |||
269 | * complete initialization after this. | 115 | * complete initialization after this. |
270 | */ | 116 | */ |
271 | dccp_set_state(sk, DCCP_REQUESTING); | 117 | dccp_set_state(sk, DCCP_REQUESTING); |
272 | err = dccp_v4_hash_connect(sk); | 118 | err = inet_hash_connect(&dccp_death_row, sk); |
273 | if (err != 0) | 119 | if (err != 0) |
274 | goto failure; | 120 | goto failure; |
275 | 121 | ||
@@ -287,16 +133,6 @@ static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, | |||
287 | usin->sin_port); | 133 | usin->sin_port); |
288 | dccp_update_gss(sk, dp->dccps_iss); | 134 | dccp_update_gss(sk, dp->dccps_iss); |
289 | 135 | ||
290 | /* | ||
291 | * SWL and AWL are initially adjusted so that they are not less than | ||
292 | * the initial Sequence Numbers received and sent, respectively: | ||
293 | * SWL := max(GSR + 1 - floor(W/4), ISR), | ||
294 | * AWL := max(GSS - W' + 1, ISS). | ||
295 | * These adjustments MUST be applied only at the beginning of the | ||
296 | * connection. | ||
297 | */ | ||
298 | dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss)); | ||
299 | |||
300 | inet->id = dp->dccps_iss ^ jiffies; | 136 | inet->id = dp->dccps_iss ^ jiffies; |
301 | 137 | ||
302 | err = dccp_connect(sk); | 138 | err = dccp_connect(sk); |
@@ -316,6 +152,8 @@ failure: | |||
316 | goto out; | 152 | goto out; |
317 | } | 153 | } |
318 | 154 | ||
155 | EXPORT_SYMBOL_GPL(dccp_v4_connect); | ||
156 | |||
319 | /* | 157 | /* |
320 | * This routine does path mtu discovery as defined in RFC1191. | 158 | * This routine does path mtu discovery as defined in RFC1191. |
321 | */ | 159 | */ |
@@ -354,7 +192,7 @@ static inline void dccp_do_pmtu_discovery(struct sock *sk, | |||
354 | mtu = dst_mtu(dst); | 192 | mtu = dst_mtu(dst); |
355 | 193 | ||
356 | if (inet->pmtudisc != IP_PMTUDISC_DONT && | 194 | if (inet->pmtudisc != IP_PMTUDISC_DONT && |
357 | dp->dccps_pmtu_cookie > mtu) { | 195 | inet_csk(sk)->icsk_pmtu_cookie > mtu) { |
358 | dccp_sync_mss(sk, mtu); | 196 | dccp_sync_mss(sk, mtu); |
359 | 197 | ||
360 | /* | 198 | /* |
@@ -606,6 +444,17 @@ out: | |||
606 | sock_put(sk); | 444 | sock_put(sk); |
607 | } | 445 | } |
608 | 446 | ||
447 | /* This routine computes an IPv4 DCCP checksum. */ | ||
448 | void dccp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb) | ||
449 | { | ||
450 | const struct inet_sock *inet = inet_sk(sk); | ||
451 | struct dccp_hdr *dh = dccp_hdr(skb); | ||
452 | |||
453 | dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr, inet->daddr); | ||
454 | } | ||
455 | |||
456 | EXPORT_SYMBOL_GPL(dccp_v4_send_check); | ||
457 | |||
609 | int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code) | 458 | int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code) |
610 | { | 459 | { |
611 | struct sk_buff *skb; | 460 | struct sk_buff *skb; |
@@ -641,16 +490,6 @@ static inline u64 dccp_v4_init_sequence(const struct sock *sk, | |||
641 | dccp_hdr(skb)->dccph_sport); | 490 | dccp_hdr(skb)->dccph_sport); |
642 | } | 491 | } |
643 | 492 | ||
644 | static inline int dccp_bad_service_code(const struct sock *sk, | ||
645 | const __u32 service) | ||
646 | { | ||
647 | const struct dccp_sock *dp = dccp_sk(sk); | ||
648 | |||
649 | if (dp->dccps_service == service) | ||
650 | return 0; | ||
651 | return !dccp_list_has_service(dp->dccps_service_list, service); | ||
652 | } | ||
653 | |||
654 | int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | 493 | int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) |
655 | { | 494 | { |
656 | struct inet_request_sock *ireq; | 495 | struct inet_request_sock *ireq; |
@@ -662,7 +501,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
662 | const __u32 service = dccp_hdr_request(skb)->dccph_req_service; | 501 | const __u32 service = dccp_hdr_request(skb)->dccph_req_service; |
663 | struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); | 502 | struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); |
664 | __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY; | 503 | __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY; |
665 | struct dst_entry *dst = NULL; | ||
666 | 504 | ||
667 | /* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */ | 505 | /* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */ |
668 | if (((struct rtable *)skb->dst)->rt_flags & | 506 | if (((struct rtable *)skb->dst)->rt_flags & |
@@ -703,7 +541,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
703 | ireq = inet_rsk(req); | 541 | ireq = inet_rsk(req); |
704 | ireq->loc_addr = daddr; | 542 | ireq->loc_addr = daddr; |
705 | ireq->rmt_addr = saddr; | 543 | ireq->rmt_addr = saddr; |
706 | /* FIXME: Merge Aristeu's option parsing code when ready */ | ||
707 | req->rcv_wnd = 100; /* Fake, option parsing will get the | 544 | req->rcv_wnd = 100; /* Fake, option parsing will get the |
708 | right value */ | 545 | right value */ |
709 | ireq->opt = NULL; | 546 | ireq->opt = NULL; |
@@ -721,23 +558,22 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
721 | dreq->dreq_iss = dccp_v4_init_sequence(sk, skb); | 558 | dreq->dreq_iss = dccp_v4_init_sequence(sk, skb); |
722 | dreq->dreq_service = service; | 559 | dreq->dreq_service = service; |
723 | 560 | ||
724 | if (dccp_v4_send_response(sk, req, dst)) | 561 | if (dccp_v4_send_response(sk, req, NULL)) |
725 | goto drop_and_free; | 562 | goto drop_and_free; |
726 | 563 | ||
727 | inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT); | 564 | inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT); |
728 | return 0; | 565 | return 0; |
729 | 566 | ||
730 | drop_and_free: | 567 | drop_and_free: |
731 | /* | 568 | reqsk_free(req); |
732 | * FIXME: should be reqsk_free after implementing req->rsk_ops | ||
733 | */ | ||
734 | __reqsk_free(req); | ||
735 | drop: | 569 | drop: |
736 | DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS); | 570 | DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS); |
737 | dcb->dccpd_reset_code = reset_code; | 571 | dcb->dccpd_reset_code = reset_code; |
738 | return -1; | 572 | return -1; |
739 | } | 573 | } |
740 | 574 | ||
575 | EXPORT_SYMBOL_GPL(dccp_v4_conn_request); | ||
576 | |||
741 | /* | 577 | /* |
742 | * The three way handshake has completed - we got a valid ACK or DATAACK - | 578 | * The three way handshake has completed - we got a valid ACK or DATAACK - |
743 | * now create the new socket. | 579 | * now create the new socket. |
@@ -792,6 +628,8 @@ exit: | |||
792 | return NULL; | 628 | return NULL; |
793 | } | 629 | } |
794 | 630 | ||
631 | EXPORT_SYMBOL_GPL(dccp_v4_request_recv_sock); | ||
632 | |||
795 | static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) | 633 | static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) |
796 | { | 634 | { |
797 | const struct dccp_hdr *dh = dccp_hdr(skb); | 635 | const struct dccp_hdr *dh = dccp_hdr(skb); |
@@ -1011,7 +849,9 @@ discard: | |||
1011 | return 0; | 849 | return 0; |
1012 | } | 850 | } |
1013 | 851 | ||
1014 | static inline int dccp_invalid_packet(struct sk_buff *skb) | 852 | EXPORT_SYMBOL_GPL(dccp_v4_do_rcv); |
853 | |||
854 | int dccp_invalid_packet(struct sk_buff *skb) | ||
1015 | { | 855 | { |
1016 | const struct dccp_hdr *dh; | 856 | const struct dccp_hdr *dh; |
1017 | 857 | ||
@@ -1065,29 +905,30 @@ static inline int dccp_invalid_packet(struct sk_buff *skb) | |||
1065 | return 1; | 905 | return 1; |
1066 | } | 906 | } |
1067 | 907 | ||
1068 | /* If the header checksum is incorrect, drop packet and return */ | ||
1069 | if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr, | ||
1070 | skb->nh.iph->daddr) < 0) { | ||
1071 | LIMIT_NETDEBUG(KERN_WARNING "DCCP: header checksum is " | ||
1072 | "incorrect\n"); | ||
1073 | return 1; | ||
1074 | } | ||
1075 | |||
1076 | return 0; | 908 | return 0; |
1077 | } | 909 | } |
1078 | 910 | ||
911 | EXPORT_SYMBOL_GPL(dccp_invalid_packet); | ||
912 | |||
1079 | /* this is called when real data arrives */ | 913 | /* this is called when real data arrives */ |
1080 | int dccp_v4_rcv(struct sk_buff *skb) | 914 | int dccp_v4_rcv(struct sk_buff *skb) |
1081 | { | 915 | { |
1082 | const struct dccp_hdr *dh; | 916 | const struct dccp_hdr *dh; |
1083 | struct sock *sk; | 917 | struct sock *sk; |
1084 | int rc; | ||
1085 | 918 | ||
1086 | /* Step 1: Check header basics: */ | 919 | /* Step 1: Check header basics: */ |
1087 | 920 | ||
1088 | if (dccp_invalid_packet(skb)) | 921 | if (dccp_invalid_packet(skb)) |
1089 | goto discard_it; | 922 | goto discard_it; |
1090 | 923 | ||
924 | /* If the header checksum is incorrect, drop packet and return */ | ||
925 | if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr, | ||
926 | skb->nh.iph->daddr) < 0) { | ||
927 | LIMIT_NETDEBUG(KERN_WARNING "%s: incorrect header checksum\n", | ||
928 | __FUNCTION__); | ||
929 | goto discard_it; | ||
930 | } | ||
931 | |||
1091 | dh = dccp_hdr(skb); | 932 | dh = dccp_hdr(skb); |
1092 | 933 | ||
1093 | DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb); | 934 | DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb); |
@@ -1143,28 +984,10 @@ int dccp_v4_rcv(struct sk_buff *skb) | |||
1143 | goto do_time_wait; | 984 | goto do_time_wait; |
1144 | } | 985 | } |
1145 | 986 | ||
1146 | if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) { | 987 | if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) |
1147 | dccp_pr_debug("xfrm4_policy_check failed\n"); | ||
1148 | goto discard_and_relse; | 988 | goto discard_and_relse; |
1149 | } | ||
1150 | |||
1151 | if (sk_filter(sk, skb, 0)) { | ||
1152 | dccp_pr_debug("sk_filter failed\n"); | ||
1153 | goto discard_and_relse; | ||
1154 | } | ||
1155 | |||
1156 | skb->dev = NULL; | ||
1157 | |||
1158 | bh_lock_sock(sk); | ||
1159 | rc = 0; | ||
1160 | if (!sock_owned_by_user(sk)) | ||
1161 | rc = dccp_v4_do_rcv(sk, skb); | ||
1162 | else | ||
1163 | sk_add_backlog(sk, skb); | ||
1164 | bh_unlock_sock(sk); | ||
1165 | 989 | ||
1166 | sock_put(sk); | 990 | return sk_receive_skb(sk, skb); |
1167 | return rc; | ||
1168 | 991 | ||
1169 | no_dccp_socket: | 992 | no_dccp_socket: |
1170 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) | 993 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) |
@@ -1194,9 +1017,23 @@ do_time_wait: | |||
1194 | goto no_dccp_socket; | 1017 | goto no_dccp_socket; |
1195 | } | 1018 | } |
1196 | 1019 | ||
1197 | static int dccp_v4_init_sock(struct sock *sk) | 1020 | struct inet_connection_sock_af_ops dccp_ipv4_af_ops = { |
1021 | .queue_xmit = ip_queue_xmit, | ||
1022 | .send_check = dccp_v4_send_check, | ||
1023 | .rebuild_header = inet_sk_rebuild_header, | ||
1024 | .conn_request = dccp_v4_conn_request, | ||
1025 | .syn_recv_sock = dccp_v4_request_recv_sock, | ||
1026 | .net_header_len = sizeof(struct iphdr), | ||
1027 | .setsockopt = ip_setsockopt, | ||
1028 | .getsockopt = ip_getsockopt, | ||
1029 | .addr2sockaddr = inet_csk_addr2sockaddr, | ||
1030 | .sockaddr_len = sizeof(struct sockaddr_in), | ||
1031 | }; | ||
1032 | |||
1033 | int dccp_v4_init_sock(struct sock *sk) | ||
1198 | { | 1034 | { |
1199 | struct dccp_sock *dp = dccp_sk(sk); | 1035 | struct dccp_sock *dp = dccp_sk(sk); |
1036 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
1200 | static int dccp_ctl_socket_init = 1; | 1037 | static int dccp_ctl_socket_init = 1; |
1201 | 1038 | ||
1202 | dccp_options_init(&dp->dccps_options); | 1039 | dccp_options_init(&dp->dccps_options); |
@@ -1236,9 +1073,11 @@ static int dccp_v4_init_sock(struct sock *sk) | |||
1236 | dccp_ctl_socket_init = 0; | 1073 | dccp_ctl_socket_init = 0; |
1237 | 1074 | ||
1238 | dccp_init_xmit_timers(sk); | 1075 | dccp_init_xmit_timers(sk); |
1239 | inet_csk(sk)->icsk_rto = DCCP_TIMEOUT_INIT; | 1076 | icsk->icsk_rto = DCCP_TIMEOUT_INIT; |
1240 | sk->sk_state = DCCP_CLOSED; | 1077 | sk->sk_state = DCCP_CLOSED; |
1241 | sk->sk_write_space = dccp_write_space; | 1078 | sk->sk_write_space = dccp_write_space; |
1079 | icsk->icsk_af_ops = &dccp_ipv4_af_ops; | ||
1080 | icsk->icsk_sync_mss = dccp_sync_mss; | ||
1242 | dp->dccps_mss_cache = 536; | 1081 | dp->dccps_mss_cache = 536; |
1243 | dp->dccps_role = DCCP_ROLE_UNDEFINED; | 1082 | dp->dccps_role = DCCP_ROLE_UNDEFINED; |
1244 | dp->dccps_service = DCCP_SERVICE_INVALID_VALUE; | 1083 | dp->dccps_service = DCCP_SERVICE_INVALID_VALUE; |
@@ -1246,12 +1085,14 @@ static int dccp_v4_init_sock(struct sock *sk) | |||
1246 | return 0; | 1085 | return 0; |
1247 | } | 1086 | } |
1248 | 1087 | ||
1249 | static int dccp_v4_destroy_sock(struct sock *sk) | 1088 | EXPORT_SYMBOL_GPL(dccp_v4_init_sock); |
1089 | |||
1090 | int dccp_v4_destroy_sock(struct sock *sk) | ||
1250 | { | 1091 | { |
1251 | struct dccp_sock *dp = dccp_sk(sk); | 1092 | struct dccp_sock *dp = dccp_sk(sk); |
1252 | 1093 | ||
1253 | /* | 1094 | /* |
1254 | * DCCP doesn't use sk_qrite_queue, just sk_send_head | 1095 | * DCCP doesn't use sk_write_queue, just sk_send_head |
1255 | * for retransmissions | 1096 | * for retransmissions |
1256 | */ | 1097 | */ |
1257 | if (sk->sk_send_head != NULL) { | 1098 | if (sk->sk_send_head != NULL) { |
@@ -1279,6 +1120,8 @@ static int dccp_v4_destroy_sock(struct sock *sk) | |||
1279 | return 0; | 1120 | return 0; |
1280 | } | 1121 | } |
1281 | 1122 | ||
1123 | EXPORT_SYMBOL_GPL(dccp_v4_destroy_sock); | ||
1124 | |||
1282 | static void dccp_v4_reqsk_destructor(struct request_sock *req) | 1125 | static void dccp_v4_reqsk_destructor(struct request_sock *req) |
1283 | { | 1126 | { |
1284 | kfree(inet_rsk(req)->opt); | 1127 | kfree(inet_rsk(req)->opt); |
@@ -1293,7 +1136,11 @@ static struct request_sock_ops dccp_request_sock_ops = { | |||
1293 | .send_reset = dccp_v4_ctl_send_reset, | 1136 | .send_reset = dccp_v4_ctl_send_reset, |
1294 | }; | 1137 | }; |
1295 | 1138 | ||
1296 | struct proto dccp_v4_prot = { | 1139 | static struct timewait_sock_ops dccp_timewait_sock_ops = { |
1140 | .twsk_obj_size = sizeof(struct inet_timewait_sock), | ||
1141 | }; | ||
1142 | |||
1143 | struct proto dccp_prot = { | ||
1297 | .name = "DCCP", | 1144 | .name = "DCCP", |
1298 | .owner = THIS_MODULE, | 1145 | .owner = THIS_MODULE, |
1299 | .close = dccp_close, | 1146 | .close = dccp_close, |
@@ -1307,7 +1154,7 @@ struct proto dccp_v4_prot = { | |||
1307 | .recvmsg = dccp_recvmsg, | 1154 | .recvmsg = dccp_recvmsg, |
1308 | .backlog_rcv = dccp_v4_do_rcv, | 1155 | .backlog_rcv = dccp_v4_do_rcv, |
1309 | .hash = dccp_v4_hash, | 1156 | .hash = dccp_v4_hash, |
1310 | .unhash = dccp_v4_unhash, | 1157 | .unhash = dccp_unhash, |
1311 | .accept = inet_csk_accept, | 1158 | .accept = inet_csk_accept, |
1312 | .get_port = dccp_v4_get_port, | 1159 | .get_port = dccp_v4_get_port, |
1313 | .shutdown = dccp_shutdown, | 1160 | .shutdown = dccp_shutdown, |
@@ -1316,5 +1163,7 @@ struct proto dccp_v4_prot = { | |||
1316 | .max_header = MAX_DCCP_HEADER, | 1163 | .max_header = MAX_DCCP_HEADER, |
1317 | .obj_size = sizeof(struct dccp_sock), | 1164 | .obj_size = sizeof(struct dccp_sock), |
1318 | .rsk_prot = &dccp_request_sock_ops, | 1165 | .rsk_prot = &dccp_request_sock_ops, |
1319 | .twsk_obj_size = sizeof(struct inet_timewait_sock), | 1166 | .twsk_prot = &dccp_timewait_sock_ops, |
1320 | }; | 1167 | }; |
1168 | |||
1169 | EXPORT_SYMBOL_GPL(dccp_prot); | ||
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c new file mode 100644 index 000000000000..c609dc78f487 --- /dev/null +++ b/net/dccp/ipv6.c | |||
@@ -0,0 +1,1261 @@ | |||
1 | /* | ||
2 | * DCCP over IPv6 | ||
3 | * Linux INET6 implementation | ||
4 | * | ||
5 | * Based on net/dccp6/ipv6.c | ||
6 | * | ||
7 | * Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | */ | ||
14 | |||
15 | #include <linux/config.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/random.h> | ||
18 | #include <linux/xfrm.h> | ||
19 | |||
20 | #include <net/addrconf.h> | ||
21 | #include <net/inet_common.h> | ||
22 | #include <net/inet_hashtables.h> | ||
23 | #include <net/inet_sock.h> | ||
24 | #include <net/inet6_connection_sock.h> | ||
25 | #include <net/inet6_hashtables.h> | ||
26 | #include <net/ip6_route.h> | ||
27 | #include <net/ipv6.h> | ||
28 | #include <net/protocol.h> | ||
29 | #include <net/transp_v6.h> | ||
30 | #include <net/xfrm.h> | ||
31 | |||
32 | #include "dccp.h" | ||
33 | #include "ipv6.h" | ||
34 | |||
35 | static void dccp_v6_ctl_send_reset(struct sk_buff *skb); | ||
36 | static void dccp_v6_reqsk_send_ack(struct sk_buff *skb, | ||
37 | struct request_sock *req); | ||
38 | static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb); | ||
39 | |||
40 | static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); | ||
41 | |||
42 | static struct inet_connection_sock_af_ops dccp_ipv6_mapped; | ||
43 | static struct inet_connection_sock_af_ops dccp_ipv6_af_ops; | ||
44 | |||
45 | static int dccp_v6_get_port(struct sock *sk, unsigned short snum) | ||
46 | { | ||
47 | return inet_csk_get_port(&dccp_hashinfo, sk, snum, | ||
48 | inet6_csk_bind_conflict); | ||
49 | } | ||
50 | |||
51 | static void dccp_v6_hash(struct sock *sk) | ||
52 | { | ||
53 | if (sk->sk_state != DCCP_CLOSED) { | ||
54 | if (inet_csk(sk)->icsk_af_ops == &dccp_ipv6_mapped) { | ||
55 | dccp_prot.hash(sk); | ||
56 | return; | ||
57 | } | ||
58 | local_bh_disable(); | ||
59 | __inet6_hash(&dccp_hashinfo, sk); | ||
60 | local_bh_enable(); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | static inline u16 dccp_v6_check(struct dccp_hdr *dh, int len, | ||
65 | struct in6_addr *saddr, | ||
66 | struct in6_addr *daddr, | ||
67 | unsigned long base) | ||
68 | { | ||
69 | return csum_ipv6_magic(saddr, daddr, len, IPPROTO_DCCP, base); | ||
70 | } | ||
71 | |||
72 | static __u32 dccp_v6_init_sequence(struct sock *sk, struct sk_buff *skb) | ||
73 | { | ||
74 | const struct dccp_hdr *dh = dccp_hdr(skb); | ||
75 | |||
76 | if (skb->protocol == htons(ETH_P_IPV6)) | ||
77 | return secure_tcpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32, | ||
78 | skb->nh.ipv6h->saddr.s6_addr32, | ||
79 | dh->dccph_dport, | ||
80 | dh->dccph_sport); | ||
81 | else | ||
82 | return secure_dccp_sequence_number(skb->nh.iph->daddr, | ||
83 | skb->nh.iph->saddr, | ||
84 | dh->dccph_dport, | ||
85 | dh->dccph_sport); | ||
86 | } | ||
87 | |||
88 | static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | ||
89 | int addr_len) | ||
90 | { | ||
91 | struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; | ||
92 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
93 | struct inet_sock *inet = inet_sk(sk); | ||
94 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
95 | struct dccp_sock *dp = dccp_sk(sk); | ||
96 | struct in6_addr *saddr = NULL, *final_p = NULL, final; | ||
97 | struct flowi fl; | ||
98 | struct dst_entry *dst; | ||
99 | int addr_type; | ||
100 | int err; | ||
101 | |||
102 | dp->dccps_role = DCCP_ROLE_CLIENT; | ||
103 | |||
104 | if (addr_len < SIN6_LEN_RFC2133) | ||
105 | return -EINVAL; | ||
106 | |||
107 | if (usin->sin6_family != AF_INET6) | ||
108 | return -EAFNOSUPPORT; | ||
109 | |||
110 | memset(&fl, 0, sizeof(fl)); | ||
111 | |||
112 | if (np->sndflow) { | ||
113 | fl.fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK; | ||
114 | IP6_ECN_flow_init(fl.fl6_flowlabel); | ||
115 | if (fl.fl6_flowlabel & IPV6_FLOWLABEL_MASK) { | ||
116 | struct ip6_flowlabel *flowlabel; | ||
117 | flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel); | ||
118 | if (flowlabel == NULL) | ||
119 | return -EINVAL; | ||
120 | ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst); | ||
121 | fl6_sock_release(flowlabel); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | /* | ||
126 | * connect() to INADDR_ANY means loopback (BSD'ism). | ||
127 | */ | ||
128 | |||
129 | if (ipv6_addr_any(&usin->sin6_addr)) | ||
130 | usin->sin6_addr.s6_addr[15] = 0x1; | ||
131 | |||
132 | addr_type = ipv6_addr_type(&usin->sin6_addr); | ||
133 | |||
134 | if(addr_type & IPV6_ADDR_MULTICAST) | ||
135 | return -ENETUNREACH; | ||
136 | |||
137 | if (addr_type & IPV6_ADDR_LINKLOCAL) { | ||
138 | if (addr_len >= sizeof(struct sockaddr_in6) && | ||
139 | usin->sin6_scope_id) { | ||
140 | /* If interface is set while binding, indices | ||
141 | * must coincide. | ||
142 | */ | ||
143 | if (sk->sk_bound_dev_if && | ||
144 | sk->sk_bound_dev_if != usin->sin6_scope_id) | ||
145 | return -EINVAL; | ||
146 | |||
147 | sk->sk_bound_dev_if = usin->sin6_scope_id; | ||
148 | } | ||
149 | |||
150 | /* Connect to link-local address requires an interface */ | ||
151 | if (!sk->sk_bound_dev_if) | ||
152 | return -EINVAL; | ||
153 | } | ||
154 | |||
155 | ipv6_addr_copy(&np->daddr, &usin->sin6_addr); | ||
156 | np->flow_label = fl.fl6_flowlabel; | ||
157 | |||
158 | /* | ||
159 | * DCCP over IPv4 | ||
160 | */ | ||
161 | |||
162 | if (addr_type == IPV6_ADDR_MAPPED) { | ||
163 | u32 exthdrlen = icsk->icsk_ext_hdr_len; | ||
164 | struct sockaddr_in sin; | ||
165 | |||
166 | SOCK_DEBUG(sk, "connect: ipv4 mapped\n"); | ||
167 | |||
168 | if (__ipv6_only_sock(sk)) | ||
169 | return -ENETUNREACH; | ||
170 | |||
171 | sin.sin_family = AF_INET; | ||
172 | sin.sin_port = usin->sin6_port; | ||
173 | sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3]; | ||
174 | |||
175 | icsk->icsk_af_ops = &dccp_ipv6_mapped; | ||
176 | sk->sk_backlog_rcv = dccp_v4_do_rcv; | ||
177 | |||
178 | err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin)); | ||
179 | |||
180 | if (err) { | ||
181 | icsk->icsk_ext_hdr_len = exthdrlen; | ||
182 | icsk->icsk_af_ops = &dccp_ipv6_af_ops; | ||
183 | sk->sk_backlog_rcv = dccp_v6_do_rcv; | ||
184 | goto failure; | ||
185 | } else { | ||
186 | ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF), | ||
187 | inet->saddr); | ||
188 | ipv6_addr_set(&np->rcv_saddr, 0, 0, htonl(0x0000FFFF), | ||
189 | inet->rcv_saddr); | ||
190 | } | ||
191 | |||
192 | return err; | ||
193 | } | ||
194 | |||
195 | if (!ipv6_addr_any(&np->rcv_saddr)) | ||
196 | saddr = &np->rcv_saddr; | ||
197 | |||
198 | fl.proto = IPPROTO_DCCP; | ||
199 | ipv6_addr_copy(&fl.fl6_dst, &np->daddr); | ||
200 | ipv6_addr_copy(&fl.fl6_src, saddr ? saddr : &np->saddr); | ||
201 | fl.oif = sk->sk_bound_dev_if; | ||
202 | fl.fl_ip_dport = usin->sin6_port; | ||
203 | fl.fl_ip_sport = inet->sport; | ||
204 | |||
205 | if (np->opt && np->opt->srcrt) { | ||
206 | struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt; | ||
207 | ipv6_addr_copy(&final, &fl.fl6_dst); | ||
208 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); | ||
209 | final_p = &final; | ||
210 | } | ||
211 | |||
212 | err = ip6_dst_lookup(sk, &dst, &fl); | ||
213 | if (err) | ||
214 | goto failure; | ||
215 | if (final_p) | ||
216 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
217 | |||
218 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) | ||
219 | goto failure; | ||
220 | |||
221 | if (saddr == NULL) { | ||
222 | saddr = &fl.fl6_src; | ||
223 | ipv6_addr_copy(&np->rcv_saddr, saddr); | ||
224 | } | ||
225 | |||
226 | /* set the source address */ | ||
227 | ipv6_addr_copy(&np->saddr, saddr); | ||
228 | inet->rcv_saddr = LOOPBACK4_IPV6; | ||
229 | |||
230 | ip6_dst_store(sk, dst, NULL); | ||
231 | |||
232 | icsk->icsk_ext_hdr_len = 0; | ||
233 | if (np->opt) | ||
234 | icsk->icsk_ext_hdr_len = (np->opt->opt_flen + | ||
235 | np->opt->opt_nflen); | ||
236 | |||
237 | inet->dport = usin->sin6_port; | ||
238 | |||
239 | dccp_set_state(sk, DCCP_REQUESTING); | ||
240 | err = inet6_hash_connect(&dccp_death_row, sk); | ||
241 | if (err) | ||
242 | goto late_failure; | ||
243 | /* FIXME */ | ||
244 | #if 0 | ||
245 | dp->dccps_gar = secure_dccp_v6_sequence_number(np->saddr.s6_addr32, | ||
246 | np->daddr.s6_addr32, | ||
247 | inet->sport, | ||
248 | inet->dport); | ||
249 | #endif | ||
250 | err = dccp_connect(sk); | ||
251 | if (err) | ||
252 | goto late_failure; | ||
253 | |||
254 | return 0; | ||
255 | |||
256 | late_failure: | ||
257 | dccp_set_state(sk, DCCP_CLOSED); | ||
258 | __sk_dst_reset(sk); | ||
259 | failure: | ||
260 | inet->dport = 0; | ||
261 | sk->sk_route_caps = 0; | ||
262 | return err; | ||
263 | } | ||
264 | |||
265 | static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | ||
266 | int type, int code, int offset, __u32 info) | ||
267 | { | ||
268 | struct ipv6hdr *hdr = (struct ipv6hdr *)skb->data; | ||
269 | const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset); | ||
270 | struct ipv6_pinfo *np; | ||
271 | struct sock *sk; | ||
272 | int err; | ||
273 | __u64 seq; | ||
274 | |||
275 | sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport, | ||
276 | &hdr->saddr, dh->dccph_sport, skb->dev->ifindex); | ||
277 | |||
278 | if (sk == NULL) { | ||
279 | ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); | ||
280 | return; | ||
281 | } | ||
282 | |||
283 | if (sk->sk_state == DCCP_TIME_WAIT) { | ||
284 | inet_twsk_put((struct inet_timewait_sock *)sk); | ||
285 | return; | ||
286 | } | ||
287 | |||
288 | bh_lock_sock(sk); | ||
289 | if (sock_owned_by_user(sk)) | ||
290 | NET_INC_STATS_BH(LINUX_MIB_LOCKDROPPEDICMPS); | ||
291 | |||
292 | if (sk->sk_state == DCCP_CLOSED) | ||
293 | goto out; | ||
294 | |||
295 | np = inet6_sk(sk); | ||
296 | |||
297 | if (type == ICMPV6_PKT_TOOBIG) { | ||
298 | struct dst_entry *dst = NULL; | ||
299 | |||
300 | if (sock_owned_by_user(sk)) | ||
301 | goto out; | ||
302 | if ((1 << sk->sk_state) & (DCCPF_LISTEN | DCCPF_CLOSED)) | ||
303 | goto out; | ||
304 | |||
305 | /* icmp should have updated the destination cache entry */ | ||
306 | dst = __sk_dst_check(sk, np->dst_cookie); | ||
307 | |||
308 | if (dst == NULL) { | ||
309 | struct inet_sock *inet = inet_sk(sk); | ||
310 | struct flowi fl; | ||
311 | |||
312 | /* BUGGG_FUTURE: Again, it is not clear how | ||
313 | to handle rthdr case. Ignore this complexity | ||
314 | for now. | ||
315 | */ | ||
316 | memset(&fl, 0, sizeof(fl)); | ||
317 | fl.proto = IPPROTO_DCCP; | ||
318 | ipv6_addr_copy(&fl.fl6_dst, &np->daddr); | ||
319 | ipv6_addr_copy(&fl.fl6_src, &np->saddr); | ||
320 | fl.oif = sk->sk_bound_dev_if; | ||
321 | fl.fl_ip_dport = inet->dport; | ||
322 | fl.fl_ip_sport = inet->sport; | ||
323 | |||
324 | if ((err = ip6_dst_lookup(sk, &dst, &fl))) { | ||
325 | sk->sk_err_soft = -err; | ||
326 | goto out; | ||
327 | } | ||
328 | |||
329 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | ||
330 | sk->sk_err_soft = -err; | ||
331 | goto out; | ||
332 | } | ||
333 | |||
334 | } else | ||
335 | dst_hold(dst); | ||
336 | |||
337 | if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) { | ||
338 | dccp_sync_mss(sk, dst_mtu(dst)); | ||
339 | } /* else let the usual retransmit timer handle it */ | ||
340 | dst_release(dst); | ||
341 | goto out; | ||
342 | } | ||
343 | |||
344 | icmpv6_err_convert(type, code, &err); | ||
345 | |||
346 | seq = DCCP_SKB_CB(skb)->dccpd_seq; | ||
347 | /* Might be for an request_sock */ | ||
348 | switch (sk->sk_state) { | ||
349 | struct request_sock *req, **prev; | ||
350 | case DCCP_LISTEN: | ||
351 | if (sock_owned_by_user(sk)) | ||
352 | goto out; | ||
353 | |||
354 | req = inet6_csk_search_req(sk, &prev, dh->dccph_dport, | ||
355 | &hdr->daddr, &hdr->saddr, | ||
356 | inet6_iif(skb)); | ||
357 | if (!req) | ||
358 | goto out; | ||
359 | |||
360 | /* ICMPs are not backlogged, hence we cannot get | ||
361 | * an established socket here. | ||
362 | */ | ||
363 | BUG_TRAP(req->sk == NULL); | ||
364 | |||
365 | if (seq != dccp_rsk(req)->dreq_iss) { | ||
366 | NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS); | ||
367 | goto out; | ||
368 | } | ||
369 | |||
370 | inet_csk_reqsk_queue_drop(sk, req, prev); | ||
371 | goto out; | ||
372 | |||
373 | case DCCP_REQUESTING: | ||
374 | case DCCP_RESPOND: /* Cannot happen. | ||
375 | It can, it SYNs are crossed. --ANK */ | ||
376 | if (!sock_owned_by_user(sk)) { | ||
377 | DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS); | ||
378 | sk->sk_err = err; | ||
379 | /* | ||
380 | * Wake people up to see the error | ||
381 | * (see connect in sock.c) | ||
382 | */ | ||
383 | sk->sk_error_report(sk); | ||
384 | |||
385 | dccp_done(sk); | ||
386 | } else | ||
387 | sk->sk_err_soft = err; | ||
388 | goto out; | ||
389 | } | ||
390 | |||
391 | if (!sock_owned_by_user(sk) && np->recverr) { | ||
392 | sk->sk_err = err; | ||
393 | sk->sk_error_report(sk); | ||
394 | } else | ||
395 | sk->sk_err_soft = err; | ||
396 | |||
397 | out: | ||
398 | bh_unlock_sock(sk); | ||
399 | sock_put(sk); | ||
400 | } | ||
401 | |||
402 | |||
403 | static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, | ||
404 | struct dst_entry *dst) | ||
405 | { | ||
406 | struct inet6_request_sock *ireq6 = inet6_rsk(req); | ||
407 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
408 | struct sk_buff *skb; | ||
409 | struct ipv6_txoptions *opt = NULL; | ||
410 | struct in6_addr *final_p = NULL, final; | ||
411 | struct flowi fl; | ||
412 | int err = -1; | ||
413 | |||
414 | memset(&fl, 0, sizeof(fl)); | ||
415 | fl.proto = IPPROTO_DCCP; | ||
416 | ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); | ||
417 | ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr); | ||
418 | fl.fl6_flowlabel = 0; | ||
419 | fl.oif = ireq6->iif; | ||
420 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; | ||
421 | fl.fl_ip_sport = inet_sk(sk)->sport; | ||
422 | |||
423 | if (dst == NULL) { | ||
424 | opt = np->opt; | ||
425 | if (opt == NULL && | ||
426 | np->rxopt.bits.osrcrt == 2 && | ||
427 | ireq6->pktopts) { | ||
428 | struct sk_buff *pktopts = ireq6->pktopts; | ||
429 | struct inet6_skb_parm *rxopt = IP6CB(pktopts); | ||
430 | if (rxopt->srcrt) | ||
431 | opt = ipv6_invert_rthdr(sk, | ||
432 | (struct ipv6_rt_hdr *)(pktopts->nh.raw + | ||
433 | rxopt->srcrt)); | ||
434 | } | ||
435 | |||
436 | if (opt && opt->srcrt) { | ||
437 | struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt; | ||
438 | ipv6_addr_copy(&final, &fl.fl6_dst); | ||
439 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); | ||
440 | final_p = &final; | ||
441 | } | ||
442 | |||
443 | err = ip6_dst_lookup(sk, &dst, &fl); | ||
444 | if (err) | ||
445 | goto done; | ||
446 | if (final_p) | ||
447 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
448 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) | ||
449 | goto done; | ||
450 | } | ||
451 | |||
452 | skb = dccp_make_response(sk, dst, req); | ||
453 | if (skb != NULL) { | ||
454 | struct dccp_hdr *dh = dccp_hdr(skb); | ||
455 | dh->dccph_checksum = dccp_v6_check(dh, skb->len, | ||
456 | &ireq6->loc_addr, | ||
457 | &ireq6->rmt_addr, | ||
458 | csum_partial((char *)dh, | ||
459 | skb->len, | ||
460 | skb->csum)); | ||
461 | ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); | ||
462 | err = ip6_xmit(sk, skb, &fl, opt, 0); | ||
463 | if (err == NET_XMIT_CN) | ||
464 | err = 0; | ||
465 | } | ||
466 | |||
467 | done: | ||
468 | if (opt && opt != np->opt) | ||
469 | sock_kfree_s(sk, opt, opt->tot_len); | ||
470 | return err; | ||
471 | } | ||
472 | |||
473 | static void dccp_v6_reqsk_destructor(struct request_sock *req) | ||
474 | { | ||
475 | if (inet6_rsk(req)->pktopts != NULL) | ||
476 | kfree_skb(inet6_rsk(req)->pktopts); | ||
477 | } | ||
478 | |||
479 | static struct request_sock_ops dccp6_request_sock_ops = { | ||
480 | .family = AF_INET6, | ||
481 | .obj_size = sizeof(struct dccp6_request_sock), | ||
482 | .rtx_syn_ack = dccp_v6_send_response, | ||
483 | .send_ack = dccp_v6_reqsk_send_ack, | ||
484 | .destructor = dccp_v6_reqsk_destructor, | ||
485 | .send_reset = dccp_v6_ctl_send_reset, | ||
486 | }; | ||
487 | |||
488 | static struct timewait_sock_ops dccp6_timewait_sock_ops = { | ||
489 | .twsk_obj_size = sizeof(struct dccp6_timewait_sock), | ||
490 | }; | ||
491 | |||
492 | static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb) | ||
493 | { | ||
494 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
495 | struct dccp_hdr *dh = dccp_hdr(skb); | ||
496 | |||
497 | dh->dccph_checksum = csum_ipv6_magic(&np->saddr, &np->daddr, | ||
498 | len, IPPROTO_DCCP, | ||
499 | csum_partial((char *)dh, | ||
500 | dh->dccph_doff << 2, | ||
501 | skb->csum)); | ||
502 | } | ||
503 | |||
504 | static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb) | ||
505 | { | ||
506 | struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh; | ||
507 | const int dccp_hdr_reset_len = sizeof(struct dccp_hdr) + | ||
508 | sizeof(struct dccp_hdr_ext) + | ||
509 | sizeof(struct dccp_hdr_reset); | ||
510 | struct sk_buff *skb; | ||
511 | struct flowi fl; | ||
512 | u64 seqno; | ||
513 | |||
514 | if (rxdh->dccph_type == DCCP_PKT_RESET) | ||
515 | return; | ||
516 | |||
517 | if (!ipv6_unicast_destination(rxskb)) | ||
518 | return; | ||
519 | |||
520 | /* | ||
521 | * We need to grab some memory, and put together an RST, | ||
522 | * and then put it into the queue to be sent. | ||
523 | */ | ||
524 | |||
525 | skb = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + | ||
526 | dccp_hdr_reset_len, GFP_ATOMIC); | ||
527 | if (skb == NULL) | ||
528 | return; | ||
529 | |||
530 | skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr) + | ||
531 | dccp_hdr_reset_len); | ||
532 | |||
533 | skb->h.raw = skb_push(skb, dccp_hdr_reset_len); | ||
534 | dh = dccp_hdr(skb); | ||
535 | memset(dh, 0, dccp_hdr_reset_len); | ||
536 | |||
537 | /* Swap the send and the receive. */ | ||
538 | dh->dccph_type = DCCP_PKT_RESET; | ||
539 | dh->dccph_sport = rxdh->dccph_dport; | ||
540 | dh->dccph_dport = rxdh->dccph_sport; | ||
541 | dh->dccph_doff = dccp_hdr_reset_len / 4; | ||
542 | dh->dccph_x = 1; | ||
543 | dccp_hdr_reset(skb)->dccph_reset_code = | ||
544 | DCCP_SKB_CB(rxskb)->dccpd_reset_code; | ||
545 | |||
546 | /* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */ | ||
547 | seqno = 0; | ||
548 | if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) | ||
549 | dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); | ||
550 | |||
551 | dccp_hdr_set_seq(dh, seqno); | ||
552 | dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), | ||
553 | DCCP_SKB_CB(rxskb)->dccpd_seq); | ||
554 | |||
555 | memset(&fl, 0, sizeof(fl)); | ||
556 | ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr); | ||
557 | ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr); | ||
558 | dh->dccph_checksum = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst, | ||
559 | sizeof(*dh), IPPROTO_DCCP, | ||
560 | skb->csum); | ||
561 | fl.proto = IPPROTO_DCCP; | ||
562 | fl.oif = inet6_iif(rxskb); | ||
563 | fl.fl_ip_dport = dh->dccph_dport; | ||
564 | fl.fl_ip_sport = dh->dccph_sport; | ||
565 | |||
566 | /* sk = NULL, but it is safe for now. RST socket required. */ | ||
567 | if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) { | ||
568 | if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) { | ||
569 | ip6_xmit(NULL, skb, &fl, NULL, 0); | ||
570 | DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS); | ||
571 | DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS); | ||
572 | return; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | kfree_skb(skb); | ||
577 | } | ||
578 | |||
579 | static void dccp_v6_ctl_send_ack(struct sk_buff *rxskb) | ||
580 | { | ||
581 | struct flowi fl; | ||
582 | struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh; | ||
583 | const int dccp_hdr_ack_len = sizeof(struct dccp_hdr) + | ||
584 | sizeof(struct dccp_hdr_ext) + | ||
585 | sizeof(struct dccp_hdr_ack_bits); | ||
586 | struct sk_buff *skb; | ||
587 | |||
588 | skb = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + | ||
589 | dccp_hdr_ack_len, GFP_ATOMIC); | ||
590 | if (skb == NULL) | ||
591 | return; | ||
592 | |||
593 | skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr) + | ||
594 | dccp_hdr_ack_len); | ||
595 | |||
596 | skb->h.raw = skb_push(skb, dccp_hdr_ack_len); | ||
597 | dh = dccp_hdr(skb); | ||
598 | memset(dh, 0, dccp_hdr_ack_len); | ||
599 | |||
600 | /* Build DCCP header and checksum it. */ | ||
601 | dh->dccph_type = DCCP_PKT_ACK; | ||
602 | dh->dccph_sport = rxdh->dccph_dport; | ||
603 | dh->dccph_dport = rxdh->dccph_sport; | ||
604 | dh->dccph_doff = dccp_hdr_ack_len / 4; | ||
605 | dh->dccph_x = 1; | ||
606 | |||
607 | dccp_hdr_set_seq(dh, DCCP_SKB_CB(rxskb)->dccpd_ack_seq); | ||
608 | dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), | ||
609 | DCCP_SKB_CB(rxskb)->dccpd_seq); | ||
610 | |||
611 | memset(&fl, 0, sizeof(fl)); | ||
612 | ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr); | ||
613 | ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr); | ||
614 | |||
615 | /* FIXME: calculate checksum, IPv4 also should... */ | ||
616 | |||
617 | fl.proto = IPPROTO_DCCP; | ||
618 | fl.oif = inet6_iif(rxskb); | ||
619 | fl.fl_ip_dport = dh->dccph_dport; | ||
620 | fl.fl_ip_sport = dh->dccph_sport; | ||
621 | |||
622 | if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) { | ||
623 | if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) { | ||
624 | ip6_xmit(NULL, skb, &fl, NULL, 0); | ||
625 | DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS); | ||
626 | return; | ||
627 | } | ||
628 | } | ||
629 | |||
630 | kfree_skb(skb); | ||
631 | } | ||
632 | |||
633 | static void dccp_v6_reqsk_send_ack(struct sk_buff *skb, | ||
634 | struct request_sock *req) | ||
635 | { | ||
636 | dccp_v6_ctl_send_ack(skb); | ||
637 | } | ||
638 | |||
639 | static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) | ||
640 | { | ||
641 | const struct dccp_hdr *dh = dccp_hdr(skb); | ||
642 | const struct ipv6hdr *iph = skb->nh.ipv6h; | ||
643 | struct sock *nsk; | ||
644 | struct request_sock **prev; | ||
645 | /* Find possible connection requests. */ | ||
646 | struct request_sock *req = inet6_csk_search_req(sk, &prev, | ||
647 | dh->dccph_sport, | ||
648 | &iph->saddr, | ||
649 | &iph->daddr, | ||
650 | inet6_iif(skb)); | ||
651 | if (req != NULL) | ||
652 | return dccp_check_req(sk, skb, req, prev); | ||
653 | |||
654 | nsk = __inet6_lookup_established(&dccp_hashinfo, | ||
655 | &iph->saddr, dh->dccph_sport, | ||
656 | &iph->daddr, ntohs(dh->dccph_dport), | ||
657 | inet6_iif(skb)); | ||
658 | |||
659 | if (nsk != NULL) { | ||
660 | if (nsk->sk_state != DCCP_TIME_WAIT) { | ||
661 | bh_lock_sock(nsk); | ||
662 | return nsk; | ||
663 | } | ||
664 | inet_twsk_put((struct inet_timewait_sock *)nsk); | ||
665 | return NULL; | ||
666 | } | ||
667 | |||
668 | return sk; | ||
669 | } | ||
670 | |||
671 | static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | ||
672 | { | ||
673 | struct inet_request_sock *ireq; | ||
674 | struct dccp_sock dp; | ||
675 | struct request_sock *req; | ||
676 | struct dccp_request_sock *dreq; | ||
677 | struct inet6_request_sock *ireq6; | ||
678 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
679 | const __u32 service = dccp_hdr_request(skb)->dccph_req_service; | ||
680 | struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); | ||
681 | __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY; | ||
682 | |||
683 | if (skb->protocol == htons(ETH_P_IP)) | ||
684 | return dccp_v4_conn_request(sk, skb); | ||
685 | |||
686 | if (!ipv6_unicast_destination(skb)) | ||
687 | goto drop; | ||
688 | |||
689 | if (dccp_bad_service_code(sk, service)) { | ||
690 | reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE; | ||
691 | goto drop; | ||
692 | } | ||
693 | /* | ||
694 | * There are no SYN attacks on IPv6, yet... | ||
695 | */ | ||
696 | if (inet_csk_reqsk_queue_is_full(sk)) | ||
697 | goto drop; | ||
698 | |||
699 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) | ||
700 | goto drop; | ||
701 | |||
702 | req = inet6_reqsk_alloc(sk->sk_prot->rsk_prot); | ||
703 | if (req == NULL) | ||
704 | goto drop; | ||
705 | |||
706 | /* FIXME: process options */ | ||
707 | |||
708 | dccp_openreq_init(req, &dp, skb); | ||
709 | |||
710 | ireq6 = inet6_rsk(req); | ||
711 | ireq = inet_rsk(req); | ||
712 | ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr); | ||
713 | ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr); | ||
714 | req->rcv_wnd = 100; /* Fake, option parsing will get the | ||
715 | right value */ | ||
716 | ireq6->pktopts = NULL; | ||
717 | |||
718 | if (ipv6_opt_accepted(sk, skb) || | ||
719 | np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || | ||
720 | np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { | ||
721 | atomic_inc(&skb->users); | ||
722 | ireq6->pktopts = skb; | ||
723 | } | ||
724 | ireq6->iif = sk->sk_bound_dev_if; | ||
725 | |||
726 | /* So that link locals have meaning */ | ||
727 | if (!sk->sk_bound_dev_if && | ||
728 | ipv6_addr_type(&ireq6->rmt_addr) & IPV6_ADDR_LINKLOCAL) | ||
729 | ireq6->iif = inet6_iif(skb); | ||
730 | |||
731 | /* | ||
732 | * Step 3: Process LISTEN state | ||
733 | * | ||
734 | * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie | ||
735 | * | ||
736 | * In fact we defer setting S.GSR, S.SWL, S.SWH to | ||
737 | * dccp_create_openreq_child. | ||
738 | */ | ||
739 | dreq = dccp_rsk(req); | ||
740 | dreq->dreq_isr = dcb->dccpd_seq; | ||
741 | dreq->dreq_iss = dccp_v6_init_sequence(sk, skb); | ||
742 | dreq->dreq_service = service; | ||
743 | |||
744 | if (dccp_v6_send_response(sk, req, NULL)) | ||
745 | goto drop_and_free; | ||
746 | |||
747 | inet6_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT); | ||
748 | return 0; | ||
749 | |||
750 | drop_and_free: | ||
751 | reqsk_free(req); | ||
752 | drop: | ||
753 | DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS); | ||
754 | dcb->dccpd_reset_code = reset_code; | ||
755 | return -1; | ||
756 | } | ||
757 | |||
758 | static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | ||
759 | struct sk_buff *skb, | ||
760 | struct request_sock *req, | ||
761 | struct dst_entry *dst) | ||
762 | { | ||
763 | struct inet6_request_sock *ireq6 = inet6_rsk(req); | ||
764 | struct ipv6_pinfo *newnp, *np = inet6_sk(sk); | ||
765 | struct inet_sock *newinet; | ||
766 | struct dccp_sock *newdp; | ||
767 | struct dccp6_sock *newdp6; | ||
768 | struct sock *newsk; | ||
769 | struct ipv6_txoptions *opt; | ||
770 | |||
771 | if (skb->protocol == htons(ETH_P_IP)) { | ||
772 | /* | ||
773 | * v6 mapped | ||
774 | */ | ||
775 | |||
776 | newsk = dccp_v4_request_recv_sock(sk, skb, req, dst); | ||
777 | if (newsk == NULL) | ||
778 | return NULL; | ||
779 | |||
780 | newdp6 = (struct dccp6_sock *)newsk; | ||
781 | newdp = dccp_sk(newsk); | ||
782 | newinet = inet_sk(newsk); | ||
783 | newinet->pinet6 = &newdp6->inet6; | ||
784 | newnp = inet6_sk(newsk); | ||
785 | |||
786 | memcpy(newnp, np, sizeof(struct ipv6_pinfo)); | ||
787 | |||
788 | ipv6_addr_set(&newnp->daddr, 0, 0, htonl(0x0000FFFF), | ||
789 | newinet->daddr); | ||
790 | |||
791 | ipv6_addr_set(&newnp->saddr, 0, 0, htonl(0x0000FFFF), | ||
792 | newinet->saddr); | ||
793 | |||
794 | ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr); | ||
795 | |||
796 | inet_csk(newsk)->icsk_af_ops = &dccp_ipv6_mapped; | ||
797 | newsk->sk_backlog_rcv = dccp_v4_do_rcv; | ||
798 | newnp->pktoptions = NULL; | ||
799 | newnp->opt = NULL; | ||
800 | newnp->mcast_oif = inet6_iif(skb); | ||
801 | newnp->mcast_hops = skb->nh.ipv6h->hop_limit; | ||
802 | |||
803 | /* | ||
804 | * No need to charge this sock to the relevant IPv6 refcnt debug socks count | ||
805 | * here, dccp_create_openreq_child now does this for us, see the comment in | ||
806 | * that function for the gory details. -acme | ||
807 | */ | ||
808 | |||
809 | /* It is tricky place. Until this moment IPv4 tcp | ||
810 | worked with IPv6 icsk.icsk_af_ops. | ||
811 | Sync it now. | ||
812 | */ | ||
813 | dccp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie); | ||
814 | |||
815 | return newsk; | ||
816 | } | ||
817 | |||
818 | opt = np->opt; | ||
819 | |||
820 | if (sk_acceptq_is_full(sk)) | ||
821 | goto out_overflow; | ||
822 | |||
823 | if (np->rxopt.bits.osrcrt == 2 && | ||
824 | opt == NULL && ireq6->pktopts) { | ||
825 | struct inet6_skb_parm *rxopt = IP6CB(ireq6->pktopts); | ||
826 | if (rxopt->srcrt) | ||
827 | opt = ipv6_invert_rthdr(sk, | ||
828 | (struct ipv6_rt_hdr *)(ireq6->pktopts->nh.raw + | ||
829 | rxopt->srcrt)); | ||
830 | } | ||
831 | |||
832 | if (dst == NULL) { | ||
833 | struct in6_addr *final_p = NULL, final; | ||
834 | struct flowi fl; | ||
835 | |||
836 | memset(&fl, 0, sizeof(fl)); | ||
837 | fl.proto = IPPROTO_DCCP; | ||
838 | ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); | ||
839 | if (opt && opt->srcrt) { | ||
840 | struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; | ||
841 | ipv6_addr_copy(&final, &fl.fl6_dst); | ||
842 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); | ||
843 | final_p = &final; | ||
844 | } | ||
845 | ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr); | ||
846 | fl.oif = sk->sk_bound_dev_if; | ||
847 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; | ||
848 | fl.fl_ip_sport = inet_sk(sk)->sport; | ||
849 | |||
850 | if (ip6_dst_lookup(sk, &dst, &fl)) | ||
851 | goto out; | ||
852 | |||
853 | if (final_p) | ||
854 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
855 | |||
856 | if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0) | ||
857 | goto out; | ||
858 | } | ||
859 | |||
860 | newsk = dccp_create_openreq_child(sk, req, skb); | ||
861 | if (newsk == NULL) | ||
862 | goto out; | ||
863 | |||
864 | /* | ||
865 | * No need to charge this sock to the relevant IPv6 refcnt debug socks | ||
866 | * count here, dccp_create_openreq_child now does this for us, see the | ||
867 | * comment in that function for the gory details. -acme | ||
868 | */ | ||
869 | |||
870 | ip6_dst_store(newsk, dst, NULL); | ||
871 | newsk->sk_route_caps = dst->dev->features & | ||
872 | ~(NETIF_F_IP_CSUM | NETIF_F_TSO); | ||
873 | |||
874 | newdp6 = (struct dccp6_sock *)newsk; | ||
875 | newinet = inet_sk(newsk); | ||
876 | newinet->pinet6 = &newdp6->inet6; | ||
877 | newdp = dccp_sk(newsk); | ||
878 | newnp = inet6_sk(newsk); | ||
879 | |||
880 | memcpy(newnp, np, sizeof(struct ipv6_pinfo)); | ||
881 | |||
882 | ipv6_addr_copy(&newnp->daddr, &ireq6->rmt_addr); | ||
883 | ipv6_addr_copy(&newnp->saddr, &ireq6->loc_addr); | ||
884 | ipv6_addr_copy(&newnp->rcv_saddr, &ireq6->loc_addr); | ||
885 | newsk->sk_bound_dev_if = ireq6->iif; | ||
886 | |||
887 | /* Now IPv6 options... | ||
888 | |||
889 | First: no IPv4 options. | ||
890 | */ | ||
891 | newinet->opt = NULL; | ||
892 | |||
893 | /* Clone RX bits */ | ||
894 | newnp->rxopt.all = np->rxopt.all; | ||
895 | |||
896 | /* Clone pktoptions received with SYN */ | ||
897 | newnp->pktoptions = NULL; | ||
898 | if (ireq6->pktopts != NULL) { | ||
899 | newnp->pktoptions = skb_clone(ireq6->pktopts, GFP_ATOMIC); | ||
900 | kfree_skb(ireq6->pktopts); | ||
901 | ireq6->pktopts = NULL; | ||
902 | if (newnp->pktoptions) | ||
903 | skb_set_owner_r(newnp->pktoptions, newsk); | ||
904 | } | ||
905 | newnp->opt = NULL; | ||
906 | newnp->mcast_oif = inet6_iif(skb); | ||
907 | newnp->mcast_hops = skb->nh.ipv6h->hop_limit; | ||
908 | |||
909 | /* Clone native IPv6 options from listening socket (if any) | ||
910 | |||
911 | Yes, keeping reference count would be much more clever, | ||
912 | but we make one more one thing there: reattach optmem | ||
913 | to newsk. | ||
914 | */ | ||
915 | if (opt) { | ||
916 | newnp->opt = ipv6_dup_options(newsk, opt); | ||
917 | if (opt != np->opt) | ||
918 | sock_kfree_s(sk, opt, opt->tot_len); | ||
919 | } | ||
920 | |||
921 | inet_csk(newsk)->icsk_ext_hdr_len = 0; | ||
922 | if (newnp->opt) | ||
923 | inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + | ||
924 | newnp->opt->opt_flen); | ||
925 | |||
926 | dccp_sync_mss(newsk, dst_mtu(dst)); | ||
927 | |||
928 | newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6; | ||
929 | |||
930 | __inet6_hash(&dccp_hashinfo, newsk); | ||
931 | inet_inherit_port(&dccp_hashinfo, sk, newsk); | ||
932 | |||
933 | return newsk; | ||
934 | |||
935 | out_overflow: | ||
936 | NET_INC_STATS_BH(LINUX_MIB_LISTENOVERFLOWS); | ||
937 | out: | ||
938 | NET_INC_STATS_BH(LINUX_MIB_LISTENDROPS); | ||
939 | if (opt && opt != np->opt) | ||
940 | sock_kfree_s(sk, opt, opt->tot_len); | ||
941 | dst_release(dst); | ||
942 | return NULL; | ||
943 | } | ||
944 | |||
945 | /* The socket must have it's spinlock held when we get | ||
946 | * here. | ||
947 | * | ||
948 | * We have a potential double-lock case here, so even when | ||
949 | * doing backlog processing we use the BH locking scheme. | ||
950 | * This is because we cannot sleep with the original spinlock | ||
951 | * held. | ||
952 | */ | ||
953 | static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | ||
954 | { | ||
955 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
956 | struct sk_buff *opt_skb = NULL; | ||
957 | |||
958 | /* Imagine: socket is IPv6. IPv4 packet arrives, | ||
959 | goes to IPv4 receive handler and backlogged. | ||
960 | From backlog it always goes here. Kerboom... | ||
961 | Fortunately, dccp_rcv_established and rcv_established | ||
962 | handle them correctly, but it is not case with | ||
963 | dccp_v6_hnd_req and dccp_v6_ctl_send_reset(). --ANK | ||
964 | */ | ||
965 | |||
966 | if (skb->protocol == htons(ETH_P_IP)) | ||
967 | return dccp_v4_do_rcv(sk, skb); | ||
968 | |||
969 | if (sk_filter(sk, skb, 0)) | ||
970 | goto discard; | ||
971 | |||
972 | /* | ||
973 | * socket locking is here for SMP purposes as backlog rcv | ||
974 | * is currently called with bh processing disabled. | ||
975 | */ | ||
976 | |||
977 | /* Do Stevens' IPV6_PKTOPTIONS. | ||
978 | |||
979 | Yes, guys, it is the only place in our code, where we | ||
980 | may make it not affecting IPv4. | ||
981 | The rest of code is protocol independent, | ||
982 | and I do not like idea to uglify IPv4. | ||
983 | |||
984 | Actually, all the idea behind IPV6_PKTOPTIONS | ||
985 | looks not very well thought. For now we latch | ||
986 | options, received in the last packet, enqueued | ||
987 | by tcp. Feel free to propose better solution. | ||
988 | --ANK (980728) | ||
989 | */ | ||
990 | if (np->rxopt.all) | ||
991 | opt_skb = skb_clone(skb, GFP_ATOMIC); | ||
992 | |||
993 | if (sk->sk_state == DCCP_OPEN) { /* Fast path */ | ||
994 | if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len)) | ||
995 | goto reset; | ||
996 | return 0; | ||
997 | } | ||
998 | |||
999 | if (sk->sk_state == DCCP_LISTEN) { | ||
1000 | struct sock *nsk = dccp_v6_hnd_req(sk, skb); | ||
1001 | if (!nsk) | ||
1002 | goto discard; | ||
1003 | |||
1004 | /* | ||
1005 | * Queue it on the new socket if the new socket is active, | ||
1006 | * otherwise we just shortcircuit this and continue with | ||
1007 | * the new socket.. | ||
1008 | */ | ||
1009 | if(nsk != sk) { | ||
1010 | if (dccp_child_process(sk, nsk, skb)) | ||
1011 | goto reset; | ||
1012 | if (opt_skb) | ||
1013 | __kfree_skb(opt_skb); | ||
1014 | return 0; | ||
1015 | } | ||
1016 | } | ||
1017 | |||
1018 | if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len)) | ||
1019 | goto reset; | ||
1020 | return 0; | ||
1021 | |||
1022 | reset: | ||
1023 | dccp_v6_ctl_send_reset(skb); | ||
1024 | discard: | ||
1025 | if (opt_skb) | ||
1026 | __kfree_skb(opt_skb); | ||
1027 | kfree_skb(skb); | ||
1028 | return 0; | ||
1029 | } | ||
1030 | |||
1031 | static int dccp_v6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) | ||
1032 | { | ||
1033 | const struct dccp_hdr *dh; | ||
1034 | struct sk_buff *skb = *pskb; | ||
1035 | struct sock *sk; | ||
1036 | |||
1037 | /* Step 1: Check header basics: */ | ||
1038 | |||
1039 | if (dccp_invalid_packet(skb)) | ||
1040 | goto discard_it; | ||
1041 | |||
1042 | dh = dccp_hdr(skb); | ||
1043 | |||
1044 | DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb); | ||
1045 | DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type; | ||
1046 | |||
1047 | if (dccp_packet_without_ack(skb)) | ||
1048 | DCCP_SKB_CB(skb)->dccpd_ack_seq = DCCP_PKT_WITHOUT_ACK_SEQ; | ||
1049 | else | ||
1050 | DCCP_SKB_CB(skb)->dccpd_ack_seq = dccp_hdr_ack_seq(skb); | ||
1051 | |||
1052 | /* Step 2: | ||
1053 | * Look up flow ID in table and get corresponding socket */ | ||
1054 | sk = __inet6_lookup(&dccp_hashinfo, &skb->nh.ipv6h->saddr, | ||
1055 | dh->dccph_sport, | ||
1056 | &skb->nh.ipv6h->daddr, ntohs(dh->dccph_dport), | ||
1057 | inet6_iif(skb)); | ||
1058 | /* | ||
1059 | * Step 2: | ||
1060 | * If no socket ... | ||
1061 | * Generate Reset(No Connection) unless P.type == Reset | ||
1062 | * Drop packet and return | ||
1063 | */ | ||
1064 | if (sk == NULL) | ||
1065 | goto no_dccp_socket; | ||
1066 | |||
1067 | /* | ||
1068 | * Step 2: | ||
1069 | * ... or S.state == TIMEWAIT, | ||
1070 | * Generate Reset(No Connection) unless P.type == Reset | ||
1071 | * Drop packet and return | ||
1072 | */ | ||
1073 | |||
1074 | if (sk->sk_state == DCCP_TIME_WAIT) | ||
1075 | goto do_time_wait; | ||
1076 | |||
1077 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) | ||
1078 | goto discard_and_relse; | ||
1079 | |||
1080 | return sk_receive_skb(sk, skb) ? -1 : 0; | ||
1081 | |||
1082 | no_dccp_socket: | ||
1083 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) | ||
1084 | goto discard_it; | ||
1085 | /* | ||
1086 | * Step 2: | ||
1087 | * Generate Reset(No Connection) unless P.type == Reset | ||
1088 | * Drop packet and return | ||
1089 | */ | ||
1090 | if (dh->dccph_type != DCCP_PKT_RESET) { | ||
1091 | DCCP_SKB_CB(skb)->dccpd_reset_code = | ||
1092 | DCCP_RESET_CODE_NO_CONNECTION; | ||
1093 | dccp_v6_ctl_send_reset(skb); | ||
1094 | } | ||
1095 | discard_it: | ||
1096 | |||
1097 | /* | ||
1098 | * Discard frame | ||
1099 | */ | ||
1100 | |||
1101 | kfree_skb(skb); | ||
1102 | return 0; | ||
1103 | |||
1104 | discard_and_relse: | ||
1105 | sock_put(sk); | ||
1106 | goto discard_it; | ||
1107 | |||
1108 | do_time_wait: | ||
1109 | inet_twsk_put((struct inet_timewait_sock *)sk); | ||
1110 | goto no_dccp_socket; | ||
1111 | } | ||
1112 | |||
1113 | static struct inet_connection_sock_af_ops dccp_ipv6_af_ops = { | ||
1114 | .queue_xmit = inet6_csk_xmit, | ||
1115 | .send_check = dccp_v6_send_check, | ||
1116 | .rebuild_header = inet6_sk_rebuild_header, | ||
1117 | .conn_request = dccp_v6_conn_request, | ||
1118 | .syn_recv_sock = dccp_v6_request_recv_sock, | ||
1119 | .net_header_len = sizeof(struct ipv6hdr), | ||
1120 | .setsockopt = ipv6_setsockopt, | ||
1121 | .getsockopt = ipv6_getsockopt, | ||
1122 | .addr2sockaddr = inet6_csk_addr2sockaddr, | ||
1123 | .sockaddr_len = sizeof(struct sockaddr_in6) | ||
1124 | }; | ||
1125 | |||
1126 | /* | ||
1127 | * DCCP over IPv4 via INET6 API | ||
1128 | */ | ||
1129 | static struct inet_connection_sock_af_ops dccp_ipv6_mapped = { | ||
1130 | .queue_xmit = ip_queue_xmit, | ||
1131 | .send_check = dccp_v4_send_check, | ||
1132 | .rebuild_header = inet_sk_rebuild_header, | ||
1133 | .conn_request = dccp_v6_conn_request, | ||
1134 | .syn_recv_sock = dccp_v6_request_recv_sock, | ||
1135 | .net_header_len = sizeof(struct iphdr), | ||
1136 | .setsockopt = ipv6_setsockopt, | ||
1137 | .getsockopt = ipv6_getsockopt, | ||
1138 | .addr2sockaddr = inet6_csk_addr2sockaddr, | ||
1139 | .sockaddr_len = sizeof(struct sockaddr_in6) | ||
1140 | }; | ||
1141 | |||
1142 | /* NOTE: A lot of things set to zero explicitly by call to | ||
1143 | * sk_alloc() so need not be done here. | ||
1144 | */ | ||
1145 | static int dccp_v6_init_sock(struct sock *sk) | ||
1146 | { | ||
1147 | int err = dccp_v4_init_sock(sk); | ||
1148 | |||
1149 | if (err == 0) | ||
1150 | inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops; | ||
1151 | |||
1152 | return err; | ||
1153 | } | ||
1154 | |||
1155 | static int dccp_v6_destroy_sock(struct sock *sk) | ||
1156 | { | ||
1157 | dccp_v4_destroy_sock(sk); | ||
1158 | return inet6_destroy_sock(sk); | ||
1159 | } | ||
1160 | |||
1161 | static struct proto dccp_v6_prot = { | ||
1162 | .name = "DCCPv6", | ||
1163 | .owner = THIS_MODULE, | ||
1164 | .close = dccp_close, | ||
1165 | .connect = dccp_v6_connect, | ||
1166 | .disconnect = dccp_disconnect, | ||
1167 | .ioctl = dccp_ioctl, | ||
1168 | .init = dccp_v6_init_sock, | ||
1169 | .setsockopt = dccp_setsockopt, | ||
1170 | .getsockopt = dccp_getsockopt, | ||
1171 | .sendmsg = dccp_sendmsg, | ||
1172 | .recvmsg = dccp_recvmsg, | ||
1173 | .backlog_rcv = dccp_v6_do_rcv, | ||
1174 | .hash = dccp_v6_hash, | ||
1175 | .unhash = dccp_unhash, | ||
1176 | .accept = inet_csk_accept, | ||
1177 | .get_port = dccp_v6_get_port, | ||
1178 | .shutdown = dccp_shutdown, | ||
1179 | .destroy = dccp_v6_destroy_sock, | ||
1180 | .orphan_count = &dccp_orphan_count, | ||
1181 | .max_header = MAX_DCCP_HEADER, | ||
1182 | .obj_size = sizeof(struct dccp6_sock), | ||
1183 | .rsk_prot = &dccp6_request_sock_ops, | ||
1184 | .twsk_prot = &dccp6_timewait_sock_ops, | ||
1185 | }; | ||
1186 | |||
1187 | static struct inet6_protocol dccp_v6_protocol = { | ||
1188 | .handler = dccp_v6_rcv, | ||
1189 | .err_handler = dccp_v6_err, | ||
1190 | .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL, | ||
1191 | }; | ||
1192 | |||
1193 | static struct proto_ops inet6_dccp_ops = { | ||
1194 | .family = PF_INET6, | ||
1195 | .owner = THIS_MODULE, | ||
1196 | .release = inet6_release, | ||
1197 | .bind = inet6_bind, | ||
1198 | .connect = inet_stream_connect, | ||
1199 | .socketpair = sock_no_socketpair, | ||
1200 | .accept = inet_accept, | ||
1201 | .getname = inet6_getname, | ||
1202 | .poll = dccp_poll, | ||
1203 | .ioctl = inet6_ioctl, | ||
1204 | .listen = inet_dccp_listen, | ||
1205 | .shutdown = inet_shutdown, | ||
1206 | .setsockopt = sock_common_setsockopt, | ||
1207 | .getsockopt = sock_common_getsockopt, | ||
1208 | .sendmsg = inet_sendmsg, | ||
1209 | .recvmsg = sock_common_recvmsg, | ||
1210 | .mmap = sock_no_mmap, | ||
1211 | .sendpage = sock_no_sendpage, | ||
1212 | }; | ||
1213 | |||
1214 | static struct inet_protosw dccp_v6_protosw = { | ||
1215 | .type = SOCK_DCCP, | ||
1216 | .protocol = IPPROTO_DCCP, | ||
1217 | .prot = &dccp_v6_prot, | ||
1218 | .ops = &inet6_dccp_ops, | ||
1219 | .capability = -1, | ||
1220 | .flags = INET_PROTOSW_ICSK, | ||
1221 | }; | ||
1222 | |||
1223 | static int __init dccp_v6_init(void) | ||
1224 | { | ||
1225 | int err = proto_register(&dccp_v6_prot, 1); | ||
1226 | |||
1227 | if (err != 0) | ||
1228 | goto out; | ||
1229 | |||
1230 | err = inet6_add_protocol(&dccp_v6_protocol, IPPROTO_DCCP); | ||
1231 | if (err != 0) | ||
1232 | goto out_unregister_proto; | ||
1233 | |||
1234 | inet6_register_protosw(&dccp_v6_protosw); | ||
1235 | out: | ||
1236 | return err; | ||
1237 | out_unregister_proto: | ||
1238 | proto_unregister(&dccp_v6_prot); | ||
1239 | goto out; | ||
1240 | } | ||
1241 | |||
1242 | static void __exit dccp_v6_exit(void) | ||
1243 | { | ||
1244 | inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP); | ||
1245 | inet6_unregister_protosw(&dccp_v6_protosw); | ||
1246 | proto_unregister(&dccp_v6_prot); | ||
1247 | } | ||
1248 | |||
1249 | module_init(dccp_v6_init); | ||
1250 | module_exit(dccp_v6_exit); | ||
1251 | |||
1252 | /* | ||
1253 | * __stringify doesn't likes enums, so use SOCK_DCCP (6) and IPPROTO_DCCP (33) | ||
1254 | * values directly, Also cover the case where the protocol is not specified, | ||
1255 | * i.e. net-pf-PF_INET6-proto-0-type-SOCK_DCCP | ||
1256 | */ | ||
1257 | MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-33-type-6"); | ||
1258 | MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-0-type-6"); | ||
1259 | MODULE_LICENSE("GPL"); | ||
1260 | MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>"); | ||
1261 | MODULE_DESCRIPTION("DCCPv6 - Datagram Congestion Controlled Protocol"); | ||
diff --git a/net/dccp/ipv6.h b/net/dccp/ipv6.h new file mode 100644 index 000000000000..e4d4e9309270 --- /dev/null +++ b/net/dccp/ipv6.h | |||
@@ -0,0 +1,37 @@ | |||
1 | #ifndef _DCCP_IPV6_H | ||
2 | #define _DCCP_IPV6_H | ||
3 | /* | ||
4 | * net/dccp/ipv6.h | ||
5 | * | ||
6 | * An implementation of the DCCP protocol | ||
7 | * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/dccp.h> | ||
16 | #include <linux/ipv6.h> | ||
17 | |||
18 | struct dccp6_sock { | ||
19 | struct dccp_sock dccp; | ||
20 | /* | ||
21 | * ipv6_pinfo has to be the last member of dccp6_sock, | ||
22 | * see inet6_sk_generic. | ||
23 | */ | ||
24 | struct ipv6_pinfo inet6; | ||
25 | }; | ||
26 | |||
27 | struct dccp6_request_sock { | ||
28 | struct dccp_request_sock dccp; | ||
29 | struct inet6_request_sock inet6; | ||
30 | }; | ||
31 | |||
32 | struct dccp6_timewait_sock { | ||
33 | struct inet_timewait_sock inet; | ||
34 | struct inet6_timewait_sock tw6; | ||
35 | }; | ||
36 | |||
37 | #endif /* _DCCP_IPV6_H */ | ||
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index 1393461898bb..29261fc198e7 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c | |||
@@ -40,6 +40,8 @@ struct inet_timewait_death_row dccp_death_row = { | |||
40 | (unsigned long)&dccp_death_row), | 40 | (unsigned long)&dccp_death_row), |
41 | }; | 41 | }; |
42 | 42 | ||
43 | EXPORT_SYMBOL_GPL(dccp_death_row); | ||
44 | |||
43 | void dccp_time_wait(struct sock *sk, int state, int timeo) | 45 | void dccp_time_wait(struct sock *sk, int state, int timeo) |
44 | { | 46 | { |
45 | struct inet_timewait_sock *tw = NULL; | 47 | struct inet_timewait_sock *tw = NULL; |
@@ -50,7 +52,18 @@ void dccp_time_wait(struct sock *sk, int state, int timeo) | |||
50 | if (tw != NULL) { | 52 | if (tw != NULL) { |
51 | const struct inet_connection_sock *icsk = inet_csk(sk); | 53 | const struct inet_connection_sock *icsk = inet_csk(sk); |
52 | const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1); | 54 | const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1); |
53 | 55 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | |
56 | if (tw->tw_family == PF_INET6) { | ||
57 | const struct ipv6_pinfo *np = inet6_sk(sk); | ||
58 | struct inet6_timewait_sock *tw6; | ||
59 | |||
60 | tw->tw_ipv6_offset = inet6_tw_offset(sk->sk_prot); | ||
61 | tw6 = inet6_twsk((struct sock *)tw); | ||
62 | ipv6_addr_copy(&tw6->tw_v6_daddr, &np->daddr); | ||
63 | ipv6_addr_copy(&tw6->tw_v6_rcv_saddr, &np->rcv_saddr); | ||
64 | tw->tw_ipv6only = np->ipv6only; | ||
65 | } | ||
66 | #endif | ||
54 | /* Linkage updates. */ | 67 | /* Linkage updates. */ |
55 | __inet_twsk_hashdance(tw, sk, &dccp_hashinfo); | 68 | __inet_twsk_hashdance(tw, sk, &dccp_hashinfo); |
56 | 69 | ||
@@ -170,6 +183,8 @@ out_free: | |||
170 | return newsk; | 183 | return newsk; |
171 | } | 184 | } |
172 | 185 | ||
186 | EXPORT_SYMBOL_GPL(dccp_create_openreq_child); | ||
187 | |||
173 | /* | 188 | /* |
174 | * Process an incoming packet for RESPOND sockets represented | 189 | * Process an incoming packet for RESPOND sockets represented |
175 | * as an request_sock. | 190 | * as an request_sock. |
@@ -214,7 +229,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, | |||
214 | goto drop; | 229 | goto drop; |
215 | } | 230 | } |
216 | 231 | ||
217 | child = dccp_v4_request_recv_sock(sk, skb, req, NULL); | 232 | child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL); |
218 | if (child == NULL) | 233 | if (child == NULL) |
219 | goto listen_overflow; | 234 | goto listen_overflow; |
220 | 235 | ||
@@ -236,6 +251,8 @@ drop: | |||
236 | goto out; | 251 | goto out; |
237 | } | 252 | } |
238 | 253 | ||
254 | EXPORT_SYMBOL_GPL(dccp_check_req); | ||
255 | |||
239 | /* | 256 | /* |
240 | * Queue segment on the new socket if the new socket is active, | 257 | * Queue segment on the new socket if the new socket is active, |
241 | * otherwise we just shortcircuit this and continue with | 258 | * otherwise we just shortcircuit this and continue with |
@@ -266,3 +283,5 @@ int dccp_child_process(struct sock *parent, struct sock *child, | |||
266 | sock_put(child); | 283 | sock_put(child); |
267 | return ret; | 284 | return ret; |
268 | } | 285 | } |
286 | |||
287 | EXPORT_SYMBOL_GPL(dccp_child_process); | ||
diff --git a/net/dccp/output.c b/net/dccp/output.c index 74ff87025878..efd7ffb903a1 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/skbuff.h> | 16 | #include <linux/skbuff.h> |
17 | 17 | ||
18 | #include <net/inet_sock.h> | ||
18 | #include <net/sock.h> | 19 | #include <net/sock.h> |
19 | 20 | ||
20 | #include "ackvec.h" | 21 | #include "ackvec.h" |
@@ -43,6 +44,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) | |||
43 | { | 44 | { |
44 | if (likely(skb != NULL)) { | 45 | if (likely(skb != NULL)) { |
45 | const struct inet_sock *inet = inet_sk(sk); | 46 | const struct inet_sock *inet = inet_sk(sk); |
47 | const struct inet_connection_sock *icsk = inet_csk(sk); | ||
46 | struct dccp_sock *dp = dccp_sk(sk); | 48 | struct dccp_sock *dp = dccp_sk(sk); |
47 | struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); | 49 | struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); |
48 | struct dccp_hdr *dh; | 50 | struct dccp_hdr *dh; |
@@ -108,8 +110,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) | |||
108 | break; | 110 | break; |
109 | } | 111 | } |
110 | 112 | ||
111 | dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr, | 113 | icsk->icsk_af_ops->send_check(sk, skb->len, skb); |
112 | inet->daddr); | ||
113 | 114 | ||
114 | if (set_ack) | 115 | if (set_ack) |
115 | dccp_event_ack_sent(sk); | 116 | dccp_event_ack_sent(sk); |
@@ -117,7 +118,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) | |||
117 | DCCP_INC_STATS(DCCP_MIB_OUTSEGS); | 118 | DCCP_INC_STATS(DCCP_MIB_OUTSEGS); |
118 | 119 | ||
119 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 120 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
120 | err = ip_queue_xmit(skb, 0); | 121 | err = icsk->icsk_af_ops->queue_xmit(skb, 0); |
121 | if (err <= 0) | 122 | if (err <= 0) |
122 | return err; | 123 | return err; |
123 | 124 | ||
@@ -134,20 +135,13 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) | |||
134 | 135 | ||
135 | unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu) | 136 | unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu) |
136 | { | 137 | { |
138 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
137 | struct dccp_sock *dp = dccp_sk(sk); | 139 | struct dccp_sock *dp = dccp_sk(sk); |
138 | int mss_now; | 140 | int mss_now = (pmtu - icsk->icsk_af_ops->net_header_len - |
139 | 141 | sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext)); | |
140 | /* | ||
141 | * FIXME: we really should be using the af_specific thing to support | ||
142 | * IPv6. | ||
143 | * mss_now = pmtu - tp->af_specific->net_header_len - | ||
144 | * sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext); | ||
145 | */ | ||
146 | mss_now = pmtu - sizeof(struct iphdr) - sizeof(struct dccp_hdr) - | ||
147 | sizeof(struct dccp_hdr_ext); | ||
148 | 142 | ||
149 | /* Now subtract optional transport overhead */ | 143 | /* Now subtract optional transport overhead */ |
150 | mss_now -= dp->dccps_ext_header_len; | 144 | mss_now -= icsk->icsk_ext_hdr_len; |
151 | 145 | ||
152 | /* | 146 | /* |
153 | * FIXME: this should come from the CCID infrastructure, where, say, | 147 | * FIXME: this should come from the CCID infrastructure, where, say, |
@@ -160,12 +154,14 @@ unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu) | |||
160 | mss_now -= ((5 + 6 + 10 + 6 + 6 + 6 + 3) / 4) * 4; | 154 | mss_now -= ((5 + 6 + 10 + 6 + 6 + 6 + 3) / 4) * 4; |
161 | 155 | ||
162 | /* And store cached results */ | 156 | /* And store cached results */ |
163 | dp->dccps_pmtu_cookie = pmtu; | 157 | icsk->icsk_pmtu_cookie = pmtu; |
164 | dp->dccps_mss_cache = mss_now; | 158 | dp->dccps_mss_cache = mss_now; |
165 | 159 | ||
166 | return mss_now; | 160 | return mss_now; |
167 | } | 161 | } |
168 | 162 | ||
163 | EXPORT_SYMBOL_GPL(dccp_sync_mss); | ||
164 | |||
169 | void dccp_write_space(struct sock *sk) | 165 | void dccp_write_space(struct sock *sk) |
170 | { | 166 | { |
171 | read_lock(&sk->sk_callback_lock); | 167 | read_lock(&sk->sk_callback_lock); |
@@ -266,7 +262,7 @@ int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, long *timeo) | |||
266 | 262 | ||
267 | int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | 263 | int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb) |
268 | { | 264 | { |
269 | if (inet_sk_rebuild_header(sk) != 0) | 265 | if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk) != 0) |
270 | return -EHOSTUNREACH; /* Routing failure or similar. */ | 266 | return -EHOSTUNREACH; /* Routing failure or similar. */ |
271 | 267 | ||
272 | return dccp_transmit_skb(sk, (skb_cloned(skb) ? | 268 | return dccp_transmit_skb(sk, (skb_cloned(skb) ? |
@@ -321,6 +317,8 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst, | |||
321 | return skb; | 317 | return skb; |
322 | } | 318 | } |
323 | 319 | ||
320 | EXPORT_SYMBOL_GPL(dccp_make_response); | ||
321 | |||
324 | struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst, | 322 | struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst, |
325 | const enum dccp_reset_codes code) | 323 | const enum dccp_reset_codes code) |
326 | 324 | ||
@@ -377,6 +375,7 @@ struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst, | |||
377 | */ | 375 | */ |
378 | static inline void dccp_connect_init(struct sock *sk) | 376 | static inline void dccp_connect_init(struct sock *sk) |
379 | { | 377 | { |
378 | struct dccp_sock *dp = dccp_sk(sk); | ||
380 | struct dst_entry *dst = __sk_dst_get(sk); | 379 | struct dst_entry *dst = __sk_dst_get(sk); |
381 | struct inet_connection_sock *icsk = inet_csk(sk); | 380 | struct inet_connection_sock *icsk = inet_csk(sk); |
382 | 381 | ||
@@ -385,10 +384,16 @@ static inline void dccp_connect_init(struct sock *sk) | |||
385 | 384 | ||
386 | dccp_sync_mss(sk, dst_mtu(dst)); | 385 | dccp_sync_mss(sk, dst_mtu(dst)); |
387 | 386 | ||
388 | /* | 387 | dccp_update_gss(sk, dp->dccps_iss); |
389 | * FIXME: set dp->{dccps_swh,dccps_swl}, with | 388 | /* |
390 | * something like dccp_inc_seq | 389 | * SWL and AWL are initially adjusted so that they are not less than |
391 | */ | 390 | * the initial Sequence Numbers received and sent, respectively: |
391 | * SWL := max(GSR + 1 - floor(W/4), ISR), | ||
392 | * AWL := max(GSS - W' + 1, ISS). | ||
393 | * These adjustments MUST be applied only at the beginning of the | ||
394 | * connection. | ||
395 | */ | ||
396 | dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss)); | ||
392 | 397 | ||
393 | icsk->icsk_retransmits = 0; | 398 | icsk->icsk_retransmits = 0; |
394 | } | 399 | } |
@@ -420,6 +425,8 @@ int dccp_connect(struct sock *sk) | |||
420 | return 0; | 425 | return 0; |
421 | } | 426 | } |
422 | 427 | ||
428 | EXPORT_SYMBOL_GPL(dccp_connect); | ||
429 | |||
423 | void dccp_send_ack(struct sock *sk) | 430 | void dccp_send_ack(struct sock *sk) |
424 | { | 431 | { |
425 | /* If we have been reset, we may not send again. */ | 432 | /* If we have been reset, we may not send again. */ |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 8a6b2a9e4581..65b11ea90d85 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <net/checksum.h> | 24 | #include <net/checksum.h> |
25 | 25 | ||
26 | #include <net/inet_common.h> | 26 | #include <net/inet_common.h> |
27 | #include <net/ip.h> | 27 | #include <net/inet_sock.h> |
28 | #include <net/protocol.h> | 28 | #include <net/protocol.h> |
29 | #include <net/sock.h> | 29 | #include <net/sock.h> |
30 | #include <net/xfrm.h> | 30 | #include <net/xfrm.h> |
@@ -34,15 +34,18 @@ | |||
34 | #include <linux/timer.h> | 34 | #include <linux/timer.h> |
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/poll.h> | 36 | #include <linux/poll.h> |
37 | #include <linux/dccp.h> | ||
38 | 37 | ||
39 | #include "ccid.h" | 38 | #include "ccid.h" |
40 | #include "dccp.h" | 39 | #include "dccp.h" |
41 | 40 | ||
42 | DEFINE_SNMP_STAT(struct dccp_mib, dccp_statistics) __read_mostly; | 41 | DEFINE_SNMP_STAT(struct dccp_mib, dccp_statistics) __read_mostly; |
43 | 42 | ||
43 | EXPORT_SYMBOL_GPL(dccp_statistics); | ||
44 | |||
44 | atomic_t dccp_orphan_count = ATOMIC_INIT(0); | 45 | atomic_t dccp_orphan_count = ATOMIC_INIT(0); |
45 | 46 | ||
47 | EXPORT_SYMBOL_GPL(dccp_orphan_count); | ||
48 | |||
46 | static struct net_protocol dccp_protocol = { | 49 | static struct net_protocol dccp_protocol = { |
47 | .handler = dccp_v4_rcv, | 50 | .handler = dccp_v4_rcv, |
48 | .err_handler = dccp_v4_err, | 51 | .err_handler = dccp_v4_err, |
@@ -149,6 +152,8 @@ int dccp_disconnect(struct sock *sk, int flags) | |||
149 | return err; | 152 | return err; |
150 | } | 153 | } |
151 | 154 | ||
155 | EXPORT_SYMBOL_GPL(dccp_disconnect); | ||
156 | |||
152 | /* | 157 | /* |
153 | * Wait for a DCCP event. | 158 | * Wait for a DCCP event. |
154 | * | 159 | * |
@@ -156,8 +161,8 @@ int dccp_disconnect(struct sock *sk, int flags) | |||
156 | * take care of normal races (between the test and the event) and we don't | 161 | * take care of normal races (between the test and the event) and we don't |
157 | * go look at any of the socket buffers directly. | 162 | * go look at any of the socket buffers directly. |
158 | */ | 163 | */ |
159 | static unsigned int dccp_poll(struct file *file, struct socket *sock, | 164 | unsigned int dccp_poll(struct file *file, struct socket *sock, |
160 | poll_table *wait) | 165 | poll_table *wait) |
161 | { | 166 | { |
162 | unsigned int mask; | 167 | unsigned int mask; |
163 | struct sock *sk = sock->sk; | 168 | struct sock *sk = sock->sk; |
@@ -205,12 +210,16 @@ static unsigned int dccp_poll(struct file *file, struct socket *sock, | |||
205 | return mask; | 210 | return mask; |
206 | } | 211 | } |
207 | 212 | ||
213 | EXPORT_SYMBOL_GPL(dccp_poll); | ||
214 | |||
208 | int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg) | 215 | int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg) |
209 | { | 216 | { |
210 | dccp_pr_debug("entry\n"); | 217 | dccp_pr_debug("entry\n"); |
211 | return -ENOIOCTLCMD; | 218 | return -ENOIOCTLCMD; |
212 | } | 219 | } |
213 | 220 | ||
221 | EXPORT_SYMBOL_GPL(dccp_ioctl); | ||
222 | |||
214 | static int dccp_setsockopt_service(struct sock *sk, const u32 service, | 223 | static int dccp_setsockopt_service(struct sock *sk, const u32 service, |
215 | char __user *optval, int optlen) | 224 | char __user *optval, int optlen) |
216 | { | 225 | { |
@@ -254,7 +263,9 @@ int dccp_setsockopt(struct sock *sk, int level, int optname, | |||
254 | int val; | 263 | int val; |
255 | 264 | ||
256 | if (level != SOL_DCCP) | 265 | if (level != SOL_DCCP) |
257 | return ip_setsockopt(sk, level, optname, optval, optlen); | 266 | return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level, |
267 | optname, optval, | ||
268 | optlen); | ||
258 | 269 | ||
259 | if (optlen < sizeof(int)) | 270 | if (optlen < sizeof(int)) |
260 | return -EINVAL; | 271 | return -EINVAL; |
@@ -282,6 +293,8 @@ int dccp_setsockopt(struct sock *sk, int level, int optname, | |||
282 | return err; | 293 | return err; |
283 | } | 294 | } |
284 | 295 | ||
296 | EXPORT_SYMBOL_GPL(dccp_setsockopt); | ||
297 | |||
285 | static int dccp_getsockopt_service(struct sock *sk, int len, | 298 | static int dccp_getsockopt_service(struct sock *sk, int len, |
286 | u32 __user *optval, | 299 | u32 __user *optval, |
287 | int __user *optlen) | 300 | int __user *optlen) |
@@ -320,8 +333,9 @@ int dccp_getsockopt(struct sock *sk, int level, int optname, | |||
320 | int val, len; | 333 | int val, len; |
321 | 334 | ||
322 | if (level != SOL_DCCP) | 335 | if (level != SOL_DCCP) |
323 | return ip_getsockopt(sk, level, optname, optval, optlen); | 336 | return inet_csk(sk)->icsk_af_ops->getsockopt(sk, level, |
324 | 337 | optname, optval, | |
338 | optlen); | ||
325 | if (get_user(len, optlen)) | 339 | if (get_user(len, optlen)) |
326 | return -EFAULT; | 340 | return -EFAULT; |
327 | 341 | ||
@@ -354,6 +368,8 @@ int dccp_getsockopt(struct sock *sk, int level, int optname, | |||
354 | return 0; | 368 | return 0; |
355 | } | 369 | } |
356 | 370 | ||
371 | EXPORT_SYMBOL_GPL(dccp_getsockopt); | ||
372 | |||
357 | int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | 373 | int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
358 | size_t len) | 374 | size_t len) |
359 | { | 375 | { |
@@ -410,6 +426,8 @@ out_discard: | |||
410 | goto out_release; | 426 | goto out_release; |
411 | } | 427 | } |
412 | 428 | ||
429 | EXPORT_SYMBOL_GPL(dccp_sendmsg); | ||
430 | |||
413 | int dccp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | 431 | int dccp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
414 | size_t len, int nonblock, int flags, int *addr_len) | 432 | size_t len, int nonblock, int flags, int *addr_len) |
415 | { | 433 | { |
@@ -507,7 +525,9 @@ out: | |||
507 | return len; | 525 | return len; |
508 | } | 526 | } |
509 | 527 | ||
510 | static int inet_dccp_listen(struct socket *sock, int backlog) | 528 | EXPORT_SYMBOL_GPL(dccp_recvmsg); |
529 | |||
530 | int inet_dccp_listen(struct socket *sock, int backlog) | ||
511 | { | 531 | { |
512 | struct sock *sk = sock->sk; | 532 | struct sock *sk = sock->sk; |
513 | unsigned char old_state; | 533 | unsigned char old_state; |
@@ -543,6 +563,8 @@ out: | |||
543 | return err; | 563 | return err; |
544 | } | 564 | } |
545 | 565 | ||
566 | EXPORT_SYMBOL_GPL(inet_dccp_listen); | ||
567 | |||
546 | static const unsigned char dccp_new_state[] = { | 568 | static const unsigned char dccp_new_state[] = { |
547 | /* current state: new state: action: */ | 569 | /* current state: new state: action: */ |
548 | [0] = DCCP_CLOSED, | 570 | [0] = DCCP_CLOSED, |
@@ -648,12 +670,16 @@ adjudge_to_death: | |||
648 | sock_put(sk); | 670 | sock_put(sk); |
649 | } | 671 | } |
650 | 672 | ||
673 | EXPORT_SYMBOL_GPL(dccp_close); | ||
674 | |||
651 | void dccp_shutdown(struct sock *sk, int how) | 675 | void dccp_shutdown(struct sock *sk, int how) |
652 | { | 676 | { |
653 | dccp_pr_debug("entry\n"); | 677 | dccp_pr_debug("entry\n"); |
654 | } | 678 | } |
655 | 679 | ||
656 | static struct proto_ops inet_dccp_ops = { | 680 | EXPORT_SYMBOL_GPL(dccp_shutdown); |
681 | |||
682 | static const struct proto_ops inet_dccp_ops = { | ||
657 | .family = PF_INET, | 683 | .family = PF_INET, |
658 | .owner = THIS_MODULE, | 684 | .owner = THIS_MODULE, |
659 | .release = inet_release, | 685 | .release = inet_release, |
@@ -681,11 +707,11 @@ extern struct net_proto_family inet_family_ops; | |||
681 | static struct inet_protosw dccp_v4_protosw = { | 707 | static struct inet_protosw dccp_v4_protosw = { |
682 | .type = SOCK_DCCP, | 708 | .type = SOCK_DCCP, |
683 | .protocol = IPPROTO_DCCP, | 709 | .protocol = IPPROTO_DCCP, |
684 | .prot = &dccp_v4_prot, | 710 | .prot = &dccp_prot, |
685 | .ops = &inet_dccp_ops, | 711 | .ops = &inet_dccp_ops, |
686 | .capability = -1, | 712 | .capability = -1, |
687 | .no_check = 0, | 713 | .no_check = 0, |
688 | .flags = 0, | 714 | .flags = INET_PROTOSW_ICSK, |
689 | }; | 715 | }; |
690 | 716 | ||
691 | /* | 717 | /* |
@@ -760,13 +786,15 @@ MODULE_PARM_DESC(thash_entries, "Number of ehash buckets"); | |||
760 | int dccp_debug; | 786 | int dccp_debug; |
761 | module_param(dccp_debug, int, 0444); | 787 | module_param(dccp_debug, int, 0444); |
762 | MODULE_PARM_DESC(dccp_debug, "Enable debug messages"); | 788 | MODULE_PARM_DESC(dccp_debug, "Enable debug messages"); |
789 | |||
790 | EXPORT_SYMBOL_GPL(dccp_debug); | ||
763 | #endif | 791 | #endif |
764 | 792 | ||
765 | static int __init dccp_init(void) | 793 | static int __init dccp_init(void) |
766 | { | 794 | { |
767 | unsigned long goal; | 795 | unsigned long goal; |
768 | int ehash_order, bhash_order, i; | 796 | int ehash_order, bhash_order, i; |
769 | int rc = proto_register(&dccp_v4_prot, 1); | 797 | int rc = proto_register(&dccp_prot, 1); |
770 | 798 | ||
771 | if (rc) | 799 | if (rc) |
772 | goto out; | 800 | goto out; |
@@ -869,7 +897,7 @@ out_free_bind_bucket_cachep: | |||
869 | kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep); | 897 | kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep); |
870 | dccp_hashinfo.bind_bucket_cachep = NULL; | 898 | dccp_hashinfo.bind_bucket_cachep = NULL; |
871 | out_proto_unregister: | 899 | out_proto_unregister: |
872 | proto_unregister(&dccp_v4_prot); | 900 | proto_unregister(&dccp_prot); |
873 | goto out; | 901 | goto out; |
874 | } | 902 | } |
875 | 903 | ||
@@ -892,7 +920,7 @@ static void __exit dccp_fini(void) | |||
892 | get_order(dccp_hashinfo.ehash_size * | 920 | get_order(dccp_hashinfo.ehash_size * |
893 | sizeof(struct inet_ehash_bucket))); | 921 | sizeof(struct inet_ehash_bucket))); |
894 | kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep); | 922 | kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep); |
895 | proto_unregister(&dccp_v4_prot); | 923 | proto_unregister(&dccp_prot); |
896 | } | 924 | } |
897 | 925 | ||
898 | module_init(dccp_init); | 926 | module_init(dccp_init); |
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index d402e9020c68..78ec5344be86 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
@@ -149,7 +149,7 @@ static void dn_keepalive(struct sock *sk); | |||
149 | #define DN_SK_HASH_MASK (DN_SK_HASH_SIZE - 1) | 149 | #define DN_SK_HASH_MASK (DN_SK_HASH_SIZE - 1) |
150 | 150 | ||
151 | 151 | ||
152 | static struct proto_ops dn_proto_ops; | 152 | static const struct proto_ops dn_proto_ops; |
153 | static DEFINE_RWLOCK(dn_hash_lock); | 153 | static DEFINE_RWLOCK(dn_hash_lock); |
154 | static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE]; | 154 | static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE]; |
155 | static struct hlist_head dn_wild_sk; | 155 | static struct hlist_head dn_wild_sk; |
@@ -1252,7 +1252,7 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1252 | break; | 1252 | break; |
1253 | 1253 | ||
1254 | default: | 1254 | default: |
1255 | err = dev_ioctl(cmd, (void __user *)arg); | 1255 | err = -ENOIOCTLCMD; |
1256 | break; | 1256 | break; |
1257 | } | 1257 | } |
1258 | 1258 | ||
@@ -2342,7 +2342,7 @@ static struct net_proto_family dn_family_ops = { | |||
2342 | .owner = THIS_MODULE, | 2342 | .owner = THIS_MODULE, |
2343 | }; | 2343 | }; |
2344 | 2344 | ||
2345 | static struct proto_ops dn_proto_ops = { | 2345 | static const struct proto_ops dn_proto_ops = { |
2346 | .family = AF_DECnet, | 2346 | .family = AF_DECnet, |
2347 | .owner = THIS_MODULE, | 2347 | .owner = THIS_MODULE, |
2348 | .release = dn_release, | 2348 | .release = dn_release, |
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index 8d0cc3cf3e49..33ab256cfd4a 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c | |||
@@ -408,11 +408,14 @@ int dn_neigh_router_hello(struct sk_buff *skb) | |||
408 | } | 408 | } |
409 | } | 409 | } |
410 | 410 | ||
411 | if (!dn_db->router) { | 411 | /* Only use routers in our area */ |
412 | dn_db->router = neigh_clone(neigh); | 412 | if ((dn_ntohs(src)>>10) == dn_ntohs((decnet_address)>>10)) { |
413 | } else { | 413 | if (!dn_db->router) { |
414 | if (msg->priority > ((struct dn_neigh *)dn_db->router)->priority) | 414 | dn_db->router = neigh_clone(neigh); |
415 | neigh_release(xchg(&dn_db->router, neigh_clone(neigh))); | 415 | } else { |
416 | if (msg->priority > ((struct dn_neigh *)dn_db->router)->priority) | ||
417 | neigh_release(xchg(&dn_db->router, neigh_clone(neigh))); | ||
418 | } | ||
416 | } | 419 | } |
417 | write_unlock(&neigh->lock); | 420 | write_unlock(&neigh->lock); |
418 | neigh_release(neigh); | 421 | neigh_release(neigh); |
diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c index 369f25b60f3f..44bda85e678f 100644 --- a/net/decnet/dn_nsp_in.c +++ b/net/decnet/dn_nsp_in.c | |||
@@ -793,7 +793,6 @@ static int dn_nsp_rx_packet(struct sk_buff *skb) | |||
793 | got_it: | 793 | got_it: |
794 | if (sk != NULL) { | 794 | if (sk != NULL) { |
795 | struct dn_scp *scp = DN_SK(sk); | 795 | struct dn_scp *scp = DN_SK(sk); |
796 | int ret; | ||
797 | 796 | ||
798 | /* Reset backoff */ | 797 | /* Reset backoff */ |
799 | scp->nsp_rxtshift = 0; | 798 | scp->nsp_rxtshift = 0; |
@@ -807,21 +806,7 @@ got_it: | |||
807 | goto free_out; | 806 | goto free_out; |
808 | } | 807 | } |
809 | 808 | ||
810 | bh_lock_sock(sk); | 809 | return sk_receive_skb(sk, skb); |
811 | ret = NET_RX_SUCCESS; | ||
812 | if (decnet_debug_level & 8) | ||
813 | printk(KERN_DEBUG "NSP: 0x%02x 0x%02x 0x%04x 0x%04x %d\n", | ||
814 | (int)cb->rt_flags, (int)cb->nsp_flags, | ||
815 | (int)cb->src_port, (int)cb->dst_port, | ||
816 | !!sock_owned_by_user(sk)); | ||
817 | if (!sock_owned_by_user(sk)) | ||
818 | ret = dn_nsp_backlog_rcv(sk, skb); | ||
819 | else | ||
820 | sk_add_backlog(sk, skb); | ||
821 | bh_unlock_sock(sk); | ||
822 | sock_put(sk); | ||
823 | |||
824 | return ret; | ||
825 | } | 810 | } |
826 | 811 | ||
827 | return dn_nsp_no_socket(skb, reason); | 812 | return dn_nsp_no_socket(skb, reason); |
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 34fdac51df96..c792994d7952 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/if_arp.h> | 31 | #include <linux/if_arp.h> |
32 | #include <linux/wireless.h> | 32 | #include <linux/wireless.h> |
33 | #include <linux/skbuff.h> | 33 | #include <linux/skbuff.h> |
34 | #include <linux/udp.h> | ||
34 | #include <net/sock.h> | 35 | #include <net/sock.h> |
35 | #include <net/inet_common.h> | 36 | #include <net/inet_common.h> |
36 | #include <linux/stat.h> | 37 | #include <linux/stat.h> |
@@ -45,7 +46,7 @@ | |||
45 | #include <asm/uaccess.h> | 46 | #include <asm/uaccess.h> |
46 | #include <asm/system.h> | 47 | #include <asm/system.h> |
47 | 48 | ||
48 | static struct proto_ops econet_ops; | 49 | static const struct proto_ops econet_ops; |
49 | static struct hlist_head econet_sklist; | 50 | static struct hlist_head econet_sklist; |
50 | static DEFINE_RWLOCK(econet_lock); | 51 | static DEFINE_RWLOCK(econet_lock); |
51 | 52 | ||
@@ -56,7 +57,7 @@ static struct net_device *net2dev_map[256]; | |||
56 | #define EC_PORT_IP 0xd2 | 57 | #define EC_PORT_IP 0xd2 |
57 | 58 | ||
58 | #ifdef CONFIG_ECONET_AUNUDP | 59 | #ifdef CONFIG_ECONET_AUNUDP |
59 | static spinlock_t aun_queue_lock; | 60 | static DEFINE_SPINLOCK(aun_queue_lock); |
60 | static struct socket *udpsock; | 61 | static struct socket *udpsock; |
61 | #define AUN_PORT 0x8000 | 62 | #define AUN_PORT 0x8000 |
62 | 63 | ||
@@ -686,7 +687,7 @@ static int econet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg | |||
686 | break; | 687 | break; |
687 | 688 | ||
688 | default: | 689 | default: |
689 | return dev_ioctl(cmd, argp); | 690 | return -ENOIOCTLCMD; |
690 | } | 691 | } |
691 | /*NOTREACHED*/ | 692 | /*NOTREACHED*/ |
692 | return 0; | 693 | return 0; |
@@ -698,7 +699,7 @@ static struct net_proto_family econet_family_ops = { | |||
698 | .owner = THIS_MODULE, | 699 | .owner = THIS_MODULE, |
699 | }; | 700 | }; |
700 | 701 | ||
701 | static struct proto_ops SOCKOPS_WRAPPED(econet_ops) = { | 702 | static const struct proto_ops SOCKOPS_WRAPPED(econet_ops) = { |
702 | .family = PF_ECONET, | 703 | .family = PF_ECONET, |
703 | .owner = THIS_MODULE, | 704 | .owner = THIS_MODULE, |
704 | .release = econet_release, | 705 | .release = econet_release, |
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index 03efaacbdb73..4cc6f41c6930 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c | |||
@@ -410,9 +410,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | |||
410 | return 1; | 410 | return 1; |
411 | } | 411 | } |
412 | 412 | ||
413 | if ((is_multicast_ether_addr(hdr->addr1) || | 413 | if (is_multicast_ether_addr(hdr->addr1) |
414 | is_broadcast_ether_addr(hdr->addr2)) ? ieee->host_mc_decrypt : | 414 | ? ieee->host_mc_decrypt : ieee->host_decrypt) { |
415 | ieee->host_decrypt) { | ||
416 | int idx = 0; | 415 | int idx = 0; |
417 | if (skb->len >= hdrlen + 3) | 416 | if (skb->len >= hdrlen + 3) |
418 | idx = skb->data[hdrlen + 3] >> 6; | 417 | idx = skb->data[hdrlen + 3] >> 6; |
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index e55136ae09f4..011cca7ae02b 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -456,6 +456,14 @@ config TCP_CONG_BIC | |||
456 | increase provides TCP friendliness. | 456 | increase provides TCP friendliness. |
457 | See http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/ | 457 | See http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/ |
458 | 458 | ||
459 | config TCP_CONG_CUBIC | ||
460 | tristate "CUBIC TCP" | ||
461 | default m | ||
462 | ---help--- | ||
463 | This is version 2.0 of BIC-TCP which uses a cubic growth function | ||
464 | among other techniques. | ||
465 | See http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/cubic-paper.pdf | ||
466 | |||
459 | config TCP_CONG_WESTWOOD | 467 | config TCP_CONG_WESTWOOD |
460 | tristate "TCP Westwood+" | 468 | tristate "TCP Westwood+" |
461 | default m | 469 | default m |
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile index f0435d00db6b..c54edd76de09 100644 --- a/net/ipv4/Makefile +++ b/net/ipv4/Makefile | |||
@@ -34,6 +34,7 @@ obj-$(CONFIG_INET_DIAG) += inet_diag.o | |||
34 | obj-$(CONFIG_IP_ROUTE_MULTIPATH_CACHED) += multipath.o | 34 | obj-$(CONFIG_IP_ROUTE_MULTIPATH_CACHED) += multipath.o |
35 | obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o | 35 | obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o |
36 | obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o | 36 | obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o |
37 | obj-$(CONFIG_TCP_CONG_CUBIC) += tcp_cubic.o | ||
37 | obj-$(CONFIG_TCP_CONG_WESTWOOD) += tcp_westwood.o | 38 | obj-$(CONFIG_TCP_CONG_WESTWOOD) += tcp_westwood.o |
38 | obj-$(CONFIG_TCP_CONG_HSTCP) += tcp_highspeed.o | 39 | obj-$(CONFIG_TCP_CONG_HSTCP) += tcp_highspeed.o |
39 | obj-$(CONFIG_TCP_CONG_HYBLA) += tcp_hybla.o | 40 | obj-$(CONFIG_TCP_CONG_HYBLA) += tcp_hybla.o |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index d368cf249000..966a071a408c 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -93,6 +93,7 @@ | |||
93 | #include <linux/smp_lock.h> | 93 | #include <linux/smp_lock.h> |
94 | #include <linux/inet.h> | 94 | #include <linux/inet.h> |
95 | #include <linux/igmp.h> | 95 | #include <linux/igmp.h> |
96 | #include <linux/inetdevice.h> | ||
96 | #include <linux/netdevice.h> | 97 | #include <linux/netdevice.h> |
97 | #include <net/ip.h> | 98 | #include <net/ip.h> |
98 | #include <net/protocol.h> | 99 | #include <net/protocol.h> |
@@ -302,6 +303,7 @@ lookup_protocol: | |||
302 | sk->sk_reuse = 1; | 303 | sk->sk_reuse = 1; |
303 | 304 | ||
304 | inet = inet_sk(sk); | 305 | inet = inet_sk(sk); |
306 | inet->is_icsk = INET_PROTOSW_ICSK & answer_flags; | ||
305 | 307 | ||
306 | if (SOCK_RAW == sock->type) { | 308 | if (SOCK_RAW == sock->type) { |
307 | inet->num = protocol; | 309 | inet->num = protocol; |
@@ -775,16 +777,16 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
775 | err = devinet_ioctl(cmd, (void __user *)arg); | 777 | err = devinet_ioctl(cmd, (void __user *)arg); |
776 | break; | 778 | break; |
777 | default: | 779 | default: |
778 | if (!sk->sk_prot->ioctl || | 780 | if (sk->sk_prot->ioctl) |
779 | (err = sk->sk_prot->ioctl(sk, cmd, arg)) == | 781 | err = sk->sk_prot->ioctl(sk, cmd, arg); |
780 | -ENOIOCTLCMD) | 782 | else |
781 | err = dev_ioctl(cmd, (void __user *)arg); | 783 | err = -ENOIOCTLCMD; |
782 | break; | 784 | break; |
783 | } | 785 | } |
784 | return err; | 786 | return err; |
785 | } | 787 | } |
786 | 788 | ||
787 | struct proto_ops inet_stream_ops = { | 789 | const struct proto_ops inet_stream_ops = { |
788 | .family = PF_INET, | 790 | .family = PF_INET, |
789 | .owner = THIS_MODULE, | 791 | .owner = THIS_MODULE, |
790 | .release = inet_release, | 792 | .release = inet_release, |
@@ -805,7 +807,7 @@ struct proto_ops inet_stream_ops = { | |||
805 | .sendpage = tcp_sendpage | 807 | .sendpage = tcp_sendpage |
806 | }; | 808 | }; |
807 | 809 | ||
808 | struct proto_ops inet_dgram_ops = { | 810 | const struct proto_ops inet_dgram_ops = { |
809 | .family = PF_INET, | 811 | .family = PF_INET, |
810 | .owner = THIS_MODULE, | 812 | .owner = THIS_MODULE, |
811 | .release = inet_release, | 813 | .release = inet_release, |
@@ -830,7 +832,7 @@ struct proto_ops inet_dgram_ops = { | |||
830 | * For SOCK_RAW sockets; should be the same as inet_dgram_ops but without | 832 | * For SOCK_RAW sockets; should be the same as inet_dgram_ops but without |
831 | * udp_poll | 833 | * udp_poll |
832 | */ | 834 | */ |
833 | static struct proto_ops inet_sockraw_ops = { | 835 | static const struct proto_ops inet_sockraw_ops = { |
834 | .family = PF_INET, | 836 | .family = PF_INET, |
835 | .owner = THIS_MODULE, | 837 | .owner = THIS_MODULE, |
836 | .release = inet_release, | 838 | .release = inet_release, |
@@ -869,7 +871,8 @@ static struct inet_protosw inetsw_array[] = | |||
869 | .ops = &inet_stream_ops, | 871 | .ops = &inet_stream_ops, |
870 | .capability = -1, | 872 | .capability = -1, |
871 | .no_check = 0, | 873 | .no_check = 0, |
872 | .flags = INET_PROTOSW_PERMANENT, | 874 | .flags = INET_PROTOSW_PERMANENT | |
875 | INET_PROTOSW_ICSK, | ||
873 | }, | 876 | }, |
874 | 877 | ||
875 | { | 878 | { |
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index 035ad2c9e1ba..aed537fa2c88 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/crypto.h> | 6 | #include <linux/crypto.h> |
7 | #include <linux/pfkeyv2.h> | 7 | #include <linux/pfkeyv2.h> |
8 | #include <net/icmp.h> | 8 | #include <net/icmp.h> |
9 | #include <net/protocol.h> | ||
9 | #include <asm/scatterlist.h> | 10 | #include <asm/scatterlist.h> |
10 | 11 | ||
11 | 12 | ||
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index b425748f02d7..37432088fe6d 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -86,6 +86,7 @@ | |||
86 | #include <linux/in.h> | 86 | #include <linux/in.h> |
87 | #include <linux/mm.h> | 87 | #include <linux/mm.h> |
88 | #include <linux/inet.h> | 88 | #include <linux/inet.h> |
89 | #include <linux/inetdevice.h> | ||
89 | #include <linux/netdevice.h> | 90 | #include <linux/netdevice.h> |
90 | #include <linux/etherdevice.h> | 91 | #include <linux/etherdevice.h> |
91 | #include <linux/fddidevice.h> | 92 | #include <linux/fddidevice.h> |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 04a6fe3e95a2..7b9bb28e2ee9 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #endif | 58 | #endif |
59 | #include <linux/kmod.h> | 59 | #include <linux/kmod.h> |
60 | 60 | ||
61 | #include <net/arp.h> | ||
61 | #include <net/ip.h> | 62 | #include <net/ip.h> |
62 | #include <net/route.h> | 63 | #include <net/route.h> |
63 | #include <net/ip_fib.h> | 64 | #include <net/ip_fib.h> |
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 1b18ce66e7b7..73bfcae8af9c 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/pfkeyv2.h> | 9 | #include <linux/pfkeyv2.h> |
10 | #include <linux/random.h> | 10 | #include <linux/random.h> |
11 | #include <net/icmp.h> | 11 | #include <net/icmp.h> |
12 | #include <net/protocol.h> | ||
12 | #include <net/udp.h> | 13 | #include <net/udp.h> |
13 | 14 | ||
14 | /* decapsulation data for use when post-processing */ | 15 | /* decapsulation data for use when post-processing */ |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 19b1b984d687..18f5e509281a 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
31 | #include <linux/in.h> | 31 | #include <linux/in.h> |
32 | #include <linux/inet.h> | 32 | #include <linux/inet.h> |
33 | #include <linux/inetdevice.h> | ||
33 | #include <linux/netdevice.h> | 34 | #include <linux/netdevice.h> |
34 | #include <linux/if_arp.h> | 35 | #include <linux/if_arp.h> |
35 | #include <linux/skbuff.h> | 36 | #include <linux/skbuff.h> |
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 7ea0209cb169..e2890ec8159e 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
30 | #include <linux/in.h> | 30 | #include <linux/in.h> |
31 | #include <linux/inet.h> | 31 | #include <linux/inet.h> |
32 | #include <linux/inetdevice.h> | ||
32 | #include <linux/netdevice.h> | 33 | #include <linux/netdevice.h> |
33 | #include <linux/if_arp.h> | 34 | #include <linux/if_arp.h> |
34 | #include <linux/proc_fs.h> | 35 | #include <linux/proc_fs.h> |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 0b298bbc1518..0dd4d06e456d 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
34 | #include <linux/in.h> | 34 | #include <linux/in.h> |
35 | #include <linux/inet.h> | 35 | #include <linux/inet.h> |
36 | #include <linux/inetdevice.h> | ||
36 | #include <linux/netdevice.h> | 37 | #include <linux/netdevice.h> |
37 | #include <linux/if_arp.h> | 38 | #include <linux/if_arp.h> |
38 | #include <linux/proc_fs.h> | 39 | #include <linux/proc_fs.h> |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 6d2a6ac070e3..ef4724de7350 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
30 | #include <linux/in.h> | 30 | #include <linux/in.h> |
31 | #include <linux/inet.h> | 31 | #include <linux/inet.h> |
32 | #include <linux/inetdevice.h> | ||
32 | #include <linux/netdevice.h> | 33 | #include <linux/netdevice.h> |
33 | #include <linux/if_arp.h> | 34 | #include <linux/if_arp.h> |
34 | #include <linux/proc_fs.h> | 35 | #include <linux/proc_fs.h> |
@@ -36,6 +37,7 @@ | |||
36 | #include <linux/netlink.h> | 37 | #include <linux/netlink.h> |
37 | #include <linux/init.h> | 38 | #include <linux/init.h> |
38 | 39 | ||
40 | #include <net/arp.h> | ||
39 | #include <net/ip.h> | 41 | #include <net/ip.h> |
40 | #include <net/protocol.h> | 42 | #include <net/protocol.h> |
41 | #include <net/route.h> | 43 | #include <net/route.h> |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 705e3ce86df9..e320b32373e5 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -41,6 +41,13 @@ | |||
41 | * modify it under the terms of the GNU General Public License | 41 | * modify it under the terms of the GNU General Public License |
42 | * as published by the Free Software Foundation; either version | 42 | * as published by the Free Software Foundation; either version |
43 | * 2 of the License, or (at your option) any later version. | 43 | * 2 of the License, or (at your option) any later version. |
44 | * | ||
45 | * Substantial contributions to this work comes from: | ||
46 | * | ||
47 | * David S. Miller, <davem@davemloft.net> | ||
48 | * Stephen Hemminger <shemminger@osdl.org> | ||
49 | * Paul E. McKenney <paulmck@us.ibm.com> | ||
50 | * Patrick McHardy <kaber@trash.net> | ||
44 | */ | 51 | */ |
45 | 52 | ||
46 | #define VERSION "0.404" | 53 | #define VERSION "0.404" |
@@ -59,6 +66,7 @@ | |||
59 | #include <linux/errno.h> | 66 | #include <linux/errno.h> |
60 | #include <linux/in.h> | 67 | #include <linux/in.h> |
61 | #include <linux/inet.h> | 68 | #include <linux/inet.h> |
69 | #include <linux/inetdevice.h> | ||
62 | #include <linux/netdevice.h> | 70 | #include <linux/netdevice.h> |
63 | #include <linux/if_arp.h> | 71 | #include <linux/if_arp.h> |
64 | #include <linux/proc_fs.h> | 72 | #include <linux/proc_fs.h> |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 92e23b2ad4d2..be5a519cd2f8 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -73,6 +73,7 @@ | |||
73 | #include <linux/socket.h> | 73 | #include <linux/socket.h> |
74 | #include <linux/in.h> | 74 | #include <linux/in.h> |
75 | #include <linux/inet.h> | 75 | #include <linux/inet.h> |
76 | #include <linux/inetdevice.h> | ||
76 | #include <linux/netdevice.h> | 77 | #include <linux/netdevice.h> |
77 | #include <linux/string.h> | 78 | #include <linux/string.h> |
78 | #include <linux/netfilter_ipv4.h> | 79 | #include <linux/netfilter_ipv4.h> |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 4a195c724f01..34758118c10c 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -91,6 +91,8 @@ | |||
91 | #include <linux/if_arp.h> | 91 | #include <linux/if_arp.h> |
92 | #include <linux/rtnetlink.h> | 92 | #include <linux/rtnetlink.h> |
93 | #include <linux/times.h> | 93 | #include <linux/times.h> |
94 | |||
95 | #include <net/arp.h> | ||
94 | #include <net/ip.h> | 96 | #include <net/ip.h> |
95 | #include <net/protocol.h> | 97 | #include <net/protocol.h> |
96 | #include <net/route.h> | 98 | #include <net/route.h> |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 3fe021f1a566..ae20281d8deb 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -37,7 +37,8 @@ EXPORT_SYMBOL(inet_csk_timer_bug_msg); | |||
37 | */ | 37 | */ |
38 | int sysctl_local_port_range[2] = { 1024, 4999 }; | 38 | int sysctl_local_port_range[2] = { 1024, 4999 }; |
39 | 39 | ||
40 | static inline int inet_csk_bind_conflict(struct sock *sk, struct inet_bind_bucket *tb) | 40 | int inet_csk_bind_conflict(const struct sock *sk, |
41 | const struct inet_bind_bucket *tb) | ||
41 | { | 42 | { |
42 | const u32 sk_rcv_saddr = inet_rcv_saddr(sk); | 43 | const u32 sk_rcv_saddr = inet_rcv_saddr(sk); |
43 | struct sock *sk2; | 44 | struct sock *sk2; |
@@ -62,11 +63,15 @@ static inline int inet_csk_bind_conflict(struct sock *sk, struct inet_bind_bucke | |||
62 | return node != NULL; | 63 | return node != NULL; |
63 | } | 64 | } |
64 | 65 | ||
66 | EXPORT_SYMBOL_GPL(inet_csk_bind_conflict); | ||
67 | |||
65 | /* Obtain a reference to a local port for the given sock, | 68 | /* Obtain a reference to a local port for the given sock, |
66 | * if snum is zero it means select any available local port. | 69 | * if snum is zero it means select any available local port. |
67 | */ | 70 | */ |
68 | int inet_csk_get_port(struct inet_hashinfo *hashinfo, | 71 | int inet_csk_get_port(struct inet_hashinfo *hashinfo, |
69 | struct sock *sk, unsigned short snum) | 72 | struct sock *sk, unsigned short snum, |
73 | int (*bind_conflict)(const struct sock *sk, | ||
74 | const struct inet_bind_bucket *tb)) | ||
70 | { | 75 | { |
71 | struct inet_bind_hashbucket *head; | 76 | struct inet_bind_hashbucket *head; |
72 | struct hlist_node *node; | 77 | struct hlist_node *node; |
@@ -125,7 +130,7 @@ tb_found: | |||
125 | goto success; | 130 | goto success; |
126 | } else { | 131 | } else { |
127 | ret = 1; | 132 | ret = 1; |
128 | if (inet_csk_bind_conflict(sk, tb)) | 133 | if (bind_conflict(sk, tb)) |
129 | goto fail_unlock; | 134 | goto fail_unlock; |
130 | } | 135 | } |
131 | } | 136 | } |
@@ -380,7 +385,7 @@ struct request_sock *inet_csk_search_req(const struct sock *sk, | |||
380 | EXPORT_SYMBOL_GPL(inet_csk_search_req); | 385 | EXPORT_SYMBOL_GPL(inet_csk_search_req); |
381 | 386 | ||
382 | void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req, | 387 | void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req, |
383 | const unsigned timeout) | 388 | unsigned long timeout) |
384 | { | 389 | { |
385 | struct inet_connection_sock *icsk = inet_csk(sk); | 390 | struct inet_connection_sock *icsk = inet_csk(sk); |
386 | struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt; | 391 | struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt; |
@@ -631,3 +636,15 @@ void inet_csk_listen_stop(struct sock *sk) | |||
631 | } | 636 | } |
632 | 637 | ||
633 | EXPORT_SYMBOL_GPL(inet_csk_listen_stop); | 638 | EXPORT_SYMBOL_GPL(inet_csk_listen_stop); |
639 | |||
640 | void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr) | ||
641 | { | ||
642 | struct sockaddr_in *sin = (struct sockaddr_in *)uaddr; | ||
643 | const struct inet_sock *inet = inet_sk(sk); | ||
644 | |||
645 | sin->sin_family = AF_INET; | ||
646 | sin->sin_addr.s_addr = inet->daddr; | ||
647 | sin->sin_port = inet->dport; | ||
648 | } | ||
649 | |||
650 | EXPORT_SYMBOL_GPL(inet_csk_addr2sockaddr); | ||
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 39061ed53cfd..c49908192047 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
@@ -112,12 +112,12 @@ static int inet_diag_fill(struct sk_buff *skb, struct sock *sk, | |||
112 | r->idiag_inode = 0; | 112 | r->idiag_inode = 0; |
113 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | 113 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) |
114 | if (r->idiag_family == AF_INET6) { | 114 | if (r->idiag_family == AF_INET6) { |
115 | const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk); | 115 | const struct inet6_timewait_sock *tw6 = inet6_twsk(sk); |
116 | 116 | ||
117 | ipv6_addr_copy((struct in6_addr *)r->id.idiag_src, | 117 | ipv6_addr_copy((struct in6_addr *)r->id.idiag_src, |
118 | &tcp6tw->tw_v6_rcv_saddr); | 118 | &tw6->tw_v6_rcv_saddr); |
119 | ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst, | 119 | ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst, |
120 | &tcp6tw->tw_v6_daddr); | 120 | &tw6->tw_v6_daddr); |
121 | } | 121 | } |
122 | #endif | 122 | #endif |
123 | nlh->nlmsg_len = skb->tail - b; | 123 | nlh->nlmsg_len = skb->tail - b; |
@@ -489,9 +489,9 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, | |||
489 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | 489 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) |
490 | if (r->idiag_family == AF_INET6) { | 490 | if (r->idiag_family == AF_INET6) { |
491 | ipv6_addr_copy((struct in6_addr *)r->id.idiag_src, | 491 | ipv6_addr_copy((struct in6_addr *)r->id.idiag_src, |
492 | &tcp6_rsk(req)->loc_addr); | 492 | &inet6_rsk(req)->loc_addr); |
493 | ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst, | 493 | ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst, |
494 | &tcp6_rsk(req)->rmt_addr); | 494 | &inet6_rsk(req)->rmt_addr); |
495 | } | 495 | } |
496 | #endif | 496 | #endif |
497 | nlh->nlmsg_len = skb->tail - b; | 497 | nlh->nlmsg_len = skb->tail - b; |
@@ -553,13 +553,13 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, | |||
553 | entry.saddr = | 553 | entry.saddr = |
554 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | 554 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) |
555 | (entry.family == AF_INET6) ? | 555 | (entry.family == AF_INET6) ? |
556 | tcp6_rsk(req)->loc_addr.s6_addr32 : | 556 | inet6_rsk(req)->loc_addr.s6_addr32 : |
557 | #endif | 557 | #endif |
558 | &ireq->loc_addr; | 558 | &ireq->loc_addr; |
559 | entry.daddr = | 559 | entry.daddr = |
560 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | 560 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) |
561 | (entry.family == AF_INET6) ? | 561 | (entry.family == AF_INET6) ? |
562 | tcp6_rsk(req)->rmt_addr.s6_addr32 : | 562 | inet6_rsk(req)->rmt_addr.s6_addr32 : |
563 | #endif | 563 | #endif |
564 | &ireq->rmt_addr; | 564 | &ireq->rmt_addr; |
565 | entry.dport = ntohs(ireq->rmt_port); | 565 | entry.dport = ntohs(ireq->rmt_port); |
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index e8d29fe736d2..33228115cda4 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -15,12 +15,14 @@ | |||
15 | 15 | ||
16 | #include <linux/config.h> | 16 | #include <linux/config.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/random.h> | ||
18 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
19 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
20 | #include <linux/wait.h> | 21 | #include <linux/wait.h> |
21 | 22 | ||
22 | #include <net/inet_connection_sock.h> | 23 | #include <net/inet_connection_sock.h> |
23 | #include <net/inet_hashtables.h> | 24 | #include <net/inet_hashtables.h> |
25 | #include <net/ip.h> | ||
24 | 26 | ||
25 | /* | 27 | /* |
26 | * Allocate and initialize a new local port bind bucket. | 28 | * Allocate and initialize a new local port bind bucket. |
@@ -163,3 +165,179 @@ struct sock *__inet_lookup_listener(const struct hlist_head *head, const u32 dad | |||
163 | } | 165 | } |
164 | 166 | ||
165 | EXPORT_SYMBOL_GPL(__inet_lookup_listener); | 167 | EXPORT_SYMBOL_GPL(__inet_lookup_listener); |
168 | |||
169 | /* called with local bh disabled */ | ||
170 | static int __inet_check_established(struct inet_timewait_death_row *death_row, | ||
171 | struct sock *sk, __u16 lport, | ||
172 | struct inet_timewait_sock **twp) | ||
173 | { | ||
174 | struct inet_hashinfo *hinfo = death_row->hashinfo; | ||
175 | struct inet_sock *inet = inet_sk(sk); | ||
176 | u32 daddr = inet->rcv_saddr; | ||
177 | u32 saddr = inet->daddr; | ||
178 | int dif = sk->sk_bound_dev_if; | ||
179 | INET_ADDR_COOKIE(acookie, saddr, daddr) | ||
180 | const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport); | ||
181 | unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport); | ||
182 | struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); | ||
183 | struct sock *sk2; | ||
184 | const struct hlist_node *node; | ||
185 | struct inet_timewait_sock *tw; | ||
186 | |||
187 | prefetch(head->chain.first); | ||
188 | write_lock(&head->lock); | ||
189 | |||
190 | /* Check TIME-WAIT sockets first. */ | ||
191 | sk_for_each(sk2, node, &(head + hinfo->ehash_size)->chain) { | ||
192 | tw = inet_twsk(sk2); | ||
193 | |||
194 | if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) { | ||
195 | if (twsk_unique(sk, sk2, twp)) | ||
196 | goto unique; | ||
197 | else | ||
198 | goto not_unique; | ||
199 | } | ||
200 | } | ||
201 | tw = NULL; | ||
202 | |||
203 | /* And established part... */ | ||
204 | sk_for_each(sk2, node, &head->chain) { | ||
205 | if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) | ||
206 | goto not_unique; | ||
207 | } | ||
208 | |||
209 | unique: | ||
210 | /* Must record num and sport now. Otherwise we will see | ||
211 | * in hash table socket with a funny identity. */ | ||
212 | inet->num = lport; | ||
213 | inet->sport = htons(lport); | ||
214 | sk->sk_hash = hash; | ||
215 | BUG_TRAP(sk_unhashed(sk)); | ||
216 | __sk_add_node(sk, &head->chain); | ||
217 | sock_prot_inc_use(sk->sk_prot); | ||
218 | write_unlock(&head->lock); | ||
219 | |||
220 | if (twp) { | ||
221 | *twp = tw; | ||
222 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); | ||
223 | } else if (tw) { | ||
224 | /* Silly. Should hash-dance instead... */ | ||
225 | inet_twsk_deschedule(tw, death_row); | ||
226 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); | ||
227 | |||
228 | inet_twsk_put(tw); | ||
229 | } | ||
230 | |||
231 | return 0; | ||
232 | |||
233 | not_unique: | ||
234 | write_unlock(&head->lock); | ||
235 | return -EADDRNOTAVAIL; | ||
236 | } | ||
237 | |||
238 | static inline u32 inet_sk_port_offset(const struct sock *sk) | ||
239 | { | ||
240 | const struct inet_sock *inet = inet_sk(sk); | ||
241 | return secure_ipv4_port_ephemeral(inet->rcv_saddr, inet->daddr, | ||
242 | inet->dport); | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * Bind a port for a connect operation and hash it. | ||
247 | */ | ||
248 | int inet_hash_connect(struct inet_timewait_death_row *death_row, | ||
249 | struct sock *sk) | ||
250 | { | ||
251 | struct inet_hashinfo *hinfo = death_row->hashinfo; | ||
252 | const unsigned short snum = inet_sk(sk)->num; | ||
253 | struct inet_bind_hashbucket *head; | ||
254 | struct inet_bind_bucket *tb; | ||
255 | int ret; | ||
256 | |||
257 | if (!snum) { | ||
258 | int low = sysctl_local_port_range[0]; | ||
259 | int high = sysctl_local_port_range[1]; | ||
260 | int range = high - low; | ||
261 | int i; | ||
262 | int port; | ||
263 | static u32 hint; | ||
264 | u32 offset = hint + inet_sk_port_offset(sk); | ||
265 | struct hlist_node *node; | ||
266 | struct inet_timewait_sock *tw = NULL; | ||
267 | |||
268 | local_bh_disable(); | ||
269 | for (i = 1; i <= range; i++) { | ||
270 | port = low + (i + offset) % range; | ||
271 | head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)]; | ||
272 | spin_lock(&head->lock); | ||
273 | |||
274 | /* Does not bother with rcv_saddr checks, | ||
275 | * because the established check is already | ||
276 | * unique enough. | ||
277 | */ | ||
278 | inet_bind_bucket_for_each(tb, node, &head->chain) { | ||
279 | if (tb->port == port) { | ||
280 | BUG_TRAP(!hlist_empty(&tb->owners)); | ||
281 | if (tb->fastreuse >= 0) | ||
282 | goto next_port; | ||
283 | if (!__inet_check_established(death_row, | ||
284 | sk, port, | ||
285 | &tw)) | ||
286 | goto ok; | ||
287 | goto next_port; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep, head, port); | ||
292 | if (!tb) { | ||
293 | spin_unlock(&head->lock); | ||
294 | break; | ||
295 | } | ||
296 | tb->fastreuse = -1; | ||
297 | goto ok; | ||
298 | |||
299 | next_port: | ||
300 | spin_unlock(&head->lock); | ||
301 | } | ||
302 | local_bh_enable(); | ||
303 | |||
304 | return -EADDRNOTAVAIL; | ||
305 | |||
306 | ok: | ||
307 | hint += i; | ||
308 | |||
309 | /* Head lock still held and bh's disabled */ | ||
310 | inet_bind_hash(sk, tb, port); | ||
311 | if (sk_unhashed(sk)) { | ||
312 | inet_sk(sk)->sport = htons(port); | ||
313 | __inet_hash(hinfo, sk, 0); | ||
314 | } | ||
315 | spin_unlock(&head->lock); | ||
316 | |||
317 | if (tw) { | ||
318 | inet_twsk_deschedule(tw, death_row);; | ||
319 | inet_twsk_put(tw); | ||
320 | } | ||
321 | |||
322 | ret = 0; | ||
323 | goto out; | ||
324 | } | ||
325 | |||
326 | head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)]; | ||
327 | tb = inet_csk(sk)->icsk_bind_hash; | ||
328 | spin_lock_bh(&head->lock); | ||
329 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { | ||
330 | __inet_hash(hinfo, sk, 0); | ||
331 | spin_unlock_bh(&head->lock); | ||
332 | return 0; | ||
333 | } else { | ||
334 | spin_unlock(&head->lock); | ||
335 | /* No definite answer... Walk to established hash table */ | ||
336 | ret = __inet_check_established(death_row, sk, snum, NULL); | ||
337 | out: | ||
338 | local_bh_enable(); | ||
339 | return ret; | ||
340 | } | ||
341 | } | ||
342 | |||
343 | EXPORT_SYMBOL_GPL(inet_hash_connect); | ||
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index a010e9a68811..417f126c749e 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c | |||
@@ -90,8 +90,9 @@ EXPORT_SYMBOL_GPL(__inet_twsk_hashdance); | |||
90 | 90 | ||
91 | struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int state) | 91 | struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int state) |
92 | { | 92 | { |
93 | struct inet_timewait_sock *tw = kmem_cache_alloc(sk->sk_prot_creator->twsk_slab, | 93 | struct inet_timewait_sock *tw = |
94 | SLAB_ATOMIC); | 94 | kmem_cache_alloc(sk->sk_prot_creator->twsk_prot->twsk_slab, |
95 | SLAB_ATOMIC); | ||
95 | if (tw != NULL) { | 96 | if (tw != NULL) { |
96 | const struct inet_sock *inet = inet_sk(sk); | 97 | const struct inet_sock *inet = inet_sk(sk); |
97 | 98 | ||
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 2fc3fd38924f..ce5fe3f74a3d 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
@@ -401,6 +401,7 @@ struct inet_peer *inet_getpeer(__u32 daddr, int create) | |||
401 | return NULL; | 401 | return NULL; |
402 | n->v4daddr = daddr; | 402 | n->v4daddr = daddr; |
403 | atomic_set(&n->refcnt, 1); | 403 | atomic_set(&n->refcnt, 1); |
404 | atomic_set(&n->rid, 0); | ||
404 | n->ip_id_count = secure_ip_id(daddr); | 405 | n->ip_id_count = secure_ip_id(daddr); |
405 | n->tcp_ts_stamp = 0; | 406 | n->tcp_ts_stamp = 0; |
406 | 407 | ||
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 8ce0ce2ee48e..ce2b70ce4018 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -22,6 +22,7 @@ | |||
22 | * Patrick McHardy : LRU queue of frag heads for evictor. | 22 | * Patrick McHardy : LRU queue of frag heads for evictor. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/compiler.h> | ||
25 | #include <linux/config.h> | 26 | #include <linux/config.h> |
26 | #include <linux/module.h> | 27 | #include <linux/module.h> |
27 | #include <linux/types.h> | 28 | #include <linux/types.h> |
@@ -38,6 +39,7 @@ | |||
38 | #include <net/ip.h> | 39 | #include <net/ip.h> |
39 | #include <net/icmp.h> | 40 | #include <net/icmp.h> |
40 | #include <net/checksum.h> | 41 | #include <net/checksum.h> |
42 | #include <net/inetpeer.h> | ||
41 | #include <linux/tcp.h> | 43 | #include <linux/tcp.h> |
42 | #include <linux/udp.h> | 44 | #include <linux/udp.h> |
43 | #include <linux/inet.h> | 45 | #include <linux/inet.h> |
@@ -56,6 +58,8 @@ | |||
56 | int sysctl_ipfrag_high_thresh = 256*1024; | 58 | int sysctl_ipfrag_high_thresh = 256*1024; |
57 | int sysctl_ipfrag_low_thresh = 192*1024; | 59 | int sysctl_ipfrag_low_thresh = 192*1024; |
58 | 60 | ||
61 | int sysctl_ipfrag_max_dist = 64; | ||
62 | |||
59 | /* Important NOTE! Fragment queue must be destroyed before MSL expires. | 63 | /* Important NOTE! Fragment queue must be destroyed before MSL expires. |
60 | * RFC791 is wrong proposing to prolongate timer each fragment arrival by TTL. | 64 | * RFC791 is wrong proposing to prolongate timer each fragment arrival by TTL. |
61 | */ | 65 | */ |
@@ -89,8 +93,10 @@ struct ipq { | |||
89 | spinlock_t lock; | 93 | spinlock_t lock; |
90 | atomic_t refcnt; | 94 | atomic_t refcnt; |
91 | struct timer_list timer; /* when will this queue expire? */ | 95 | struct timer_list timer; /* when will this queue expire? */ |
92 | int iif; | ||
93 | struct timeval stamp; | 96 | struct timeval stamp; |
97 | int iif; | ||
98 | unsigned int rid; | ||
99 | struct inet_peer *peer; | ||
94 | }; | 100 | }; |
95 | 101 | ||
96 | /* Hash table. */ | 102 | /* Hash table. */ |
@@ -195,6 +201,9 @@ static void ip_frag_destroy(struct ipq *qp, int *work) | |||
195 | BUG_TRAP(qp->last_in&COMPLETE); | 201 | BUG_TRAP(qp->last_in&COMPLETE); |
196 | BUG_TRAP(del_timer(&qp->timer) == 0); | 202 | BUG_TRAP(del_timer(&qp->timer) == 0); |
197 | 203 | ||
204 | if (qp->peer) | ||
205 | inet_putpeer(qp->peer); | ||
206 | |||
198 | /* Release all fragment data. */ | 207 | /* Release all fragment data. */ |
199 | fp = qp->fragments; | 208 | fp = qp->fragments; |
200 | while (fp) { | 209 | while (fp) { |
@@ -353,6 +362,7 @@ static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user) | |||
353 | qp->meat = 0; | 362 | qp->meat = 0; |
354 | qp->fragments = NULL; | 363 | qp->fragments = NULL; |
355 | qp->iif = 0; | 364 | qp->iif = 0; |
365 | qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL; | ||
356 | 366 | ||
357 | /* Initialize a timer for this entry. */ | 367 | /* Initialize a timer for this entry. */ |
358 | init_timer(&qp->timer); | 368 | init_timer(&qp->timer); |
@@ -398,6 +408,56 @@ static inline struct ipq *ip_find(struct iphdr *iph, u32 user) | |||
398 | return ip_frag_create(hash, iph, user); | 408 | return ip_frag_create(hash, iph, user); |
399 | } | 409 | } |
400 | 410 | ||
411 | /* Is the fragment too far ahead to be part of ipq? */ | ||
412 | static inline int ip_frag_too_far(struct ipq *qp) | ||
413 | { | ||
414 | struct inet_peer *peer = qp->peer; | ||
415 | unsigned int max = sysctl_ipfrag_max_dist; | ||
416 | unsigned int start, end; | ||
417 | |||
418 | int rc; | ||
419 | |||
420 | if (!peer || !max) | ||
421 | return 0; | ||
422 | |||
423 | start = qp->rid; | ||
424 | end = atomic_inc_return(&peer->rid); | ||
425 | qp->rid = end; | ||
426 | |||
427 | rc = qp->fragments && (end - start) > max; | ||
428 | |||
429 | if (rc) { | ||
430 | IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); | ||
431 | } | ||
432 | |||
433 | return rc; | ||
434 | } | ||
435 | |||
436 | static int ip_frag_reinit(struct ipq *qp) | ||
437 | { | ||
438 | struct sk_buff *fp; | ||
439 | |||
440 | if (!mod_timer(&qp->timer, jiffies + sysctl_ipfrag_time)) { | ||
441 | atomic_inc(&qp->refcnt); | ||
442 | return -ETIMEDOUT; | ||
443 | } | ||
444 | |||
445 | fp = qp->fragments; | ||
446 | do { | ||
447 | struct sk_buff *xp = fp->next; | ||
448 | frag_kfree_skb(fp, NULL); | ||
449 | fp = xp; | ||
450 | } while (fp); | ||
451 | |||
452 | qp->last_in = 0; | ||
453 | qp->len = 0; | ||
454 | qp->meat = 0; | ||
455 | qp->fragments = NULL; | ||
456 | qp->iif = 0; | ||
457 | |||
458 | return 0; | ||
459 | } | ||
460 | |||
401 | /* Add new segment to existing queue. */ | 461 | /* Add new segment to existing queue. */ |
402 | static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb) | 462 | static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb) |
403 | { | 463 | { |
@@ -408,6 +468,12 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb) | |||
408 | if (qp->last_in & COMPLETE) | 468 | if (qp->last_in & COMPLETE) |
409 | goto err; | 469 | goto err; |
410 | 470 | ||
471 | if (!(IPCB(skb)->flags & IPSKB_FRAG_COMPLETE) && | ||
472 | unlikely(ip_frag_too_far(qp)) && unlikely(ip_frag_reinit(qp))) { | ||
473 | ipq_kill(qp); | ||
474 | goto err; | ||
475 | } | ||
476 | |||
411 | offset = ntohs(skb->nh.iph->frag_off); | 477 | offset = ntohs(skb->nh.iph->frag_off); |
412 | flags = offset & ~IP_OFFSET; | 478 | flags = offset & ~IP_OFFSET; |
413 | offset &= IP_OFFSET; | 479 | offset &= IP_OFFSET; |
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 473d0f2b2e0d..e45846ae570b 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -128,6 +128,7 @@ | |||
128 | #include <linux/sockios.h> | 128 | #include <linux/sockios.h> |
129 | #include <linux/in.h> | 129 | #include <linux/in.h> |
130 | #include <linux/inet.h> | 130 | #include <linux/inet.h> |
131 | #include <linux/inetdevice.h> | ||
131 | #include <linux/netdevice.h> | 132 | #include <linux/netdevice.h> |
132 | #include <linux/etherdevice.h> | 133 | #include <linux/etherdevice.h> |
133 | 134 | ||
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index dbe12da8d8b3..d3f6c468faf4 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <net/sock.h> | 22 | #include <net/sock.h> |
23 | #include <net/ip.h> | 23 | #include <net/ip.h> |
24 | #include <net/icmp.h> | 24 | #include <net/icmp.h> |
25 | #include <net/route.h> | ||
25 | 26 | ||
26 | /* | 27 | /* |
27 | * Write options to IP header, record destination address to | 28 | * Write options to IP header, record destination address to |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index eba64e2bd397..2a830de3a699 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -445,6 +445,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) | |||
445 | 445 | ||
446 | hlen = iph->ihl * 4; | 446 | hlen = iph->ihl * 4; |
447 | mtu = dst_mtu(&rt->u.dst) - hlen; /* Size of data space */ | 447 | mtu = dst_mtu(&rt->u.dst) - hlen; /* Size of data space */ |
448 | IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE; | ||
448 | 449 | ||
449 | /* When frag_list is given, use it. First, check its validity: | 450 | /* When frag_list is given, use it. First, check its validity: |
450 | * some transformers could create wrong frag_list or break existing | 451 | * some transformers could create wrong frag_list or break existing |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 4f2d87257309..6986e11d65cc 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -25,12 +25,12 @@ | |||
25 | #include <linux/skbuff.h> | 25 | #include <linux/skbuff.h> |
26 | #include <linux/ip.h> | 26 | #include <linux/ip.h> |
27 | #include <linux/icmp.h> | 27 | #include <linux/icmp.h> |
28 | #include <linux/inetdevice.h> | ||
28 | #include <linux/netdevice.h> | 29 | #include <linux/netdevice.h> |
29 | #include <net/sock.h> | 30 | #include <net/sock.h> |
30 | #include <net/ip.h> | 31 | #include <net/ip.h> |
31 | #include <net/icmp.h> | 32 | #include <net/icmp.h> |
32 | #include <net/tcp.h> | 33 | #include <net/tcp_states.h> |
33 | #include <linux/tcp.h> | ||
34 | #include <linux/udp.h> | 34 | #include <linux/udp.h> |
35 | #include <linux/igmp.h> | 35 | #include <linux/igmp.h> |
36 | #include <linux/netfilter.h> | 36 | #include <linux/netfilter.h> |
@@ -427,8 +427,8 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, | |||
427 | err = ip_options_get_from_user(&opt, optval, optlen); | 427 | err = ip_options_get_from_user(&opt, optval, optlen); |
428 | if (err) | 428 | if (err) |
429 | break; | 429 | break; |
430 | if (sk->sk_type == SOCK_STREAM) { | 430 | if (inet->is_icsk) { |
431 | struct tcp_sock *tp = tcp_sk(sk); | 431 | struct inet_connection_sock *icsk = inet_csk(sk); |
432 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 432 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
433 | if (sk->sk_family == PF_INET || | 433 | if (sk->sk_family == PF_INET || |
434 | (!((1 << sk->sk_state) & | 434 | (!((1 << sk->sk_state) & |
@@ -436,10 +436,10 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, | |||
436 | inet->daddr != LOOPBACK4_IPV6)) { | 436 | inet->daddr != LOOPBACK4_IPV6)) { |
437 | #endif | 437 | #endif |
438 | if (inet->opt) | 438 | if (inet->opt) |
439 | tp->ext_header_len -= inet->opt->optlen; | 439 | icsk->icsk_ext_hdr_len -= inet->opt->optlen; |
440 | if (opt) | 440 | if (opt) |
441 | tp->ext_header_len += opt->optlen; | 441 | icsk->icsk_ext_hdr_len += opt->optlen; |
442 | tcp_sync_mss(sk, tp->pmtu_cookie); | 442 | icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie); |
443 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 443 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
444 | } | 444 | } |
445 | #endif | 445 | #endif |
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index fc718df17b40..d64e2ec8da7b 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <net/xfrm.h> | 28 | #include <net/xfrm.h> |
29 | #include <net/icmp.h> | 29 | #include <net/icmp.h> |
30 | #include <net/ipcomp.h> | 30 | #include <net/ipcomp.h> |
31 | #include <net/protocol.h> | ||
31 | 32 | ||
32 | struct ipcomp_tfms { | 33 | struct ipcomp_tfms { |
33 | struct list_head list; | 34 | struct list_head list; |
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index e8674baaa8d9..bb3613ec448c 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/in.h> | 42 | #include <linux/in.h> |
43 | #include <linux/if.h> | 43 | #include <linux/if.h> |
44 | #include <linux/inet.h> | 44 | #include <linux/inet.h> |
45 | #include <linux/inetdevice.h> | ||
45 | #include <linux/netdevice.h> | 46 | #include <linux/netdevice.h> |
46 | #include <linux/if_arp.h> | 47 | #include <linux/if_arp.h> |
47 | #include <linux/skbuff.h> | 48 | #include <linux/skbuff.h> |
@@ -58,6 +59,7 @@ | |||
58 | #include <net/arp.h> | 59 | #include <net/arp.h> |
59 | #include <net/ip.h> | 60 | #include <net/ip.h> |
60 | #include <net/ipconfig.h> | 61 | #include <net/ipconfig.h> |
62 | #include <net/route.h> | ||
61 | 63 | ||
62 | #include <asm/uaccess.h> | 64 | #include <asm/uaccess.h> |
63 | #include <net/checksum.h> | 65 | #include <net/checksum.h> |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 302b7eb507c9..caa3b7d2e48a 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <net/ip.h> | 52 | #include <net/ip.h> |
53 | #include <net/protocol.h> | 53 | #include <net/protocol.h> |
54 | #include <linux/skbuff.h> | 54 | #include <linux/skbuff.h> |
55 | #include <net/route.h> | ||
55 | #include <net/sock.h> | 56 | #include <net/sock.h> |
56 | #include <net/icmp.h> | 57 | #include <net/icmp.h> |
57 | #include <net/udp.h> | 58 | #include <net/udp.h> |
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c index d7eb680101c2..9b176a942ac5 100644 --- a/net/ipv4/ipvs/ip_vs_app.c +++ b/net/ipv4/ipvs/ip_vs_app.c | |||
@@ -224,34 +224,6 @@ void unregister_ip_vs_app(struct ip_vs_app *app) | |||
224 | } | 224 | } |
225 | 225 | ||
226 | 226 | ||
227 | #if 0000 | ||
228 | /* | ||
229 | * Get reference to app by name (called from user context) | ||
230 | */ | ||
231 | struct ip_vs_app *ip_vs_app_get_by_name(char *appname) | ||
232 | { | ||
233 | struct ip_vs_app *app, *a = NULL; | ||
234 | |||
235 | down(&__ip_vs_app_mutex); | ||
236 | |||
237 | list_for_each_entry(ent, &ip_vs_app_list, a_list) { | ||
238 | if (strcmp(app->name, appname)) | ||
239 | continue; | ||
240 | |||
241 | /* softirq may call ip_vs_app_get too, so the caller | ||
242 | must disable softirq on the current CPU */ | ||
243 | if (ip_vs_app_get(app)) | ||
244 | a = app; | ||
245 | break; | ||
246 | } | ||
247 | |||
248 | up(&__ip_vs_app_mutex); | ||
249 | |||
250 | return a; | ||
251 | } | ||
252 | #endif | ||
253 | |||
254 | |||
255 | /* | 227 | /* |
256 | * Bind ip_vs_conn to its ip_vs_app (called by cp constructor) | 228 | * Bind ip_vs_conn to its ip_vs_app (called by cp constructor) |
257 | */ | 229 | */ |
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c index 2a3a8c59c655..81d90354c928 100644 --- a/net/ipv4/ipvs/ip_vs_conn.c +++ b/net/ipv4/ipvs/ip_vs_conn.c | |||
@@ -24,7 +24,10 @@ | |||
24 | * | 24 | * |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/in.h> | ||
28 | #include <linux/net.h> | ||
27 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/module.h> | ||
28 | #include <linux/vmalloc.h> | 31 | #include <linux/vmalloc.h> |
29 | #include <linux/proc_fs.h> /* for proc_net_* */ | 32 | #include <linux/proc_fs.h> /* for proc_net_* */ |
30 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
@@ -219,7 +222,7 @@ struct ip_vs_conn *ip_vs_conn_in_get | |||
219 | if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt)) | 222 | if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt)) |
220 | cp = __ip_vs_conn_in_get(protocol, s_addr, 0, d_addr, d_port); | 223 | cp = __ip_vs_conn_in_get(protocol, s_addr, 0, d_addr, d_port); |
221 | 224 | ||
222 | IP_VS_DBG(7, "lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n", | 225 | IP_VS_DBG(9, "lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n", |
223 | ip_vs_proto_name(protocol), | 226 | ip_vs_proto_name(protocol), |
224 | NIPQUAD(s_addr), ntohs(s_port), | 227 | NIPQUAD(s_addr), ntohs(s_port), |
225 | NIPQUAD(d_addr), ntohs(d_port), | 228 | NIPQUAD(d_addr), ntohs(d_port), |
@@ -254,7 +257,7 @@ struct ip_vs_conn *ip_vs_ct_in_get | |||
254 | out: | 257 | out: |
255 | ct_read_unlock(hash); | 258 | ct_read_unlock(hash); |
256 | 259 | ||
257 | IP_VS_DBG(7, "template lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n", | 260 | IP_VS_DBG(9, "template lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n", |
258 | ip_vs_proto_name(protocol), | 261 | ip_vs_proto_name(protocol), |
259 | NIPQUAD(s_addr), ntohs(s_port), | 262 | NIPQUAD(s_addr), ntohs(s_port), |
260 | NIPQUAD(d_addr), ntohs(d_port), | 263 | NIPQUAD(d_addr), ntohs(d_port), |
@@ -295,7 +298,7 @@ struct ip_vs_conn *ip_vs_conn_out_get | |||
295 | 298 | ||
296 | ct_read_unlock(hash); | 299 | ct_read_unlock(hash); |
297 | 300 | ||
298 | IP_VS_DBG(7, "lookup/out %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n", | 301 | IP_VS_DBG(9, "lookup/out %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n", |
299 | ip_vs_proto_name(protocol), | 302 | ip_vs_proto_name(protocol), |
300 | NIPQUAD(s_addr), ntohs(s_port), | 303 | NIPQUAD(s_addr), ntohs(s_port), |
301 | NIPQUAD(d_addr), ntohs(d_port), | 304 | NIPQUAD(d_addr), ntohs(d_port), |
@@ -391,8 +394,9 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest) | |||
391 | cp->flags |= atomic_read(&dest->conn_flags); | 394 | cp->flags |= atomic_read(&dest->conn_flags); |
392 | cp->dest = dest; | 395 | cp->dest = dest; |
393 | 396 | ||
394 | IP_VS_DBG(9, "Bind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d " | 397 | IP_VS_DBG(7, "Bind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d " |
395 | "d:%u.%u.%u.%u:%d fwd:%c s:%u flg:%X cnt:%d destcnt:%d\n", | 398 | "d:%u.%u.%u.%u:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d " |
399 | "dest->refcnt:%d\n", | ||
396 | ip_vs_proto_name(cp->protocol), | 400 | ip_vs_proto_name(cp->protocol), |
397 | NIPQUAD(cp->caddr), ntohs(cp->cport), | 401 | NIPQUAD(cp->caddr), ntohs(cp->cport), |
398 | NIPQUAD(cp->vaddr), ntohs(cp->vport), | 402 | NIPQUAD(cp->vaddr), ntohs(cp->vport), |
@@ -430,8 +434,9 @@ static inline void ip_vs_unbind_dest(struct ip_vs_conn *cp) | |||
430 | if (!dest) | 434 | if (!dest) |
431 | return; | 435 | return; |
432 | 436 | ||
433 | IP_VS_DBG(9, "Unbind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d " | 437 | IP_VS_DBG(7, "Unbind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d " |
434 | "d:%u.%u.%u.%u:%d fwd:%c s:%u flg:%X cnt:%d destcnt:%d\n", | 438 | "d:%u.%u.%u.%u:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d " |
439 | "dest->refcnt:%d\n", | ||
435 | ip_vs_proto_name(cp->protocol), | 440 | ip_vs_proto_name(cp->protocol), |
436 | NIPQUAD(cp->caddr), ntohs(cp->cport), | 441 | NIPQUAD(cp->caddr), ntohs(cp->cport), |
437 | NIPQUAD(cp->vaddr), ntohs(cp->vport), | 442 | NIPQUAD(cp->vaddr), ntohs(cp->vport), |
@@ -571,7 +576,7 @@ static void ip_vs_conn_expire(unsigned long data) | |||
571 | ip_vs_conn_hash(cp); | 576 | ip_vs_conn_hash(cp); |
572 | 577 | ||
573 | expire_later: | 578 | expire_later: |
574 | IP_VS_DBG(7, "delayed: refcnt-1=%d conn.n_control=%d\n", | 579 | IP_VS_DBG(7, "delayed: conn->refcnt-1=%d conn->n_control=%d\n", |
575 | atomic_read(&cp->refcnt)-1, | 580 | atomic_read(&cp->refcnt)-1, |
576 | atomic_read(&cp->n_control)); | 581 | atomic_read(&cp->n_control)); |
577 | 582 | ||
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c index 1a0843cd58a9..1aca94a9fd8b 100644 --- a/net/ipv4/ipvs/ip_vs_core.c +++ b/net/ipv4/ipvs/ip_vs_core.c | |||
@@ -426,7 +426,7 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) | |||
426 | return NULL; | 426 | return NULL; |
427 | 427 | ||
428 | IP_VS_DBG(6, "Schedule fwd:%c c:%u.%u.%u.%u:%u v:%u.%u.%u.%u:%u " | 428 | IP_VS_DBG(6, "Schedule fwd:%c c:%u.%u.%u.%u:%u v:%u.%u.%u.%u:%u " |
429 | "d:%u.%u.%u.%u:%u flg:%X cnt:%d\n", | 429 | "d:%u.%u.%u.%u:%u conn->flags:%X conn->refcnt:%d\n", |
430 | ip_vs_fwd_tag(cp), | 430 | ip_vs_fwd_tag(cp), |
431 | NIPQUAD(cp->caddr), ntohs(cp->cport), | 431 | NIPQUAD(cp->caddr), ntohs(cp->cport), |
432 | NIPQUAD(cp->vaddr), ntohs(cp->vport), | 432 | NIPQUAD(cp->vaddr), ntohs(cp->vport), |
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c index 9bdcf31b760e..c935c5086d33 100644 --- a/net/ipv4/ipvs/ip_vs_ctl.c +++ b/net/ipv4/ipvs/ip_vs_ctl.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/netfilter_ipv4.h> | 35 | #include <linux/netfilter_ipv4.h> |
36 | 36 | ||
37 | #include <net/ip.h> | 37 | #include <net/ip.h> |
38 | #include <net/route.h> | ||
38 | #include <net/sock.h> | 39 | #include <net/sock.h> |
39 | 40 | ||
40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
@@ -447,7 +448,7 @@ ip_vs_service_get(__u32 fwmark, __u16 protocol, __u32 vaddr, __u16 vport) | |||
447 | out: | 448 | out: |
448 | read_unlock(&__ip_vs_svc_lock); | 449 | read_unlock(&__ip_vs_svc_lock); |
449 | 450 | ||
450 | IP_VS_DBG(6, "lookup service: fwm %u %s %u.%u.%u.%u:%u %s\n", | 451 | IP_VS_DBG(9, "lookup service: fwm %u %s %u.%u.%u.%u:%u %s\n", |
451 | fwmark, ip_vs_proto_name(protocol), | 452 | fwmark, ip_vs_proto_name(protocol), |
452 | NIPQUAD(vaddr), ntohs(vport), | 453 | NIPQUAD(vaddr), ntohs(vport), |
453 | svc?"hit":"not hit"); | 454 | svc?"hit":"not hit"); |
@@ -597,7 +598,7 @@ ip_vs_trash_get_dest(struct ip_vs_service *svc, __u32 daddr, __u16 dport) | |||
597 | */ | 598 | */ |
598 | list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) { | 599 | list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) { |
599 | IP_VS_DBG(3, "Destination %u/%u.%u.%u.%u:%u still in trash, " | 600 | IP_VS_DBG(3, "Destination %u/%u.%u.%u.%u:%u still in trash, " |
600 | "refcnt=%d\n", | 601 | "dest->refcnt=%d\n", |
601 | dest->vfwmark, | 602 | dest->vfwmark, |
602 | NIPQUAD(dest->addr), ntohs(dest->port), | 603 | NIPQUAD(dest->addr), ntohs(dest->port), |
603 | atomic_read(&dest->refcnt)); | 604 | atomic_read(&dest->refcnt)); |
@@ -804,7 +805,7 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest) | |||
804 | dest = ip_vs_trash_get_dest(svc, daddr, dport); | 805 | dest = ip_vs_trash_get_dest(svc, daddr, dport); |
805 | if (dest != NULL) { | 806 | if (dest != NULL) { |
806 | IP_VS_DBG(3, "Get destination %u.%u.%u.%u:%u from trash, " | 807 | IP_VS_DBG(3, "Get destination %u.%u.%u.%u:%u from trash, " |
807 | "refcnt=%d, service %u/%u.%u.%u.%u:%u\n", | 808 | "dest->refcnt=%d, service %u/%u.%u.%u.%u:%u\n", |
808 | NIPQUAD(daddr), ntohs(dport), | 809 | NIPQUAD(daddr), ntohs(dport), |
809 | atomic_read(&dest->refcnt), | 810 | atomic_read(&dest->refcnt), |
810 | dest->vfwmark, | 811 | dest->vfwmark, |
@@ -949,7 +950,8 @@ static void __ip_vs_del_dest(struct ip_vs_dest *dest) | |||
949 | atomic_dec(&dest->svc->refcnt); | 950 | atomic_dec(&dest->svc->refcnt); |
950 | kfree(dest); | 951 | kfree(dest); |
951 | } else { | 952 | } else { |
952 | IP_VS_DBG(3, "Moving dest %u.%u.%u.%u:%u into trash, refcnt=%d\n", | 953 | IP_VS_DBG(3, "Moving dest %u.%u.%u.%u:%u into trash, " |
954 | "dest->refcnt=%d\n", | ||
953 | NIPQUAD(dest->addr), ntohs(dest->port), | 955 | NIPQUAD(dest->addr), ntohs(dest->port), |
954 | atomic_read(&dest->refcnt)); | 956 | atomic_read(&dest->refcnt)); |
955 | list_add(&dest->n_list, &ip_vs_dest_trash); | 957 | list_add(&dest->n_list, &ip_vs_dest_trash); |
diff --git a/net/ipv4/ipvs/ip_vs_dh.c b/net/ipv4/ipvs/ip_vs_dh.c index f3bc320dce93..9fee19c4c617 100644 --- a/net/ipv4/ipvs/ip_vs_dh.c +++ b/net/ipv4/ipvs/ip_vs_dh.c | |||
@@ -37,8 +37,10 @@ | |||
37 | * | 37 | * |
38 | */ | 38 | */ |
39 | 39 | ||
40 | #include <linux/ip.h> | ||
40 | #include <linux/module.h> | 41 | #include <linux/module.h> |
41 | #include <linux/kernel.h> | 42 | #include <linux/kernel.h> |
43 | #include <linux/skbuff.h> | ||
42 | 44 | ||
43 | #include <net/ip_vs.h> | 45 | #include <net/ip_vs.h> |
44 | 46 | ||
diff --git a/net/ipv4/ipvs/ip_vs_est.c b/net/ipv4/ipvs/ip_vs_est.c index 67b3e2fc1fa1..e7004741ac73 100644 --- a/net/ipv4/ipvs/ip_vs_est.c +++ b/net/ipv4/ipvs/ip_vs_est.c | |||
@@ -13,7 +13,10 @@ | |||
13 | * Changes: | 13 | * Changes: |
14 | * | 14 | * |
15 | */ | 15 | */ |
16 | #include <linux/config.h> | ||
16 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/jiffies.h> | ||
19 | #include <linux/slab.h> | ||
17 | #include <linux/types.h> | 20 | #include <linux/types.h> |
18 | 21 | ||
19 | #include <net/ip_vs.h> | 22 | #include <net/ip_vs.h> |
diff --git a/net/ipv4/ipvs/ip_vs_lblc.c b/net/ipv4/ipvs/ip_vs_lblc.c index 561cda326fa8..6e5cb92a5c83 100644 --- a/net/ipv4/ipvs/ip_vs_lblc.c +++ b/net/ipv4/ipvs/ip_vs_lblc.c | |||
@@ -41,8 +41,10 @@ | |||
41 | * me to write this module. | 41 | * me to write this module. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/ip.h> | ||
44 | #include <linux/module.h> | 45 | #include <linux/module.h> |
45 | #include <linux/kernel.h> | 46 | #include <linux/kernel.h> |
47 | #include <linux/skbuff.h> | ||
46 | 48 | ||
47 | /* for sysctl */ | 49 | /* for sysctl */ |
48 | #include <linux/fs.h> | 50 | #include <linux/fs.h> |
@@ -228,33 +230,6 @@ ip_vs_lblc_hash(struct ip_vs_lblc_table *tbl, struct ip_vs_lblc_entry *en) | |||
228 | } | 230 | } |
229 | 231 | ||
230 | 232 | ||
231 | #if 0000 | ||
232 | /* | ||
233 | * Unhash ip_vs_lblc_entry from ip_vs_lblc_table. | ||
234 | * returns bool success. | ||
235 | */ | ||
236 | static int ip_vs_lblc_unhash(struct ip_vs_lblc_table *tbl, | ||
237 | struct ip_vs_lblc_entry *en) | ||
238 | { | ||
239 | if (list_empty(&en->list)) { | ||
240 | IP_VS_ERR("ip_vs_lblc_unhash(): request for not hashed entry, " | ||
241 | "called from %p\n", __builtin_return_address(0)); | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * Remove it from the table | ||
247 | */ | ||
248 | write_lock(&tbl->lock); | ||
249 | list_del(&en->list); | ||
250 | INIT_LIST_HEAD(&en->list); | ||
251 | write_unlock(&tbl->lock); | ||
252 | |||
253 | return 1; | ||
254 | } | ||
255 | #endif | ||
256 | |||
257 | |||
258 | /* | 233 | /* |
259 | * Get ip_vs_lblc_entry associated with supplied parameters. | 234 | * Get ip_vs_lblc_entry associated with supplied parameters. |
260 | */ | 235 | */ |
diff --git a/net/ipv4/ipvs/ip_vs_lblcr.c b/net/ipv4/ipvs/ip_vs_lblcr.c index ce456dbf09a5..32ba37ba72d8 100644 --- a/net/ipv4/ipvs/ip_vs_lblcr.c +++ b/net/ipv4/ipvs/ip_vs_lblcr.c | |||
@@ -39,8 +39,10 @@ | |||
39 | * | 39 | * |
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include <linux/ip.h> | ||
42 | #include <linux/module.h> | 43 | #include <linux/module.h> |
43 | #include <linux/kernel.h> | 44 | #include <linux/kernel.h> |
45 | #include <linux/skbuff.h> | ||
44 | 46 | ||
45 | /* for sysctl */ | 47 | /* for sysctl */ |
46 | #include <linux/fs.h> | 48 | #include <linux/fs.h> |
@@ -414,33 +416,6 @@ ip_vs_lblcr_hash(struct ip_vs_lblcr_table *tbl, struct ip_vs_lblcr_entry *en) | |||
414 | } | 416 | } |
415 | 417 | ||
416 | 418 | ||
417 | #if 0000 | ||
418 | /* | ||
419 | * Unhash ip_vs_lblcr_entry from ip_vs_lblcr_table. | ||
420 | * returns bool success. | ||
421 | */ | ||
422 | static int ip_vs_lblcr_unhash(struct ip_vs_lblcr_table *tbl, | ||
423 | struct ip_vs_lblcr_entry *en) | ||
424 | { | ||
425 | if (list_empty(&en->list)) { | ||
426 | IP_VS_ERR("ip_vs_lblcr_unhash(): request for not hashed entry, " | ||
427 | "called from %p\n", __builtin_return_address(0)); | ||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * Remove it from the table | ||
433 | */ | ||
434 | write_lock(&tbl->lock); | ||
435 | list_del(&en->list); | ||
436 | INIT_LIST_HEAD(&en->list); | ||
437 | write_unlock(&tbl->lock); | ||
438 | |||
439 | return 1; | ||
440 | } | ||
441 | #endif | ||
442 | |||
443 | |||
444 | /* | 419 | /* |
445 | * Get ip_vs_lblcr_entry associated with supplied parameters. | 420 | * Get ip_vs_lblcr_entry associated with supplied parameters. |
446 | */ | 421 | */ |
diff --git a/net/ipv4/ipvs/ip_vs_proto_ah.c b/net/ipv4/ipvs/ip_vs_proto_ah.c index 453e94a0bbd7..8b0505b09317 100644 --- a/net/ipv4/ipvs/ip_vs_proto_ah.c +++ b/net/ipv4/ipvs/ip_vs_proto_ah.c | |||
@@ -12,6 +12,8 @@ | |||
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/in.h> | ||
16 | #include <linux/ip.h> | ||
15 | #include <linux/module.h> | 17 | #include <linux/module.h> |
16 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
17 | #include <linux/netfilter.h> | 19 | #include <linux/netfilter.h> |
diff --git a/net/ipv4/ipvs/ip_vs_proto_esp.c b/net/ipv4/ipvs/ip_vs_proto_esp.c index 478e5c7c7e8e..c36ccf057a19 100644 --- a/net/ipv4/ipvs/ip_vs_proto_esp.c +++ b/net/ipv4/ipvs/ip_vs_proto_esp.c | |||
@@ -12,6 +12,8 @@ | |||
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/in.h> | ||
16 | #include <linux/ip.h> | ||
15 | #include <linux/module.h> | 17 | #include <linux/module.h> |
16 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
17 | #include <linux/netfilter.h> | 19 | #include <linux/netfilter.h> |
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c index 0e878fd6215c..bc28b1160a3a 100644 --- a/net/ipv4/ipvs/ip_vs_proto_tcp.c +++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c | |||
@@ -275,28 +275,6 @@ static int tcp_timeouts[IP_VS_TCP_S_LAST+1] = { | |||
275 | [IP_VS_TCP_S_LAST] = 2*HZ, | 275 | [IP_VS_TCP_S_LAST] = 2*HZ, |
276 | }; | 276 | }; |
277 | 277 | ||
278 | |||
279 | #if 0 | ||
280 | |||
281 | /* FIXME: This is going to die */ | ||
282 | |||
283 | static int tcp_timeouts_dos[IP_VS_TCP_S_LAST+1] = { | ||
284 | [IP_VS_TCP_S_NONE] = 2*HZ, | ||
285 | [IP_VS_TCP_S_ESTABLISHED] = 8*60*HZ, | ||
286 | [IP_VS_TCP_S_SYN_SENT] = 60*HZ, | ||
287 | [IP_VS_TCP_S_SYN_RECV] = 10*HZ, | ||
288 | [IP_VS_TCP_S_FIN_WAIT] = 60*HZ, | ||
289 | [IP_VS_TCP_S_TIME_WAIT] = 60*HZ, | ||
290 | [IP_VS_TCP_S_CLOSE] = 10*HZ, | ||
291 | [IP_VS_TCP_S_CLOSE_WAIT] = 60*HZ, | ||
292 | [IP_VS_TCP_S_LAST_ACK] = 30*HZ, | ||
293 | [IP_VS_TCP_S_LISTEN] = 2*60*HZ, | ||
294 | [IP_VS_TCP_S_SYNACK] = 100*HZ, | ||
295 | [IP_VS_TCP_S_LAST] = 2*HZ, | ||
296 | }; | ||
297 | |||
298 | #endif | ||
299 | |||
300 | static char * tcp_state_name_table[IP_VS_TCP_S_LAST+1] = { | 278 | static char * tcp_state_name_table[IP_VS_TCP_S_LAST+1] = { |
301 | [IP_VS_TCP_S_NONE] = "NONE", | 279 | [IP_VS_TCP_S_NONE] = "NONE", |
302 | [IP_VS_TCP_S_ESTABLISHED] = "ESTABLISHED", | 280 | [IP_VS_TCP_S_ESTABLISHED] = "ESTABLISHED", |
@@ -448,7 +426,7 @@ set_tcp_state(struct ip_vs_protocol *pp, struct ip_vs_conn *cp, | |||
448 | struct ip_vs_dest *dest = cp->dest; | 426 | struct ip_vs_dest *dest = cp->dest; |
449 | 427 | ||
450 | IP_VS_DBG(8, "%s %s [%c%c%c%c] %u.%u.%u.%u:%d->" | 428 | IP_VS_DBG(8, "%s %s [%c%c%c%c] %u.%u.%u.%u:%d->" |
451 | "%u.%u.%u.%u:%d state: %s->%s cnt:%d\n", | 429 | "%u.%u.%u.%u:%d state: %s->%s conn->refcnt:%d\n", |
452 | pp->name, | 430 | pp->name, |
453 | (state_off==TCP_DIR_OUTPUT)?"output ":"input ", | 431 | (state_off==TCP_DIR_OUTPUT)?"output ":"input ", |
454 | th->syn? 'S' : '.', | 432 | th->syn? 'S' : '.', |
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c index 8ae5f2e0aefa..89d9175d8f28 100644 --- a/net/ipv4/ipvs/ip_vs_proto_udp.c +++ b/net/ipv4/ipvs/ip_vs_proto_udp.c | |||
@@ -15,8 +15,11 @@ | |||
15 | * | 15 | * |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/in.h> | ||
19 | #include <linux/ip.h> | ||
18 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
19 | #include <linux/netfilter_ipv4.h> | 21 | #include <linux/netfilter_ipv4.h> |
22 | #include <linux/udp.h> | ||
20 | 23 | ||
21 | #include <net/ip_vs.h> | 24 | #include <net/ip_vs.h> |
22 | 25 | ||
diff --git a/net/ipv4/ipvs/ip_vs_sh.c b/net/ipv4/ipvs/ip_vs_sh.c index 6f7c50e44a39..7775e6cc68be 100644 --- a/net/ipv4/ipvs/ip_vs_sh.c +++ b/net/ipv4/ipvs/ip_vs_sh.c | |||
@@ -34,8 +34,10 @@ | |||
34 | * | 34 | * |
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include <linux/ip.h> | ||
37 | #include <linux/module.h> | 38 | #include <linux/module.h> |
38 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
40 | #include <linux/skbuff.h> | ||
39 | 41 | ||
40 | #include <net/ip_vs.h> | 42 | #include <net/ip_vs.h> |
41 | 43 | ||
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c index 2e5ced3d8062..1bca714bda3d 100644 --- a/net/ipv4/ipvs/ip_vs_sync.c +++ b/net/ipv4/ipvs/ip_vs_sync.c | |||
@@ -21,12 +21,14 @@ | |||
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/inetdevice.h> | ||
24 | #include <linux/net.h> | 25 | #include <linux/net.h> |
25 | #include <linux/completion.h> | 26 | #include <linux/completion.h> |
26 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
27 | #include <linux/skbuff.h> | 28 | #include <linux/skbuff.h> |
28 | #include <linux/in.h> | 29 | #include <linux/in.h> |
29 | #include <linux/igmp.h> /* for ip_mc_join_group */ | 30 | #include <linux/igmp.h> /* for ip_mc_join_group */ |
31 | #include <linux/udp.h> | ||
30 | 32 | ||
31 | #include <net/ip.h> | 33 | #include <net/ip.h> |
32 | #include <net/sock.h> | 34 | #include <net/sock.h> |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 058c48e258fc..d0a447e520a2 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -12,6 +12,7 @@ ip_nat_pptp-objs := ip_nat_helper_pptp.o ip_nat_proto_gre.o | |||
12 | 12 | ||
13 | # connection tracking | 13 | # connection tracking |
14 | obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o | 14 | obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o |
15 | obj-$(CONFIG_IP_NF_NAT) += ip_nat.o | ||
15 | 16 | ||
16 | # conntrack netlink interface | 17 | # conntrack netlink interface |
17 | obj-$(CONFIG_IP_NF_CONNTRACK_NETLINK) += ip_conntrack_netlink.o | 18 | obj-$(CONFIG_IP_NF_CONNTRACK_NETLINK) += ip_conntrack_netlink.o |
@@ -41,7 +42,7 @@ obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o | |||
41 | # the three instances of ip_tables | 42 | # the three instances of ip_tables |
42 | obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o | 43 | obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o |
43 | obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o | 44 | obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o |
44 | obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o ip_nat.o | 45 | obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o |
45 | obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o | 46 | obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o |
46 | 47 | ||
47 | # matches | 48 | # matches |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 3c2e9639bba6..bba156304695 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -68,19 +68,14 @@ struct arpt_table_info { | |||
68 | unsigned int initial_entries; | 68 | unsigned int initial_entries; |
69 | unsigned int hook_entry[NF_ARP_NUMHOOKS]; | 69 | unsigned int hook_entry[NF_ARP_NUMHOOKS]; |
70 | unsigned int underflow[NF_ARP_NUMHOOKS]; | 70 | unsigned int underflow[NF_ARP_NUMHOOKS]; |
71 | char entries[0] __attribute__((aligned(SMP_CACHE_BYTES))); | 71 | void *entries[NR_CPUS]; |
72 | }; | 72 | }; |
73 | 73 | ||
74 | static LIST_HEAD(arpt_target); | 74 | static LIST_HEAD(arpt_target); |
75 | static LIST_HEAD(arpt_tables); | 75 | static LIST_HEAD(arpt_tables); |
76 | #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) | ||
76 | #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) | 77 | #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) |
77 | 78 | ||
78 | #ifdef CONFIG_SMP | ||
79 | #define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p)) | ||
80 | #else | ||
81 | #define TABLE_OFFSET(t,p) 0 | ||
82 | #endif | ||
83 | |||
84 | static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, | 79 | static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, |
85 | char *hdr_addr, int len) | 80 | char *hdr_addr, int len) |
86 | { | 81 | { |
@@ -269,9 +264,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb, | |||
269 | outdev = out ? out->name : nulldevname; | 264 | outdev = out ? out->name : nulldevname; |
270 | 265 | ||
271 | read_lock_bh(&table->lock); | 266 | read_lock_bh(&table->lock); |
272 | table_base = (void *)table->private->entries | 267 | table_base = (void *)table->private->entries[smp_processor_id()]; |
273 | + TABLE_OFFSET(table->private, | ||
274 | smp_processor_id()); | ||
275 | e = get_entry(table_base, table->private->hook_entry[hook]); | 268 | e = get_entry(table_base, table->private->hook_entry[hook]); |
276 | back = get_entry(table_base, table->private->underflow[hook]); | 269 | back = get_entry(table_base, table->private->underflow[hook]); |
277 | 270 | ||
@@ -462,7 +455,8 @@ static inline int unconditional(const struct arpt_arp *arp) | |||
462 | /* Figures out from what hook each rule can be called: returns 0 if | 455 | /* Figures out from what hook each rule can be called: returns 0 if |
463 | * there are loops. Puts hook bitmask in comefrom. | 456 | * there are loops. Puts hook bitmask in comefrom. |
464 | */ | 457 | */ |
465 | static int mark_source_chains(struct arpt_table_info *newinfo, unsigned int valid_hooks) | 458 | static int mark_source_chains(struct arpt_table_info *newinfo, |
459 | unsigned int valid_hooks, void *entry0) | ||
466 | { | 460 | { |
467 | unsigned int hook; | 461 | unsigned int hook; |
468 | 462 | ||
@@ -472,7 +466,7 @@ static int mark_source_chains(struct arpt_table_info *newinfo, unsigned int vali | |||
472 | for (hook = 0; hook < NF_ARP_NUMHOOKS; hook++) { | 466 | for (hook = 0; hook < NF_ARP_NUMHOOKS; hook++) { |
473 | unsigned int pos = newinfo->hook_entry[hook]; | 467 | unsigned int pos = newinfo->hook_entry[hook]; |
474 | struct arpt_entry *e | 468 | struct arpt_entry *e |
475 | = (struct arpt_entry *)(newinfo->entries + pos); | 469 | = (struct arpt_entry *)(entry0 + pos); |
476 | 470 | ||
477 | if (!(valid_hooks & (1 << hook))) | 471 | if (!(valid_hooks & (1 << hook))) |
478 | continue; | 472 | continue; |
@@ -514,13 +508,13 @@ static int mark_source_chains(struct arpt_table_info *newinfo, unsigned int vali | |||
514 | goto next; | 508 | goto next; |
515 | 509 | ||
516 | e = (struct arpt_entry *) | 510 | e = (struct arpt_entry *) |
517 | (newinfo->entries + pos); | 511 | (entry0 + pos); |
518 | } while (oldpos == pos + e->next_offset); | 512 | } while (oldpos == pos + e->next_offset); |
519 | 513 | ||
520 | /* Move along one */ | 514 | /* Move along one */ |
521 | size = e->next_offset; | 515 | size = e->next_offset; |
522 | e = (struct arpt_entry *) | 516 | e = (struct arpt_entry *) |
523 | (newinfo->entries + pos + size); | 517 | (entry0 + pos + size); |
524 | e->counters.pcnt = pos; | 518 | e->counters.pcnt = pos; |
525 | pos += size; | 519 | pos += size; |
526 | } else { | 520 | } else { |
@@ -537,7 +531,7 @@ static int mark_source_chains(struct arpt_table_info *newinfo, unsigned int vali | |||
537 | newpos = pos + e->next_offset; | 531 | newpos = pos + e->next_offset; |
538 | } | 532 | } |
539 | e = (struct arpt_entry *) | 533 | e = (struct arpt_entry *) |
540 | (newinfo->entries + newpos); | 534 | (entry0 + newpos); |
541 | e->counters.pcnt = pos; | 535 | e->counters.pcnt = pos; |
542 | pos = newpos; | 536 | pos = newpos; |
543 | } | 537 | } |
@@ -689,6 +683,7 @@ static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i) | |||
689 | static int translate_table(const char *name, | 683 | static int translate_table(const char *name, |
690 | unsigned int valid_hooks, | 684 | unsigned int valid_hooks, |
691 | struct arpt_table_info *newinfo, | 685 | struct arpt_table_info *newinfo, |
686 | void *entry0, | ||
692 | unsigned int size, | 687 | unsigned int size, |
693 | unsigned int number, | 688 | unsigned int number, |
694 | const unsigned int *hook_entries, | 689 | const unsigned int *hook_entries, |
@@ -710,11 +705,11 @@ static int translate_table(const char *name, | |||
710 | i = 0; | 705 | i = 0; |
711 | 706 | ||
712 | /* Walk through entries, checking offsets. */ | 707 | /* Walk through entries, checking offsets. */ |
713 | ret = ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, | 708 | ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, |
714 | check_entry_size_and_hooks, | 709 | check_entry_size_and_hooks, |
715 | newinfo, | 710 | newinfo, |
716 | newinfo->entries, | 711 | entry0, |
717 | newinfo->entries + size, | 712 | entry0 + size, |
718 | hook_entries, underflows, &i); | 713 | hook_entries, underflows, &i); |
719 | duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret); | 714 | duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret); |
720 | if (ret != 0) | 715 | if (ret != 0) |
@@ -743,29 +738,26 @@ static int translate_table(const char *name, | |||
743 | } | 738 | } |
744 | } | 739 | } |
745 | 740 | ||
746 | if (!mark_source_chains(newinfo, valid_hooks)) { | 741 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) { |
747 | duprintf("Looping hook\n"); | 742 | duprintf("Looping hook\n"); |
748 | return -ELOOP; | 743 | return -ELOOP; |
749 | } | 744 | } |
750 | 745 | ||
751 | /* Finally, each sanity check must pass */ | 746 | /* Finally, each sanity check must pass */ |
752 | i = 0; | 747 | i = 0; |
753 | ret = ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, | 748 | ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, |
754 | check_entry, name, size, &i); | 749 | check_entry, name, size, &i); |
755 | 750 | ||
756 | if (ret != 0) { | 751 | if (ret != 0) { |
757 | ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, | 752 | ARPT_ENTRY_ITERATE(entry0, newinfo->size, |
758 | cleanup_entry, &i); | 753 | cleanup_entry, &i); |
759 | return ret; | 754 | return ret; |
760 | } | 755 | } |
761 | 756 | ||
762 | /* And one copy for every other CPU */ | 757 | /* And one copy for every other CPU */ |
763 | for_each_cpu(i) { | 758 | for_each_cpu(i) { |
764 | if (i == 0) | 759 | if (newinfo->entries[i] && newinfo->entries[i] != entry0) |
765 | continue; | 760 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
766 | memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i, | ||
767 | newinfo->entries, | ||
768 | SMP_ALIGN(newinfo->size)); | ||
769 | } | 761 | } |
770 | 762 | ||
771 | return ret; | 763 | return ret; |
@@ -807,15 +799,42 @@ static inline int add_entry_to_counter(const struct arpt_entry *e, | |||
807 | return 0; | 799 | return 0; |
808 | } | 800 | } |
809 | 801 | ||
802 | static inline int set_entry_to_counter(const struct arpt_entry *e, | ||
803 | struct arpt_counters total[], | ||
804 | unsigned int *i) | ||
805 | { | ||
806 | SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); | ||
807 | |||
808 | (*i)++; | ||
809 | return 0; | ||
810 | } | ||
811 | |||
810 | static void get_counters(const struct arpt_table_info *t, | 812 | static void get_counters(const struct arpt_table_info *t, |
811 | struct arpt_counters counters[]) | 813 | struct arpt_counters counters[]) |
812 | { | 814 | { |
813 | unsigned int cpu; | 815 | unsigned int cpu; |
814 | unsigned int i; | 816 | unsigned int i; |
817 | unsigned int curcpu; | ||
818 | |||
819 | /* Instead of clearing (by a previous call to memset()) | ||
820 | * the counters and using adds, we set the counters | ||
821 | * with data used by 'current' CPU | ||
822 | * We dont care about preemption here. | ||
823 | */ | ||
824 | curcpu = raw_smp_processor_id(); | ||
825 | |||
826 | i = 0; | ||
827 | ARPT_ENTRY_ITERATE(t->entries[curcpu], | ||
828 | t->size, | ||
829 | set_entry_to_counter, | ||
830 | counters, | ||
831 | &i); | ||
815 | 832 | ||
816 | for_each_cpu(cpu) { | 833 | for_each_cpu(cpu) { |
834 | if (cpu == curcpu) | ||
835 | continue; | ||
817 | i = 0; | 836 | i = 0; |
818 | ARPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu), | 837 | ARPT_ENTRY_ITERATE(t->entries[cpu], |
819 | t->size, | 838 | t->size, |
820 | add_entry_to_counter, | 839 | add_entry_to_counter, |
821 | counters, | 840 | counters, |
@@ -831,6 +850,7 @@ static int copy_entries_to_user(unsigned int total_size, | |||
831 | struct arpt_entry *e; | 850 | struct arpt_entry *e; |
832 | struct arpt_counters *counters; | 851 | struct arpt_counters *counters; |
833 | int ret = 0; | 852 | int ret = 0; |
853 | void *loc_cpu_entry; | ||
834 | 854 | ||
835 | /* We need atomic snapshot of counters: rest doesn't change | 855 | /* We need atomic snapshot of counters: rest doesn't change |
836 | * (other than comefrom, which userspace doesn't care | 856 | * (other than comefrom, which userspace doesn't care |
@@ -843,13 +863,13 @@ static int copy_entries_to_user(unsigned int total_size, | |||
843 | return -ENOMEM; | 863 | return -ENOMEM; |
844 | 864 | ||
845 | /* First, sum counters... */ | 865 | /* First, sum counters... */ |
846 | memset(counters, 0, countersize); | ||
847 | write_lock_bh(&table->lock); | 866 | write_lock_bh(&table->lock); |
848 | get_counters(table->private, counters); | 867 | get_counters(table->private, counters); |
849 | write_unlock_bh(&table->lock); | 868 | write_unlock_bh(&table->lock); |
850 | 869 | ||
851 | /* ... then copy entire thing from CPU 0... */ | 870 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; |
852 | if (copy_to_user(userptr, table->private->entries, total_size) != 0) { | 871 | /* ... then copy entire thing ... */ |
872 | if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { | ||
853 | ret = -EFAULT; | 873 | ret = -EFAULT; |
854 | goto free_counters; | 874 | goto free_counters; |
855 | } | 875 | } |
@@ -859,7 +879,7 @@ static int copy_entries_to_user(unsigned int total_size, | |||
859 | for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ | 879 | for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ |
860 | struct arpt_entry_target *t; | 880 | struct arpt_entry_target *t; |
861 | 881 | ||
862 | e = (struct arpt_entry *)(table->private->entries + off); | 882 | e = (struct arpt_entry *)(loc_cpu_entry + off); |
863 | if (copy_to_user(userptr + off | 883 | if (copy_to_user(userptr + off |
864 | + offsetof(struct arpt_entry, counters), | 884 | + offsetof(struct arpt_entry, counters), |
865 | &counters[num], | 885 | &counters[num], |
@@ -911,6 +931,47 @@ static int get_entries(const struct arpt_get_entries *entries, | |||
911 | return ret; | 931 | return ret; |
912 | } | 932 | } |
913 | 933 | ||
934 | static void free_table_info(struct arpt_table_info *info) | ||
935 | { | ||
936 | int cpu; | ||
937 | for_each_cpu(cpu) { | ||
938 | if (info->size <= PAGE_SIZE) | ||
939 | kfree(info->entries[cpu]); | ||
940 | else | ||
941 | vfree(info->entries[cpu]); | ||
942 | } | ||
943 | kfree(info); | ||
944 | } | ||
945 | |||
946 | static struct arpt_table_info *alloc_table_info(unsigned int size) | ||
947 | { | ||
948 | struct arpt_table_info *newinfo; | ||
949 | int cpu; | ||
950 | |||
951 | newinfo = kzalloc(sizeof(struct arpt_table_info), GFP_KERNEL); | ||
952 | if (!newinfo) | ||
953 | return NULL; | ||
954 | |||
955 | newinfo->size = size; | ||
956 | |||
957 | for_each_cpu(cpu) { | ||
958 | if (size <= PAGE_SIZE) | ||
959 | newinfo->entries[cpu] = kmalloc_node(size, | ||
960 | GFP_KERNEL, | ||
961 | cpu_to_node(cpu)); | ||
962 | else | ||
963 | newinfo->entries[cpu] = vmalloc_node(size, | ||
964 | cpu_to_node(cpu)); | ||
965 | |||
966 | if (newinfo->entries[cpu] == NULL) { | ||
967 | free_table_info(newinfo); | ||
968 | return NULL; | ||
969 | } | ||
970 | } | ||
971 | |||
972 | return newinfo; | ||
973 | } | ||
974 | |||
914 | static int do_replace(void __user *user, unsigned int len) | 975 | static int do_replace(void __user *user, unsigned int len) |
915 | { | 976 | { |
916 | int ret; | 977 | int ret; |
@@ -918,6 +979,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
918 | struct arpt_table *t; | 979 | struct arpt_table *t; |
919 | struct arpt_table_info *newinfo, *oldinfo; | 980 | struct arpt_table_info *newinfo, *oldinfo; |
920 | struct arpt_counters *counters; | 981 | struct arpt_counters *counters; |
982 | void *loc_cpu_entry, *loc_cpu_old_entry; | ||
921 | 983 | ||
922 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 984 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
923 | return -EFAULT; | 985 | return -EFAULT; |
@@ -930,13 +992,13 @@ static int do_replace(void __user *user, unsigned int len) | |||
930 | if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) | 992 | if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) |
931 | return -ENOMEM; | 993 | return -ENOMEM; |
932 | 994 | ||
933 | newinfo = vmalloc(sizeof(struct arpt_table_info) | 995 | newinfo = alloc_table_info(tmp.size); |
934 | + SMP_ALIGN(tmp.size) * | ||
935 | (highest_possible_processor_id()+1)); | ||
936 | if (!newinfo) | 996 | if (!newinfo) |
937 | return -ENOMEM; | 997 | return -ENOMEM; |
938 | 998 | ||
939 | if (copy_from_user(newinfo->entries, user + sizeof(tmp), | 999 | /* choose the copy that is on our node/cpu */ |
1000 | loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; | ||
1001 | if (copy_from_user(loc_cpu_entry, user + sizeof(tmp), | ||
940 | tmp.size) != 0) { | 1002 | tmp.size) != 0) { |
941 | ret = -EFAULT; | 1003 | ret = -EFAULT; |
942 | goto free_newinfo; | 1004 | goto free_newinfo; |
@@ -947,10 +1009,9 @@ static int do_replace(void __user *user, unsigned int len) | |||
947 | ret = -ENOMEM; | 1009 | ret = -ENOMEM; |
948 | goto free_newinfo; | 1010 | goto free_newinfo; |
949 | } | 1011 | } |
950 | memset(counters, 0, tmp.num_counters * sizeof(struct arpt_counters)); | ||
951 | 1012 | ||
952 | ret = translate_table(tmp.name, tmp.valid_hooks, | 1013 | ret = translate_table(tmp.name, tmp.valid_hooks, |
953 | newinfo, tmp.size, tmp.num_entries, | 1014 | newinfo, loc_cpu_entry, tmp.size, tmp.num_entries, |
954 | tmp.hook_entry, tmp.underflow); | 1015 | tmp.hook_entry, tmp.underflow); |
955 | if (ret != 0) | 1016 | if (ret != 0) |
956 | goto free_newinfo_counters; | 1017 | goto free_newinfo_counters; |
@@ -989,8 +1050,10 @@ static int do_replace(void __user *user, unsigned int len) | |||
989 | /* Get the old counters. */ | 1050 | /* Get the old counters. */ |
990 | get_counters(oldinfo, counters); | 1051 | get_counters(oldinfo, counters); |
991 | /* Decrease module usage counts and free resource */ | 1052 | /* Decrease module usage counts and free resource */ |
992 | ARPT_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL); | 1053 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; |
993 | vfree(oldinfo); | 1054 | ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); |
1055 | |||
1056 | free_table_info(oldinfo); | ||
994 | if (copy_to_user(tmp.counters, counters, | 1057 | if (copy_to_user(tmp.counters, counters, |
995 | sizeof(struct arpt_counters) * tmp.num_counters) != 0) | 1058 | sizeof(struct arpt_counters) * tmp.num_counters) != 0) |
996 | ret = -EFAULT; | 1059 | ret = -EFAULT; |
@@ -1002,11 +1065,11 @@ static int do_replace(void __user *user, unsigned int len) | |||
1002 | module_put(t->me); | 1065 | module_put(t->me); |
1003 | up(&arpt_mutex); | 1066 | up(&arpt_mutex); |
1004 | free_newinfo_counters_untrans: | 1067 | free_newinfo_counters_untrans: |
1005 | ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry, NULL); | 1068 | ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); |
1006 | free_newinfo_counters: | 1069 | free_newinfo_counters: |
1007 | vfree(counters); | 1070 | vfree(counters); |
1008 | free_newinfo: | 1071 | free_newinfo: |
1009 | vfree(newinfo); | 1072 | free_table_info(newinfo); |
1010 | return ret; | 1073 | return ret; |
1011 | } | 1074 | } |
1012 | 1075 | ||
@@ -1030,6 +1093,7 @@ static int do_add_counters(void __user *user, unsigned int len) | |||
1030 | struct arpt_counters_info tmp, *paddc; | 1093 | struct arpt_counters_info tmp, *paddc; |
1031 | struct arpt_table *t; | 1094 | struct arpt_table *t; |
1032 | int ret = 0; | 1095 | int ret = 0; |
1096 | void *loc_cpu_entry; | ||
1033 | 1097 | ||
1034 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1098 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
1035 | return -EFAULT; | 1099 | return -EFAULT; |
@@ -1059,7 +1123,9 @@ static int do_add_counters(void __user *user, unsigned int len) | |||
1059 | } | 1123 | } |
1060 | 1124 | ||
1061 | i = 0; | 1125 | i = 0; |
1062 | ARPT_ENTRY_ITERATE(t->private->entries, | 1126 | /* Choose the copy that is on our node */ |
1127 | loc_cpu_entry = t->private->entries[smp_processor_id()]; | ||
1128 | ARPT_ENTRY_ITERATE(loc_cpu_entry, | ||
1063 | t->private->size, | 1129 | t->private->size, |
1064 | add_counter_to_entry, | 1130 | add_counter_to_entry, |
1065 | paddc->counters, | 1131 | paddc->counters, |
@@ -1220,30 +1286,32 @@ int arpt_register_table(struct arpt_table *table, | |||
1220 | struct arpt_table_info *newinfo; | 1286 | struct arpt_table_info *newinfo; |
1221 | static struct arpt_table_info bootstrap | 1287 | static struct arpt_table_info bootstrap |
1222 | = { 0, 0, 0, { 0 }, { 0 }, { } }; | 1288 | = { 0, 0, 0, { 0 }, { 0 }, { } }; |
1289 | void *loc_cpu_entry; | ||
1223 | 1290 | ||
1224 | newinfo = vmalloc(sizeof(struct arpt_table_info) | 1291 | newinfo = alloc_table_info(repl->size); |
1225 | + SMP_ALIGN(repl->size) * | ||
1226 | (highest_possible_processor_id()+1)); | ||
1227 | if (!newinfo) { | 1292 | if (!newinfo) { |
1228 | ret = -ENOMEM; | 1293 | ret = -ENOMEM; |
1229 | return ret; | 1294 | return ret; |
1230 | } | 1295 | } |
1231 | memcpy(newinfo->entries, repl->entries, repl->size); | 1296 | |
1297 | /* choose the copy on our node/cpu */ | ||
1298 | loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; | ||
1299 | memcpy(loc_cpu_entry, repl->entries, repl->size); | ||
1232 | 1300 | ||
1233 | ret = translate_table(table->name, table->valid_hooks, | 1301 | ret = translate_table(table->name, table->valid_hooks, |
1234 | newinfo, repl->size, | 1302 | newinfo, loc_cpu_entry, repl->size, |
1235 | repl->num_entries, | 1303 | repl->num_entries, |
1236 | repl->hook_entry, | 1304 | repl->hook_entry, |
1237 | repl->underflow); | 1305 | repl->underflow); |
1238 | duprintf("arpt_register_table: translate table gives %d\n", ret); | 1306 | duprintf("arpt_register_table: translate table gives %d\n", ret); |
1239 | if (ret != 0) { | 1307 | if (ret != 0) { |
1240 | vfree(newinfo); | 1308 | free_table_info(newinfo); |
1241 | return ret; | 1309 | return ret; |
1242 | } | 1310 | } |
1243 | 1311 | ||
1244 | ret = down_interruptible(&arpt_mutex); | 1312 | ret = down_interruptible(&arpt_mutex); |
1245 | if (ret != 0) { | 1313 | if (ret != 0) { |
1246 | vfree(newinfo); | 1314 | free_table_info(newinfo); |
1247 | return ret; | 1315 | return ret; |
1248 | } | 1316 | } |
1249 | 1317 | ||
@@ -1272,20 +1340,23 @@ int arpt_register_table(struct arpt_table *table, | |||
1272 | return ret; | 1340 | return ret; |
1273 | 1341 | ||
1274 | free_unlock: | 1342 | free_unlock: |
1275 | vfree(newinfo); | 1343 | free_table_info(newinfo); |
1276 | goto unlock; | 1344 | goto unlock; |
1277 | } | 1345 | } |
1278 | 1346 | ||
1279 | void arpt_unregister_table(struct arpt_table *table) | 1347 | void arpt_unregister_table(struct arpt_table *table) |
1280 | { | 1348 | { |
1349 | void *loc_cpu_entry; | ||
1350 | |||
1281 | down(&arpt_mutex); | 1351 | down(&arpt_mutex); |
1282 | LIST_DELETE(&arpt_tables, table); | 1352 | LIST_DELETE(&arpt_tables, table); |
1283 | up(&arpt_mutex); | 1353 | up(&arpt_mutex); |
1284 | 1354 | ||
1285 | /* Decrease module usage counts and free resources */ | 1355 | /* Decrease module usage counts and free resources */ |
1286 | ARPT_ENTRY_ITERATE(table->private->entries, table->private->size, | 1356 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; |
1357 | ARPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size, | ||
1287 | cleanup_entry, NULL); | 1358 | cleanup_entry, NULL); |
1288 | vfree(table->private); | 1359 | free_table_info(table->private); |
1289 | } | 1360 | } |
1290 | 1361 | ||
1291 | /* The built-in targets: standard (NULL) and error. */ | 1362 | /* The built-in targets: standard (NULL) and error. */ |
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c index e52847fa10f5..0366eedb4d70 100644 --- a/net/ipv4/netfilter/ip_conntrack_amanda.c +++ b/net/ipv4/netfilter/ip_conntrack_amanda.c | |||
@@ -18,11 +18,13 @@ | |||
18 | * | 18 | * |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/in.h> | ||
21 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
22 | #include <linux/module.h> | 23 | #include <linux/module.h> |
23 | #include <linux/netfilter.h> | 24 | #include <linux/netfilter.h> |
24 | #include <linux/ip.h> | 25 | #include <linux/ip.h> |
25 | #include <linux/moduleparam.h> | 26 | #include <linux/moduleparam.h> |
27 | #include <linux/udp.h> | ||
26 | #include <net/checksum.h> | 28 | #include <net/checksum.h> |
27 | #include <net/udp.h> | 29 | #include <net/udp.h> |
28 | 30 | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_gre.c b/net/ipv4/netfilter/ip_conntrack_proto_gre.c index 744abb9d377a..57956dee60c8 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_gre.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_gre.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/ip.h> | 31 | #include <linux/ip.h> |
32 | #include <linux/in.h> | 32 | #include <linux/in.h> |
33 | #include <linux/list.h> | 33 | #include <linux/list.h> |
34 | #include <linux/seq_file.h> | ||
34 | 35 | ||
35 | static DEFINE_RWLOCK(ip_ct_gre_lock); | 36 | static DEFINE_RWLOCK(ip_ct_gre_lock); |
36 | #define ASSERT_READ_LOCK(x) | 37 | #define ASSERT_READ_LOCK(x) |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c index f2dcac7c7660..46becbe4fe58 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/timer.h> | 11 | #include <linux/timer.h> |
12 | #include <linux/netfilter.h> | 12 | #include <linux/netfilter.h> |
13 | #include <linux/in.h> | 13 | #include <linux/in.h> |
14 | #include <linux/ip.h> | ||
14 | #include <linux/udp.h> | 15 | #include <linux/udp.h> |
15 | #include <linux/seq_file.h> | 16 | #include <linux/seq_file.h> |
16 | #include <net/checksum.h> | 17 | #include <net/checksum.h> |
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index dd476b191f4b..a88bcc551244 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #endif | 27 | #endif |
28 | #include <net/checksum.h> | 28 | #include <net/checksum.h> |
29 | #include <net/ip.h> | 29 | #include <net/ip.h> |
30 | #include <net/route.h> | ||
30 | 31 | ||
31 | #define ASSERT_READ_LOCK(x) | 32 | #define ASSERT_READ_LOCK(x) |
32 | #define ASSERT_WRITE_LOCK(x) | 33 | #define ASSERT_WRITE_LOCK(x) |
diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c index 8acb7ed40b47..4f95d477805c 100644 --- a/net/ipv4/netfilter/ip_nat_snmp_basic.c +++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c | |||
@@ -44,6 +44,7 @@ | |||
44 | * | 44 | * |
45 | */ | 45 | */ |
46 | #include <linux/config.h> | 46 | #include <linux/config.h> |
47 | #include <linux/in.h> | ||
47 | #include <linux/module.h> | 48 | #include <linux/module.h> |
48 | #include <linux/types.h> | 49 | #include <linux/types.h> |
49 | #include <linux/kernel.h> | 50 | #include <linux/kernel.h> |
@@ -53,6 +54,7 @@ | |||
53 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> | 54 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> |
54 | #include <linux/netfilter_ipv4/ip_nat_helper.h> | 55 | #include <linux/netfilter_ipv4/ip_nat_helper.h> |
55 | #include <linux/ip.h> | 56 | #include <linux/ip.h> |
57 | #include <linux/udp.h> | ||
56 | #include <net/checksum.h> | 58 | #include <net/checksum.h> |
57 | #include <net/udp.h> | 59 | #include <net/udp.h> |
58 | #include <asm/uaccess.h> | 60 | #include <asm/uaccess.h> |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 45886c8475e8..2a26d167e149 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -83,11 +83,6 @@ static DECLARE_MUTEX(ipt_mutex); | |||
83 | context stops packets coming through and allows user context to read | 83 | context stops packets coming through and allows user context to read |
84 | the counters or update the rules. | 84 | the counters or update the rules. |
85 | 85 | ||
86 | To be cache friendly on SMP, we arrange them like so: | ||
87 | [ n-entries ] | ||
88 | ... cache-align padding ... | ||
89 | [ n-entries ] | ||
90 | |||
91 | Hence the start of any table is given by get_table() below. */ | 86 | Hence the start of any table is given by get_table() below. */ |
92 | 87 | ||
93 | /* The table itself */ | 88 | /* The table itself */ |
@@ -105,20 +100,15 @@ struct ipt_table_info | |||
105 | unsigned int underflow[NF_IP_NUMHOOKS]; | 100 | unsigned int underflow[NF_IP_NUMHOOKS]; |
106 | 101 | ||
107 | /* ipt_entry tables: one per CPU */ | 102 | /* ipt_entry tables: one per CPU */ |
108 | char entries[0] ____cacheline_aligned; | 103 | void *entries[NR_CPUS]; |
109 | }; | 104 | }; |
110 | 105 | ||
111 | static LIST_HEAD(ipt_target); | 106 | static LIST_HEAD(ipt_target); |
112 | static LIST_HEAD(ipt_match); | 107 | static LIST_HEAD(ipt_match); |
113 | static LIST_HEAD(ipt_tables); | 108 | static LIST_HEAD(ipt_tables); |
109 | #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) | ||
114 | #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) | 110 | #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) |
115 | 111 | ||
116 | #ifdef CONFIG_SMP | ||
117 | #define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p)) | ||
118 | #else | ||
119 | #define TABLE_OFFSET(t,p) 0 | ||
120 | #endif | ||
121 | |||
122 | #if 0 | 112 | #if 0 |
123 | #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) | 113 | #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) |
124 | #define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; }) | 114 | #define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; }) |
@@ -290,8 +280,7 @@ ipt_do_table(struct sk_buff **pskb, | |||
290 | 280 | ||
291 | read_lock_bh(&table->lock); | 281 | read_lock_bh(&table->lock); |
292 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); | 282 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); |
293 | table_base = (void *)table->private->entries | 283 | table_base = (void *)table->private->entries[smp_processor_id()]; |
294 | + TABLE_OFFSET(table->private, smp_processor_id()); | ||
295 | e = get_entry(table_base, table->private->hook_entry[hook]); | 284 | e = get_entry(table_base, table->private->hook_entry[hook]); |
296 | 285 | ||
297 | #ifdef CONFIG_NETFILTER_DEBUG | 286 | #ifdef CONFIG_NETFILTER_DEBUG |
@@ -563,7 +552,8 @@ unconditional(const struct ipt_ip *ip) | |||
563 | /* Figures out from what hook each rule can be called: returns 0 if | 552 | /* Figures out from what hook each rule can be called: returns 0 if |
564 | there are loops. Puts hook bitmask in comefrom. */ | 553 | there are loops. Puts hook bitmask in comefrom. */ |
565 | static int | 554 | static int |
566 | mark_source_chains(struct ipt_table_info *newinfo, unsigned int valid_hooks) | 555 | mark_source_chains(struct ipt_table_info *newinfo, |
556 | unsigned int valid_hooks, void *entry0) | ||
567 | { | 557 | { |
568 | unsigned int hook; | 558 | unsigned int hook; |
569 | 559 | ||
@@ -572,7 +562,7 @@ mark_source_chains(struct ipt_table_info *newinfo, unsigned int valid_hooks) | |||
572 | for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) { | 562 | for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) { |
573 | unsigned int pos = newinfo->hook_entry[hook]; | 563 | unsigned int pos = newinfo->hook_entry[hook]; |
574 | struct ipt_entry *e | 564 | struct ipt_entry *e |
575 | = (struct ipt_entry *)(newinfo->entries + pos); | 565 | = (struct ipt_entry *)(entry0 + pos); |
576 | 566 | ||
577 | if (!(valid_hooks & (1 << hook))) | 567 | if (!(valid_hooks & (1 << hook))) |
578 | continue; | 568 | continue; |
@@ -622,13 +612,13 @@ mark_source_chains(struct ipt_table_info *newinfo, unsigned int valid_hooks) | |||
622 | goto next; | 612 | goto next; |
623 | 613 | ||
624 | e = (struct ipt_entry *) | 614 | e = (struct ipt_entry *) |
625 | (newinfo->entries + pos); | 615 | (entry0 + pos); |
626 | } while (oldpos == pos + e->next_offset); | 616 | } while (oldpos == pos + e->next_offset); |
627 | 617 | ||
628 | /* Move along one */ | 618 | /* Move along one */ |
629 | size = e->next_offset; | 619 | size = e->next_offset; |
630 | e = (struct ipt_entry *) | 620 | e = (struct ipt_entry *) |
631 | (newinfo->entries + pos + size); | 621 | (entry0 + pos + size); |
632 | e->counters.pcnt = pos; | 622 | e->counters.pcnt = pos; |
633 | pos += size; | 623 | pos += size; |
634 | } else { | 624 | } else { |
@@ -645,7 +635,7 @@ mark_source_chains(struct ipt_table_info *newinfo, unsigned int valid_hooks) | |||
645 | newpos = pos + e->next_offset; | 635 | newpos = pos + e->next_offset; |
646 | } | 636 | } |
647 | e = (struct ipt_entry *) | 637 | e = (struct ipt_entry *) |
648 | (newinfo->entries + newpos); | 638 | (entry0 + newpos); |
649 | e->counters.pcnt = pos; | 639 | e->counters.pcnt = pos; |
650 | pos = newpos; | 640 | pos = newpos; |
651 | } | 641 | } |
@@ -855,6 +845,7 @@ static int | |||
855 | translate_table(const char *name, | 845 | translate_table(const char *name, |
856 | unsigned int valid_hooks, | 846 | unsigned int valid_hooks, |
857 | struct ipt_table_info *newinfo, | 847 | struct ipt_table_info *newinfo, |
848 | void *entry0, | ||
858 | unsigned int size, | 849 | unsigned int size, |
859 | unsigned int number, | 850 | unsigned int number, |
860 | const unsigned int *hook_entries, | 851 | const unsigned int *hook_entries, |
@@ -875,11 +866,11 @@ translate_table(const char *name, | |||
875 | duprintf("translate_table: size %u\n", newinfo->size); | 866 | duprintf("translate_table: size %u\n", newinfo->size); |
876 | i = 0; | 867 | i = 0; |
877 | /* Walk through entries, checking offsets. */ | 868 | /* Walk through entries, checking offsets. */ |
878 | ret = IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, | 869 | ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, |
879 | check_entry_size_and_hooks, | 870 | check_entry_size_and_hooks, |
880 | newinfo, | 871 | newinfo, |
881 | newinfo->entries, | 872 | entry0, |
882 | newinfo->entries + size, | 873 | entry0 + size, |
883 | hook_entries, underflows, &i); | 874 | hook_entries, underflows, &i); |
884 | if (ret != 0) | 875 | if (ret != 0) |
885 | return ret; | 876 | return ret; |
@@ -907,27 +898,24 @@ translate_table(const char *name, | |||
907 | } | 898 | } |
908 | } | 899 | } |
909 | 900 | ||
910 | if (!mark_source_chains(newinfo, valid_hooks)) | 901 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) |
911 | return -ELOOP; | 902 | return -ELOOP; |
912 | 903 | ||
913 | /* Finally, each sanity check must pass */ | 904 | /* Finally, each sanity check must pass */ |
914 | i = 0; | 905 | i = 0; |
915 | ret = IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, | 906 | ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, |
916 | check_entry, name, size, &i); | 907 | check_entry, name, size, &i); |
917 | 908 | ||
918 | if (ret != 0) { | 909 | if (ret != 0) { |
919 | IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, | 910 | IPT_ENTRY_ITERATE(entry0, newinfo->size, |
920 | cleanup_entry, &i); | 911 | cleanup_entry, &i); |
921 | return ret; | 912 | return ret; |
922 | } | 913 | } |
923 | 914 | ||
924 | /* And one copy for every other CPU */ | 915 | /* And one copy for every other CPU */ |
925 | for_each_cpu(i) { | 916 | for_each_cpu(i) { |
926 | if (i == 0) | 917 | if (newinfo->entries[i] && newinfo->entries[i] != entry0) |
927 | continue; | 918 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
928 | memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i, | ||
929 | newinfo->entries, | ||
930 | SMP_ALIGN(newinfo->size)); | ||
931 | } | 919 | } |
932 | 920 | ||
933 | return ret; | 921 | return ret; |
@@ -943,15 +931,12 @@ replace_table(struct ipt_table *table, | |||
943 | 931 | ||
944 | #ifdef CONFIG_NETFILTER_DEBUG | 932 | #ifdef CONFIG_NETFILTER_DEBUG |
945 | { | 933 | { |
946 | struct ipt_entry *table_base; | 934 | int cpu; |
947 | unsigned int i; | ||
948 | 935 | ||
949 | for_each_cpu(i) { | 936 | for_each_cpu(cpu) { |
950 | table_base = | 937 | struct ipt_entry *table_base = newinfo->entries[cpu]; |
951 | (void *)newinfo->entries | 938 | if (table_base) |
952 | + TABLE_OFFSET(newinfo, i); | 939 | table_base->comefrom = 0xdead57ac; |
953 | |||
954 | table_base->comefrom = 0xdead57ac; | ||
955 | } | 940 | } |
956 | } | 941 | } |
957 | #endif | 942 | #endif |
@@ -986,16 +971,44 @@ add_entry_to_counter(const struct ipt_entry *e, | |||
986 | return 0; | 971 | return 0; |
987 | } | 972 | } |
988 | 973 | ||
974 | static inline int | ||
975 | set_entry_to_counter(const struct ipt_entry *e, | ||
976 | struct ipt_counters total[], | ||
977 | unsigned int *i) | ||
978 | { | ||
979 | SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); | ||
980 | |||
981 | (*i)++; | ||
982 | return 0; | ||
983 | } | ||
984 | |||
989 | static void | 985 | static void |
990 | get_counters(const struct ipt_table_info *t, | 986 | get_counters(const struct ipt_table_info *t, |
991 | struct ipt_counters counters[]) | 987 | struct ipt_counters counters[]) |
992 | { | 988 | { |
993 | unsigned int cpu; | 989 | unsigned int cpu; |
994 | unsigned int i; | 990 | unsigned int i; |
991 | unsigned int curcpu; | ||
992 | |||
993 | /* Instead of clearing (by a previous call to memset()) | ||
994 | * the counters and using adds, we set the counters | ||
995 | * with data used by 'current' CPU | ||
996 | * We dont care about preemption here. | ||
997 | */ | ||
998 | curcpu = raw_smp_processor_id(); | ||
999 | |||
1000 | i = 0; | ||
1001 | IPT_ENTRY_ITERATE(t->entries[curcpu], | ||
1002 | t->size, | ||
1003 | set_entry_to_counter, | ||
1004 | counters, | ||
1005 | &i); | ||
995 | 1006 | ||
996 | for_each_cpu(cpu) { | 1007 | for_each_cpu(cpu) { |
1008 | if (cpu == curcpu) | ||
1009 | continue; | ||
997 | i = 0; | 1010 | i = 0; |
998 | IPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu), | 1011 | IPT_ENTRY_ITERATE(t->entries[cpu], |
999 | t->size, | 1012 | t->size, |
1000 | add_entry_to_counter, | 1013 | add_entry_to_counter, |
1001 | counters, | 1014 | counters, |
@@ -1012,24 +1025,29 @@ copy_entries_to_user(unsigned int total_size, | |||
1012 | struct ipt_entry *e; | 1025 | struct ipt_entry *e; |
1013 | struct ipt_counters *counters; | 1026 | struct ipt_counters *counters; |
1014 | int ret = 0; | 1027 | int ret = 0; |
1028 | void *loc_cpu_entry; | ||
1015 | 1029 | ||
1016 | /* We need atomic snapshot of counters: rest doesn't change | 1030 | /* We need atomic snapshot of counters: rest doesn't change |
1017 | (other than comefrom, which userspace doesn't care | 1031 | (other than comefrom, which userspace doesn't care |
1018 | about). */ | 1032 | about). */ |
1019 | countersize = sizeof(struct ipt_counters) * table->private->number; | 1033 | countersize = sizeof(struct ipt_counters) * table->private->number; |
1020 | counters = vmalloc(countersize); | 1034 | counters = vmalloc_node(countersize, numa_node_id()); |
1021 | 1035 | ||
1022 | if (counters == NULL) | 1036 | if (counters == NULL) |
1023 | return -ENOMEM; | 1037 | return -ENOMEM; |
1024 | 1038 | ||
1025 | /* First, sum counters... */ | 1039 | /* First, sum counters... */ |
1026 | memset(counters, 0, countersize); | ||
1027 | write_lock_bh(&table->lock); | 1040 | write_lock_bh(&table->lock); |
1028 | get_counters(table->private, counters); | 1041 | get_counters(table->private, counters); |
1029 | write_unlock_bh(&table->lock); | 1042 | write_unlock_bh(&table->lock); |
1030 | 1043 | ||
1031 | /* ... then copy entire thing from CPU 0... */ | 1044 | /* choose the copy that is on our node/cpu, ... |
1032 | if (copy_to_user(userptr, table->private->entries, total_size) != 0) { | 1045 | * This choice is lazy (because current thread is |
1046 | * allowed to migrate to another cpu) | ||
1047 | */ | ||
1048 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; | ||
1049 | /* ... then copy entire thing ... */ | ||
1050 | if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { | ||
1033 | ret = -EFAULT; | 1051 | ret = -EFAULT; |
1034 | goto free_counters; | 1052 | goto free_counters; |
1035 | } | 1053 | } |
@@ -1041,7 +1059,7 @@ copy_entries_to_user(unsigned int total_size, | |||
1041 | struct ipt_entry_match *m; | 1059 | struct ipt_entry_match *m; |
1042 | struct ipt_entry_target *t; | 1060 | struct ipt_entry_target *t; |
1043 | 1061 | ||
1044 | e = (struct ipt_entry *)(table->private->entries + off); | 1062 | e = (struct ipt_entry *)(loc_cpu_entry + off); |
1045 | if (copy_to_user(userptr + off | 1063 | if (copy_to_user(userptr + off |
1046 | + offsetof(struct ipt_entry, counters), | 1064 | + offsetof(struct ipt_entry, counters), |
1047 | &counters[num], | 1065 | &counters[num], |
@@ -1110,6 +1128,45 @@ get_entries(const struct ipt_get_entries *entries, | |||
1110 | return ret; | 1128 | return ret; |
1111 | } | 1129 | } |
1112 | 1130 | ||
1131 | static void free_table_info(struct ipt_table_info *info) | ||
1132 | { | ||
1133 | int cpu; | ||
1134 | for_each_cpu(cpu) { | ||
1135 | if (info->size <= PAGE_SIZE) | ||
1136 | kfree(info->entries[cpu]); | ||
1137 | else | ||
1138 | vfree(info->entries[cpu]); | ||
1139 | } | ||
1140 | kfree(info); | ||
1141 | } | ||
1142 | |||
1143 | static struct ipt_table_info *alloc_table_info(unsigned int size) | ||
1144 | { | ||
1145 | struct ipt_table_info *newinfo; | ||
1146 | int cpu; | ||
1147 | |||
1148 | newinfo = kzalloc(sizeof(struct ipt_table_info), GFP_KERNEL); | ||
1149 | if (!newinfo) | ||
1150 | return NULL; | ||
1151 | |||
1152 | newinfo->size = size; | ||
1153 | |||
1154 | for_each_cpu(cpu) { | ||
1155 | if (size <= PAGE_SIZE) | ||
1156 | newinfo->entries[cpu] = kmalloc_node(size, | ||
1157 | GFP_KERNEL, | ||
1158 | cpu_to_node(cpu)); | ||
1159 | else | ||
1160 | newinfo->entries[cpu] = vmalloc_node(size, cpu_to_node(cpu)); | ||
1161 | if (newinfo->entries[cpu] == 0) { | ||
1162 | free_table_info(newinfo); | ||
1163 | return NULL; | ||
1164 | } | ||
1165 | } | ||
1166 | |||
1167 | return newinfo; | ||
1168 | } | ||
1169 | |||
1113 | static int | 1170 | static int |
1114 | do_replace(void __user *user, unsigned int len) | 1171 | do_replace(void __user *user, unsigned int len) |
1115 | { | 1172 | { |
@@ -1118,6 +1175,7 @@ do_replace(void __user *user, unsigned int len) | |||
1118 | struct ipt_table *t; | 1175 | struct ipt_table *t; |
1119 | struct ipt_table_info *newinfo, *oldinfo; | 1176 | struct ipt_table_info *newinfo, *oldinfo; |
1120 | struct ipt_counters *counters; | 1177 | struct ipt_counters *counters; |
1178 | void *loc_cpu_entry, *loc_cpu_old_entry; | ||
1121 | 1179 | ||
1122 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1180 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
1123 | return -EFAULT; | 1181 | return -EFAULT; |
@@ -1130,13 +1188,13 @@ do_replace(void __user *user, unsigned int len) | |||
1130 | if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) | 1188 | if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) |
1131 | return -ENOMEM; | 1189 | return -ENOMEM; |
1132 | 1190 | ||
1133 | newinfo = vmalloc(sizeof(struct ipt_table_info) | 1191 | newinfo = alloc_table_info(tmp.size); |
1134 | + SMP_ALIGN(tmp.size) * | ||
1135 | (highest_possible_processor_id()+1)); | ||
1136 | if (!newinfo) | 1192 | if (!newinfo) |
1137 | return -ENOMEM; | 1193 | return -ENOMEM; |
1138 | 1194 | ||
1139 | if (copy_from_user(newinfo->entries, user + sizeof(tmp), | 1195 | /* choose the copy that is our node/cpu */ |
1196 | loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; | ||
1197 | if (copy_from_user(loc_cpu_entry, user + sizeof(tmp), | ||
1140 | tmp.size) != 0) { | 1198 | tmp.size) != 0) { |
1141 | ret = -EFAULT; | 1199 | ret = -EFAULT; |
1142 | goto free_newinfo; | 1200 | goto free_newinfo; |
@@ -1147,10 +1205,9 @@ do_replace(void __user *user, unsigned int len) | |||
1147 | ret = -ENOMEM; | 1205 | ret = -ENOMEM; |
1148 | goto free_newinfo; | 1206 | goto free_newinfo; |
1149 | } | 1207 | } |
1150 | memset(counters, 0, tmp.num_counters * sizeof(struct ipt_counters)); | ||
1151 | 1208 | ||
1152 | ret = translate_table(tmp.name, tmp.valid_hooks, | 1209 | ret = translate_table(tmp.name, tmp.valid_hooks, |
1153 | newinfo, tmp.size, tmp.num_entries, | 1210 | newinfo, loc_cpu_entry, tmp.size, tmp.num_entries, |
1154 | tmp.hook_entry, tmp.underflow); | 1211 | tmp.hook_entry, tmp.underflow); |
1155 | if (ret != 0) | 1212 | if (ret != 0) |
1156 | goto free_newinfo_counters; | 1213 | goto free_newinfo_counters; |
@@ -1189,8 +1246,9 @@ do_replace(void __user *user, unsigned int len) | |||
1189 | /* Get the old counters. */ | 1246 | /* Get the old counters. */ |
1190 | get_counters(oldinfo, counters); | 1247 | get_counters(oldinfo, counters); |
1191 | /* Decrease module usage counts and free resource */ | 1248 | /* Decrease module usage counts and free resource */ |
1192 | IPT_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL); | 1249 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; |
1193 | vfree(oldinfo); | 1250 | IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); |
1251 | free_table_info(oldinfo); | ||
1194 | if (copy_to_user(tmp.counters, counters, | 1252 | if (copy_to_user(tmp.counters, counters, |
1195 | sizeof(struct ipt_counters) * tmp.num_counters) != 0) | 1253 | sizeof(struct ipt_counters) * tmp.num_counters) != 0) |
1196 | ret = -EFAULT; | 1254 | ret = -EFAULT; |
@@ -1202,11 +1260,11 @@ do_replace(void __user *user, unsigned int len) | |||
1202 | module_put(t->me); | 1260 | module_put(t->me); |
1203 | up(&ipt_mutex); | 1261 | up(&ipt_mutex); |
1204 | free_newinfo_counters_untrans: | 1262 | free_newinfo_counters_untrans: |
1205 | IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry,NULL); | 1263 | IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); |
1206 | free_newinfo_counters: | 1264 | free_newinfo_counters: |
1207 | vfree(counters); | 1265 | vfree(counters); |
1208 | free_newinfo: | 1266 | free_newinfo: |
1209 | vfree(newinfo); | 1267 | free_table_info(newinfo); |
1210 | return ret; | 1268 | return ret; |
1211 | } | 1269 | } |
1212 | 1270 | ||
@@ -1239,6 +1297,7 @@ do_add_counters(void __user *user, unsigned int len) | |||
1239 | struct ipt_counters_info tmp, *paddc; | 1297 | struct ipt_counters_info tmp, *paddc; |
1240 | struct ipt_table *t; | 1298 | struct ipt_table *t; |
1241 | int ret = 0; | 1299 | int ret = 0; |
1300 | void *loc_cpu_entry; | ||
1242 | 1301 | ||
1243 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1302 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
1244 | return -EFAULT; | 1303 | return -EFAULT; |
@@ -1246,7 +1305,7 @@ do_add_counters(void __user *user, unsigned int len) | |||
1246 | if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct ipt_counters)) | 1305 | if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct ipt_counters)) |
1247 | return -EINVAL; | 1306 | return -EINVAL; |
1248 | 1307 | ||
1249 | paddc = vmalloc(len); | 1308 | paddc = vmalloc_node(len, numa_node_id()); |
1250 | if (!paddc) | 1309 | if (!paddc) |
1251 | return -ENOMEM; | 1310 | return -ENOMEM; |
1252 | 1311 | ||
@@ -1268,7 +1327,9 @@ do_add_counters(void __user *user, unsigned int len) | |||
1268 | } | 1327 | } |
1269 | 1328 | ||
1270 | i = 0; | 1329 | i = 0; |
1271 | IPT_ENTRY_ITERATE(t->private->entries, | 1330 | /* Choose the copy that is on our node */ |
1331 | loc_cpu_entry = t->private->entries[raw_smp_processor_id()]; | ||
1332 | IPT_ENTRY_ITERATE(loc_cpu_entry, | ||
1272 | t->private->size, | 1333 | t->private->size, |
1273 | add_counter_to_entry, | 1334 | add_counter_to_entry, |
1274 | paddc->counters, | 1335 | paddc->counters, |
@@ -1460,28 +1521,31 @@ int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl) | |||
1460 | struct ipt_table_info *newinfo; | 1521 | struct ipt_table_info *newinfo; |
1461 | static struct ipt_table_info bootstrap | 1522 | static struct ipt_table_info bootstrap |
1462 | = { 0, 0, 0, { 0 }, { 0 }, { } }; | 1523 | = { 0, 0, 0, { 0 }, { 0 }, { } }; |
1524 | void *loc_cpu_entry; | ||
1463 | 1525 | ||
1464 | newinfo = vmalloc(sizeof(struct ipt_table_info) | 1526 | newinfo = alloc_table_info(repl->size); |
1465 | + SMP_ALIGN(repl->size) * | ||
1466 | (highest_possible_processor_id()+1)); | ||
1467 | if (!newinfo) | 1527 | if (!newinfo) |
1468 | return -ENOMEM; | 1528 | return -ENOMEM; |
1469 | 1529 | ||
1470 | memcpy(newinfo->entries, repl->entries, repl->size); | 1530 | /* choose the copy on our node/cpu |
1531 | * but dont care of preemption | ||
1532 | */ | ||
1533 | loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; | ||
1534 | memcpy(loc_cpu_entry, repl->entries, repl->size); | ||
1471 | 1535 | ||
1472 | ret = translate_table(table->name, table->valid_hooks, | 1536 | ret = translate_table(table->name, table->valid_hooks, |
1473 | newinfo, repl->size, | 1537 | newinfo, loc_cpu_entry, repl->size, |
1474 | repl->num_entries, | 1538 | repl->num_entries, |
1475 | repl->hook_entry, | 1539 | repl->hook_entry, |
1476 | repl->underflow); | 1540 | repl->underflow); |
1477 | if (ret != 0) { | 1541 | if (ret != 0) { |
1478 | vfree(newinfo); | 1542 | free_table_info(newinfo); |
1479 | return ret; | 1543 | return ret; |
1480 | } | 1544 | } |
1481 | 1545 | ||
1482 | ret = down_interruptible(&ipt_mutex); | 1546 | ret = down_interruptible(&ipt_mutex); |
1483 | if (ret != 0) { | 1547 | if (ret != 0) { |
1484 | vfree(newinfo); | 1548 | free_table_info(newinfo); |
1485 | return ret; | 1549 | return ret; |
1486 | } | 1550 | } |
1487 | 1551 | ||
@@ -1510,20 +1574,23 @@ int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl) | |||
1510 | return ret; | 1574 | return ret; |
1511 | 1575 | ||
1512 | free_unlock: | 1576 | free_unlock: |
1513 | vfree(newinfo); | 1577 | free_table_info(newinfo); |
1514 | goto unlock; | 1578 | goto unlock; |
1515 | } | 1579 | } |
1516 | 1580 | ||
1517 | void ipt_unregister_table(struct ipt_table *table) | 1581 | void ipt_unregister_table(struct ipt_table *table) |
1518 | { | 1582 | { |
1583 | void *loc_cpu_entry; | ||
1584 | |||
1519 | down(&ipt_mutex); | 1585 | down(&ipt_mutex); |
1520 | LIST_DELETE(&ipt_tables, table); | 1586 | LIST_DELETE(&ipt_tables, table); |
1521 | up(&ipt_mutex); | 1587 | up(&ipt_mutex); |
1522 | 1588 | ||
1523 | /* Decrease module usage counts and free resources */ | 1589 | /* Decrease module usage counts and free resources */ |
1524 | IPT_ENTRY_ITERATE(table->private->entries, table->private->size, | 1590 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; |
1591 | IPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size, | ||
1525 | cleanup_entry, NULL); | 1592 | cleanup_entry, NULL); |
1526 | vfree(table->private); | 1593 | free_table_info(table->private); |
1527 | } | 1594 | } |
1528 | 1595 | ||
1529 | /* Returns 1 if the port is matched by the range, 0 otherwise */ | 1596 | /* Returns 1 if the port is matched by the range, 0 otherwise */ |
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index 275a174c6fe6..27860510ca6d 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <linux/inetdevice.h> | ||
14 | #include <linux/ip.h> | 15 | #include <linux/ip.h> |
15 | #include <linux/timer.h> | 16 | #include <linux/timer.h> |
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
@@ -18,6 +19,7 @@ | |||
18 | #include <net/protocol.h> | 19 | #include <net/protocol.h> |
19 | #include <net/ip.h> | 20 | #include <net/ip.h> |
20 | #include <net/checksum.h> | 21 | #include <net/checksum.h> |
22 | #include <net/route.h> | ||
21 | #include <linux/netfilter_ipv4.h> | 23 | #include <linux/netfilter_ipv4.h> |
22 | #include <linux/netfilter_ipv4/ip_nat_rule.h> | 24 | #include <linux/netfilter_ipv4/ip_nat_rule.h> |
23 | #include <linux/netfilter_ipv4/ip_tables.h> | 25 | #include <linux/netfilter_ipv4/ip_tables.h> |
diff --git a/net/ipv4/netfilter/ipt_physdev.c b/net/ipv4/netfilter/ipt_physdev.c index 1a53924041fc..03f554857a4d 100644 --- a/net/ipv4/netfilter/ipt_physdev.c +++ b/net/ipv4/netfilter/ipt_physdev.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/netdevice.h> | ||
12 | #include <linux/skbuff.h> | 13 | #include <linux/skbuff.h> |
13 | #include <linux/netfilter_ipv4/ipt_physdev.h> | 14 | #include <linux/netfilter_ipv4/ipt_physdev.h> |
14 | #include <linux/netfilter_ipv4/ip_tables.h> | 15 | #include <linux/netfilter_ipv4/ip_tables.h> |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 0d7dc668db46..39d49dc333a7 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <net/protocol.h> | 38 | #include <net/protocol.h> |
39 | #include <net/tcp.h> | 39 | #include <net/tcp.h> |
40 | #include <net/udp.h> | 40 | #include <net/udp.h> |
41 | #include <linux/inetdevice.h> | ||
41 | #include <linux/proc_fs.h> | 42 | #include <linux/proc_fs.h> |
42 | #include <linux/seq_file.h> | 43 | #include <linux/seq_file.h> |
43 | #include <net/sock.h> | 44 | #include <net/sock.h> |
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index a34e60ea48a1..e20be3331f67 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -173,10 +173,10 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb, | |||
173 | struct request_sock *req, | 173 | struct request_sock *req, |
174 | struct dst_entry *dst) | 174 | struct dst_entry *dst) |
175 | { | 175 | { |
176 | struct tcp_sock *tp = tcp_sk(sk); | 176 | struct inet_connection_sock *icsk = inet_csk(sk); |
177 | struct sock *child; | 177 | struct sock *child; |
178 | 178 | ||
179 | child = tp->af_specific->syn_recv_sock(sk, skb, req, dst); | 179 | child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst); |
180 | if (child) | 180 | if (child) |
181 | inet_csk_reqsk_queue_add(sk, req, child); | 181 | inet_csk_reqsk_queue_add(sk, req, child); |
182 | else | 182 | else |
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 01444a02b48b..16984d4a8a06 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/sysctl.h> | 12 | #include <linux/sysctl.h> |
13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
14 | #include <linux/igmp.h> | 14 | #include <linux/igmp.h> |
15 | #include <linux/inetdevice.h> | ||
15 | #include <net/snmp.h> | 16 | #include <net/snmp.h> |
16 | #include <net/icmp.h> | 17 | #include <net/icmp.h> |
17 | #include <net/ip.h> | 18 | #include <net/ip.h> |
@@ -22,6 +23,7 @@ | |||
22 | extern int sysctl_ip_nonlocal_bind; | 23 | extern int sysctl_ip_nonlocal_bind; |
23 | 24 | ||
24 | #ifdef CONFIG_SYSCTL | 25 | #ifdef CONFIG_SYSCTL |
26 | static int zero; | ||
25 | static int tcp_retr1_max = 255; | 27 | static int tcp_retr1_max = 255; |
26 | static int ip_local_port_range_min[] = { 1, 1 }; | 28 | static int ip_local_port_range_min[] = { 1, 1 }; |
27 | static int ip_local_port_range_max[] = { 65535, 65535 }; | 29 | static int ip_local_port_range_max[] = { 65535, 65535 }; |
@@ -614,6 +616,15 @@ ctl_table ipv4_table[] = { | |||
614 | .strategy = &sysctl_jiffies | 616 | .strategy = &sysctl_jiffies |
615 | }, | 617 | }, |
616 | { | 618 | { |
619 | .ctl_name = NET_IPV4_IPFRAG_MAX_DIST, | ||
620 | .procname = "ipfrag_max_dist", | ||
621 | .data = &sysctl_ipfrag_max_dist, | ||
622 | .maxlen = sizeof(int), | ||
623 | .mode = 0644, | ||
624 | .proc_handler = &proc_dointvec_minmax, | ||
625 | .extra1 = &zero | ||
626 | }, | ||
627 | { | ||
617 | .ctl_name = NET_TCP_NO_METRICS_SAVE, | 628 | .ctl_name = NET_TCP_NO_METRICS_SAVE, |
618 | .procname = "tcp_no_metrics_save", | 629 | .procname = "tcp_no_metrics_save", |
619 | .data = &sysctl_tcp_nometrics_save, | 630 | .data = &sysctl_tcp_nometrics_save, |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index ef98b14ac56d..00aa80e93243 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1696,8 +1696,8 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, | |||
1696 | int err = 0; | 1696 | int err = 0; |
1697 | 1697 | ||
1698 | if (level != SOL_TCP) | 1698 | if (level != SOL_TCP) |
1699 | return tp->af_specific->setsockopt(sk, level, optname, | 1699 | return icsk->icsk_af_ops->setsockopt(sk, level, optname, |
1700 | optval, optlen); | 1700 | optval, optlen); |
1701 | 1701 | ||
1702 | /* This is a string value all the others are int's */ | 1702 | /* This is a string value all the others are int's */ |
1703 | if (optname == TCP_CONGESTION) { | 1703 | if (optname == TCP_CONGESTION) { |
@@ -1914,7 +1914,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) | |||
1914 | info->tcpi_last_data_recv = jiffies_to_msecs(now - icsk->icsk_ack.lrcvtime); | 1914 | info->tcpi_last_data_recv = jiffies_to_msecs(now - icsk->icsk_ack.lrcvtime); |
1915 | info->tcpi_last_ack_recv = jiffies_to_msecs(now - tp->rcv_tstamp); | 1915 | info->tcpi_last_ack_recv = jiffies_to_msecs(now - tp->rcv_tstamp); |
1916 | 1916 | ||
1917 | info->tcpi_pmtu = tp->pmtu_cookie; | 1917 | info->tcpi_pmtu = icsk->icsk_pmtu_cookie; |
1918 | info->tcpi_rcv_ssthresh = tp->rcv_ssthresh; | 1918 | info->tcpi_rcv_ssthresh = tp->rcv_ssthresh; |
1919 | info->tcpi_rtt = jiffies_to_usecs(tp->srtt)>>3; | 1919 | info->tcpi_rtt = jiffies_to_usecs(tp->srtt)>>3; |
1920 | info->tcpi_rttvar = jiffies_to_usecs(tp->mdev)>>2; | 1920 | info->tcpi_rttvar = jiffies_to_usecs(tp->mdev)>>2; |
@@ -1939,8 +1939,8 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, | |||
1939 | int val, len; | 1939 | int val, len; |
1940 | 1940 | ||
1941 | if (level != SOL_TCP) | 1941 | if (level != SOL_TCP) |
1942 | return tp->af_specific->getsockopt(sk, level, optname, | 1942 | return icsk->icsk_af_ops->getsockopt(sk, level, optname, |
1943 | optval, optlen); | 1943 | optval, optlen); |
1944 | 1944 | ||
1945 | if (get_user(len, optlen)) | 1945 | if (get_user(len, optlen)) |
1946 | return -EFAULT; | 1946 | return -EFAULT; |
diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c index 1d0cd86621b1..035f2092d73a 100644 --- a/net/ipv4/tcp_bic.c +++ b/net/ipv4/tcp_bic.c | |||
@@ -30,8 +30,6 @@ static int fast_convergence = 1; | |||
30 | static int max_increment = 16; | 30 | static int max_increment = 16; |
31 | static int low_window = 14; | 31 | static int low_window = 14; |
32 | static int beta = 819; /* = 819/1024 (BICTCP_BETA_SCALE) */ | 32 | static int beta = 819; /* = 819/1024 (BICTCP_BETA_SCALE) */ |
33 | static int low_utilization_threshold = 153; | ||
34 | static int low_utilization_period = 2; | ||
35 | static int initial_ssthresh = 100; | 33 | static int initial_ssthresh = 100; |
36 | static int smooth_part = 20; | 34 | static int smooth_part = 20; |
37 | 35 | ||
@@ -43,10 +41,6 @@ module_param(low_window, int, 0644); | |||
43 | MODULE_PARM_DESC(low_window, "lower bound on congestion window (for TCP friendliness)"); | 41 | MODULE_PARM_DESC(low_window, "lower bound on congestion window (for TCP friendliness)"); |
44 | module_param(beta, int, 0644); | 42 | module_param(beta, int, 0644); |
45 | MODULE_PARM_DESC(beta, "beta for multiplicative increase"); | 43 | MODULE_PARM_DESC(beta, "beta for multiplicative increase"); |
46 | module_param(low_utilization_threshold, int, 0644); | ||
47 | MODULE_PARM_DESC(low_utilization_threshold, "percent (scaled by 1024) for low utilization mode"); | ||
48 | module_param(low_utilization_period, int, 0644); | ||
49 | MODULE_PARM_DESC(low_utilization_period, "if average delay exceeds then goto to low utilization mode (seconds)"); | ||
50 | module_param(initial_ssthresh, int, 0644); | 44 | module_param(initial_ssthresh, int, 0644); |
51 | MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold"); | 45 | MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold"); |
52 | module_param(smooth_part, int, 0644); | 46 | module_param(smooth_part, int, 0644); |
@@ -60,11 +54,6 @@ struct bictcp { | |||
60 | u32 loss_cwnd; /* congestion window at last loss */ | 54 | u32 loss_cwnd; /* congestion window at last loss */ |
61 | u32 last_cwnd; /* the last snd_cwnd */ | 55 | u32 last_cwnd; /* the last snd_cwnd */ |
62 | u32 last_time; /* time when updated last_cwnd */ | 56 | u32 last_time; /* time when updated last_cwnd */ |
63 | u32 delay_min; /* min delay */ | ||
64 | u32 delay_max; /* max delay */ | ||
65 | u32 last_delay; | ||
66 | u8 low_utilization;/* 0: high; 1: low */ | ||
67 | u32 low_utilization_start; /* starting time of low utilization detection*/ | ||
68 | u32 epoch_start; /* beginning of an epoch */ | 57 | u32 epoch_start; /* beginning of an epoch */ |
69 | #define ACK_RATIO_SHIFT 4 | 58 | #define ACK_RATIO_SHIFT 4 |
70 | u32 delayed_ack; /* estimate the ratio of Packets/ACKs << 4 */ | 59 | u32 delayed_ack; /* estimate the ratio of Packets/ACKs << 4 */ |
@@ -77,11 +66,6 @@ static inline void bictcp_reset(struct bictcp *ca) | |||
77 | ca->loss_cwnd = 0; | 66 | ca->loss_cwnd = 0; |
78 | ca->last_cwnd = 0; | 67 | ca->last_cwnd = 0; |
79 | ca->last_time = 0; | 68 | ca->last_time = 0; |
80 | ca->delay_min = 0; | ||
81 | ca->delay_max = 0; | ||
82 | ca->last_delay = 0; | ||
83 | ca->low_utilization = 0; | ||
84 | ca->low_utilization_start = 0; | ||
85 | ca->epoch_start = 0; | 69 | ca->epoch_start = 0; |
86 | ca->delayed_ack = 2 << ACK_RATIO_SHIFT; | 70 | ca->delayed_ack = 2 << ACK_RATIO_SHIFT; |
87 | } | 71 | } |
@@ -143,8 +127,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd) | |||
143 | } | 127 | } |
144 | 128 | ||
145 | /* if in slow start or link utilization is very low */ | 129 | /* if in slow start or link utilization is very low */ |
146 | if ( ca->loss_cwnd == 0 || | 130 | if (ca->loss_cwnd == 0) { |
147 | (cwnd > ca->loss_cwnd && ca->low_utilization)) { | ||
148 | if (ca->cnt > 20) /* increase cwnd 5% per RTT */ | 131 | if (ca->cnt > 20) /* increase cwnd 5% per RTT */ |
149 | ca->cnt = 20; | 132 | ca->cnt = 20; |
150 | } | 133 | } |
@@ -154,69 +137,12 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd) | |||
154 | ca->cnt = 1; | 137 | ca->cnt = 1; |
155 | } | 138 | } |
156 | 139 | ||
157 | |||
158 | /* Detect low utilization in congestion avoidance */ | ||
159 | static inline void bictcp_low_utilization(struct sock *sk, int flag) | ||
160 | { | ||
161 | const struct tcp_sock *tp = tcp_sk(sk); | ||
162 | struct bictcp *ca = inet_csk_ca(sk); | ||
163 | u32 dist, delay; | ||
164 | |||
165 | /* No time stamp */ | ||
166 | if (!(tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) || | ||
167 | /* Discard delay samples right after fast recovery */ | ||
168 | tcp_time_stamp < ca->epoch_start + HZ || | ||
169 | /* this delay samples may not be accurate */ | ||
170 | flag == 0) { | ||
171 | ca->last_delay = 0; | ||
172 | goto notlow; | ||
173 | } | ||
174 | |||
175 | delay = ca->last_delay<<3; /* use the same scale as tp->srtt*/ | ||
176 | ca->last_delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr; | ||
177 | if (delay == 0) /* no previous delay sample */ | ||
178 | goto notlow; | ||
179 | |||
180 | /* first time call or link delay decreases */ | ||
181 | if (ca->delay_min == 0 || ca->delay_min > delay) { | ||
182 | ca->delay_min = ca->delay_max = delay; | ||
183 | goto notlow; | ||
184 | } | ||
185 | |||
186 | if (ca->delay_max < delay) | ||
187 | ca->delay_max = delay; | ||
188 | |||
189 | /* utilization is low, if avg delay < dist*threshold | ||
190 | for checking_period time */ | ||
191 | dist = ca->delay_max - ca->delay_min; | ||
192 | if (dist <= ca->delay_min>>6 || | ||
193 | tp->srtt - ca->delay_min >= (dist*low_utilization_threshold)>>10) | ||
194 | goto notlow; | ||
195 | |||
196 | if (ca->low_utilization_start == 0) { | ||
197 | ca->low_utilization = 0; | ||
198 | ca->low_utilization_start = tcp_time_stamp; | ||
199 | } else if ((s32)(tcp_time_stamp - ca->low_utilization_start) | ||
200 | > low_utilization_period*HZ) { | ||
201 | ca->low_utilization = 1; | ||
202 | } | ||
203 | |||
204 | return; | ||
205 | |||
206 | notlow: | ||
207 | ca->low_utilization = 0; | ||
208 | ca->low_utilization_start = 0; | ||
209 | |||
210 | } | ||
211 | |||
212 | static void bictcp_cong_avoid(struct sock *sk, u32 ack, | 140 | static void bictcp_cong_avoid(struct sock *sk, u32 ack, |
213 | u32 seq_rtt, u32 in_flight, int data_acked) | 141 | u32 seq_rtt, u32 in_flight, int data_acked) |
214 | { | 142 | { |
215 | struct tcp_sock *tp = tcp_sk(sk); | 143 | struct tcp_sock *tp = tcp_sk(sk); |
216 | struct bictcp *ca = inet_csk_ca(sk); | 144 | struct bictcp *ca = inet_csk_ca(sk); |
217 | 145 | ||
218 | bictcp_low_utilization(sk, data_acked); | ||
219 | |||
220 | if (!tcp_is_cwnd_limited(sk, in_flight)) | 146 | if (!tcp_is_cwnd_limited(sk, in_flight)) |
221 | return; | 147 | return; |
222 | 148 | ||
@@ -249,11 +175,6 @@ static u32 bictcp_recalc_ssthresh(struct sock *sk) | |||
249 | 175 | ||
250 | ca->epoch_start = 0; /* end of epoch */ | 176 | ca->epoch_start = 0; /* end of epoch */ |
251 | 177 | ||
252 | /* in case of wrong delay_max*/ | ||
253 | if (ca->delay_min > 0 && ca->delay_max > ca->delay_min) | ||
254 | ca->delay_max = ca->delay_min | ||
255 | + ((ca->delay_max - ca->delay_min)* 90) / 100; | ||
256 | |||
257 | /* Wmax and fast convergence */ | 178 | /* Wmax and fast convergence */ |
258 | if (tp->snd_cwnd < ca->last_max_cwnd && fast_convergence) | 179 | if (tp->snd_cwnd < ca->last_max_cwnd && fast_convergence) |
259 | ca->last_max_cwnd = (tp->snd_cwnd * (BICTCP_BETA_SCALE + beta)) | 180 | ca->last_max_cwnd = (tp->snd_cwnd * (BICTCP_BETA_SCALE + beta)) |
@@ -289,14 +210,14 @@ static void bictcp_state(struct sock *sk, u8 new_state) | |||
289 | bictcp_reset(inet_csk_ca(sk)); | 210 | bictcp_reset(inet_csk_ca(sk)); |
290 | } | 211 | } |
291 | 212 | ||
292 | /* Track delayed acknowledgement ratio using sliding window | 213 | /* Track delayed acknowledgment ratio using sliding window |
293 | * ratio = (15*ratio + sample) / 16 | 214 | * ratio = (15*ratio + sample) / 16 |
294 | */ | 215 | */ |
295 | static void bictcp_acked(struct sock *sk, u32 cnt) | 216 | static void bictcp_acked(struct sock *sk, u32 cnt) |
296 | { | 217 | { |
297 | const struct inet_connection_sock *icsk = inet_csk(sk); | 218 | const struct inet_connection_sock *icsk = inet_csk(sk); |
298 | 219 | ||
299 | if (cnt > 0 && icsk->icsk_ca_state == TCP_CA_Open) { | 220 | if (cnt > 0 && icsk->icsk_ca_state == TCP_CA_Open) { |
300 | struct bictcp *ca = inet_csk_ca(sk); | 221 | struct bictcp *ca = inet_csk_ca(sk); |
301 | cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT; | 222 | cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT; |
302 | ca->delayed_ack += cnt; | 223 | ca->delayed_ack += cnt; |
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index c7cc62c8dc12..e688c687d62d 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
@@ -174,6 +174,34 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) | |||
174 | return err; | 174 | return err; |
175 | } | 175 | } |
176 | 176 | ||
177 | |||
178 | /* | ||
179 | * Linear increase during slow start | ||
180 | */ | ||
181 | void tcp_slow_start(struct tcp_sock *tp) | ||
182 | { | ||
183 | if (sysctl_tcp_abc) { | ||
184 | /* RFC3465: Slow Start | ||
185 | * TCP sender SHOULD increase cwnd by the number of | ||
186 | * previously unacknowledged bytes ACKed by each incoming | ||
187 | * acknowledgment, provided the increase is not more than L | ||
188 | */ | ||
189 | if (tp->bytes_acked < tp->mss_cache) | ||
190 | return; | ||
191 | |||
192 | /* We MAY increase by 2 if discovered delayed ack */ | ||
193 | if (sysctl_tcp_abc > 1 && tp->bytes_acked > 2*tp->mss_cache) { | ||
194 | if (tp->snd_cwnd < tp->snd_cwnd_clamp) | ||
195 | tp->snd_cwnd++; | ||
196 | } | ||
197 | } | ||
198 | tp->bytes_acked = 0; | ||
199 | |||
200 | if (tp->snd_cwnd < tp->snd_cwnd_clamp) | ||
201 | tp->snd_cwnd++; | ||
202 | } | ||
203 | EXPORT_SYMBOL_GPL(tcp_slow_start); | ||
204 | |||
177 | /* | 205 | /* |
178 | * TCP Reno congestion control | 206 | * TCP Reno congestion control |
179 | * This is special case used for fallback as well. | 207 | * This is special case used for fallback as well. |
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c new file mode 100644 index 000000000000..31a4986dfbf7 --- /dev/null +++ b/net/ipv4/tcp_cubic.c | |||
@@ -0,0 +1,411 @@ | |||
1 | /* | ||
2 | * TCP CUBIC: Binary Increase Congestion control for TCP v2.0 | ||
3 | * | ||
4 | * This is from the implementation of CUBIC TCP in | ||
5 | * Injong Rhee, Lisong Xu. | ||
6 | * "CUBIC: A New TCP-Friendly High-Speed TCP Variant | ||
7 | * in PFLDnet 2005 | ||
8 | * Available from: | ||
9 | * http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/cubic-paper.pdf | ||
10 | * | ||
11 | * Unless CUBIC is enabled and congestion window is large | ||
12 | * this behaves the same as the original Reno. | ||
13 | */ | ||
14 | |||
15 | #include <linux/config.h> | ||
16 | #include <linux/mm.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <net/tcp.h> | ||
19 | #include <asm/div64.h> | ||
20 | |||
21 | #define BICTCP_BETA_SCALE 1024 /* Scale factor beta calculation | ||
22 | * max_cwnd = snd_cwnd * beta | ||
23 | */ | ||
24 | #define BICTCP_B 4 /* | ||
25 | * In binary search, | ||
26 | * go to point (max+min)/N | ||
27 | */ | ||
28 | #define BICTCP_HZ 10 /* BIC HZ 2^10 = 1024 */ | ||
29 | |||
30 | static int fast_convergence = 1; | ||
31 | static int max_increment = 16; | ||
32 | static int beta = 819; /* = 819/1024 (BICTCP_BETA_SCALE) */ | ||
33 | static int initial_ssthresh = 100; | ||
34 | static int bic_scale = 41; | ||
35 | static int tcp_friendliness = 1; | ||
36 | |||
37 | static u32 cube_rtt_scale; | ||
38 | static u32 beta_scale; | ||
39 | static u64 cube_factor; | ||
40 | |||
41 | /* Note parameters that are used for precomputing scale factors are read-only */ | ||
42 | module_param(fast_convergence, int, 0644); | ||
43 | MODULE_PARM_DESC(fast_convergence, "turn on/off fast convergence"); | ||
44 | module_param(max_increment, int, 0644); | ||
45 | MODULE_PARM_DESC(max_increment, "Limit on increment allowed during binary search"); | ||
46 | module_param(beta, int, 0444); | ||
47 | MODULE_PARM_DESC(beta, "beta for multiplicative increase"); | ||
48 | module_param(initial_ssthresh, int, 0644); | ||
49 | MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold"); | ||
50 | module_param(bic_scale, int, 0444); | ||
51 | MODULE_PARM_DESC(bic_scale, "scale (scaled by 1024) value for bic function (bic_scale/1024)"); | ||
52 | module_param(tcp_friendliness, int, 0644); | ||
53 | MODULE_PARM_DESC(tcp_friendliness, "turn on/off tcp friendliness"); | ||
54 | |||
55 | #include <asm/div64.h> | ||
56 | |||
57 | /* BIC TCP Parameters */ | ||
58 | struct bictcp { | ||
59 | u32 cnt; /* increase cwnd by 1 after ACKs */ | ||
60 | u32 last_max_cwnd; /* last maximum snd_cwnd */ | ||
61 | u32 loss_cwnd; /* congestion window at last loss */ | ||
62 | u32 last_cwnd; /* the last snd_cwnd */ | ||
63 | u32 last_time; /* time when updated last_cwnd */ | ||
64 | u32 bic_origin_point;/* origin point of bic function */ | ||
65 | u32 bic_K; /* time to origin point from the beginning of the current epoch */ | ||
66 | u32 delay_min; /* min delay */ | ||
67 | u32 epoch_start; /* beginning of an epoch */ | ||
68 | u32 ack_cnt; /* number of acks */ | ||
69 | u32 tcp_cwnd; /* estimated tcp cwnd */ | ||
70 | #define ACK_RATIO_SHIFT 4 | ||
71 | u32 delayed_ack; /* estimate the ratio of Packets/ACKs << 4 */ | ||
72 | }; | ||
73 | |||
74 | static inline void bictcp_reset(struct bictcp *ca) | ||
75 | { | ||
76 | ca->cnt = 0; | ||
77 | ca->last_max_cwnd = 0; | ||
78 | ca->loss_cwnd = 0; | ||
79 | ca->last_cwnd = 0; | ||
80 | ca->last_time = 0; | ||
81 | ca->bic_origin_point = 0; | ||
82 | ca->bic_K = 0; | ||
83 | ca->delay_min = 0; | ||
84 | ca->epoch_start = 0; | ||
85 | ca->delayed_ack = 2 << ACK_RATIO_SHIFT; | ||
86 | ca->ack_cnt = 0; | ||
87 | ca->tcp_cwnd = 0; | ||
88 | } | ||
89 | |||
90 | static void bictcp_init(struct sock *sk) | ||
91 | { | ||
92 | bictcp_reset(inet_csk_ca(sk)); | ||
93 | if (initial_ssthresh) | ||
94 | tcp_sk(sk)->snd_ssthresh = initial_ssthresh; | ||
95 | } | ||
96 | |||
97 | /* 64bit divisor, dividend and result. dynamic precision */ | ||
98 | static inline u_int64_t div64_64(u_int64_t dividend, u_int64_t divisor) | ||
99 | { | ||
100 | u_int32_t d = divisor; | ||
101 | |||
102 | if (divisor > 0xffffffffULL) { | ||
103 | unsigned int shift = fls(divisor >> 32); | ||
104 | |||
105 | d = divisor >> shift; | ||
106 | dividend >>= shift; | ||
107 | } | ||
108 | |||
109 | /* avoid 64 bit division if possible */ | ||
110 | if (dividend >> 32) | ||
111 | do_div(dividend, d); | ||
112 | else | ||
113 | dividend = (uint32_t) dividend / d; | ||
114 | |||
115 | return dividend; | ||
116 | } | ||
117 | |||
118 | /* | ||
119 | * calculate the cubic root of x using Newton-Raphson | ||
120 | */ | ||
121 | static u32 cubic_root(u64 a) | ||
122 | { | ||
123 | u32 x, x1; | ||
124 | |||
125 | /* Initial estimate is based on: | ||
126 | * cbrt(x) = exp(log(x) / 3) | ||
127 | */ | ||
128 | x = 1u << (fls64(a)/3); | ||
129 | |||
130 | /* | ||
131 | * Iteration based on: | ||
132 | * 2 | ||
133 | * x = ( 2 * x + a / x ) / 3 | ||
134 | * k+1 k k | ||
135 | */ | ||
136 | do { | ||
137 | x1 = x; | ||
138 | x = (2 * x + (uint32_t) div64_64(a, x*x)) / 3; | ||
139 | } while (abs(x1 - x) > 1); | ||
140 | |||
141 | return x; | ||
142 | } | ||
143 | |||
144 | /* | ||
145 | * Compute congestion window to use. | ||
146 | */ | ||
147 | static inline void bictcp_update(struct bictcp *ca, u32 cwnd) | ||
148 | { | ||
149 | u64 offs; | ||
150 | u32 delta, t, bic_target, min_cnt, max_cnt; | ||
151 | |||
152 | ca->ack_cnt++; /* count the number of ACKs */ | ||
153 | |||
154 | if (ca->last_cwnd == cwnd && | ||
155 | (s32)(tcp_time_stamp - ca->last_time) <= HZ / 32) | ||
156 | return; | ||
157 | |||
158 | ca->last_cwnd = cwnd; | ||
159 | ca->last_time = tcp_time_stamp; | ||
160 | |||
161 | if (ca->epoch_start == 0) { | ||
162 | ca->epoch_start = tcp_time_stamp; /* record the beginning of an epoch */ | ||
163 | ca->ack_cnt = 1; /* start counting */ | ||
164 | ca->tcp_cwnd = cwnd; /* syn with cubic */ | ||
165 | |||
166 | if (ca->last_max_cwnd <= cwnd) { | ||
167 | ca->bic_K = 0; | ||
168 | ca->bic_origin_point = cwnd; | ||
169 | } else { | ||
170 | /* Compute new K based on | ||
171 | * (wmax-cwnd) * (srtt>>3 / HZ) / c * 2^(3*bictcp_HZ) | ||
172 | */ | ||
173 | ca->bic_K = cubic_root(cube_factor | ||
174 | * (ca->last_max_cwnd - cwnd)); | ||
175 | ca->bic_origin_point = ca->last_max_cwnd; | ||
176 | } | ||
177 | } | ||
178 | |||
179 | /* cubic function - calc*/ | ||
180 | /* calculate c * time^3 / rtt, | ||
181 | * while considering overflow in calculation of time^3 | ||
182 | * (so time^3 is done by using 64 bit) | ||
183 | * and without the support of division of 64bit numbers | ||
184 | * (so all divisions are done by using 32 bit) | ||
185 | * also NOTE the unit of those veriables | ||
186 | * time = (t - K) / 2^bictcp_HZ | ||
187 | * c = bic_scale >> 10 | ||
188 | * rtt = (srtt >> 3) / HZ | ||
189 | * !!! The following code does not have overflow problems, | ||
190 | * if the cwnd < 1 million packets !!! | ||
191 | */ | ||
192 | |||
193 | /* change the unit from HZ to bictcp_HZ */ | ||
194 | t = ((tcp_time_stamp + ca->delay_min - ca->epoch_start) | ||
195 | << BICTCP_HZ) / HZ; | ||
196 | |||
197 | if (t < ca->bic_K) /* t - K */ | ||
198 | offs = ca->bic_K - t; | ||
199 | else | ||
200 | offs = t - ca->bic_K; | ||
201 | |||
202 | /* c/rtt * (t-K)^3 */ | ||
203 | delta = (cube_rtt_scale * offs * offs * offs) >> (10+3*BICTCP_HZ); | ||
204 | if (t < ca->bic_K) /* below origin*/ | ||
205 | bic_target = ca->bic_origin_point - delta; | ||
206 | else /* above origin*/ | ||
207 | bic_target = ca->bic_origin_point + delta; | ||
208 | |||
209 | /* cubic function - calc bictcp_cnt*/ | ||
210 | if (bic_target > cwnd) { | ||
211 | ca->cnt = cwnd / (bic_target - cwnd); | ||
212 | } else { | ||
213 | ca->cnt = 100 * cwnd; /* very small increment*/ | ||
214 | } | ||
215 | |||
216 | if (ca->delay_min > 0) { | ||
217 | /* max increment = Smax * rtt / 0.1 */ | ||
218 | min_cnt = (cwnd * HZ * 8)/(10 * max_increment * ca->delay_min); | ||
219 | if (ca->cnt < min_cnt) | ||
220 | ca->cnt = min_cnt; | ||
221 | } | ||
222 | |||
223 | /* slow start and low utilization */ | ||
224 | if (ca->loss_cwnd == 0) /* could be aggressive in slow start */ | ||
225 | ca->cnt = 50; | ||
226 | |||
227 | /* TCP Friendly */ | ||
228 | if (tcp_friendliness) { | ||
229 | u32 scale = beta_scale; | ||
230 | delta = (cwnd * scale) >> 3; | ||
231 | while (ca->ack_cnt > delta) { /* update tcp cwnd */ | ||
232 | ca->ack_cnt -= delta; | ||
233 | ca->tcp_cwnd++; | ||
234 | } | ||
235 | |||
236 | if (ca->tcp_cwnd > cwnd){ /* if bic is slower than tcp */ | ||
237 | delta = ca->tcp_cwnd - cwnd; | ||
238 | max_cnt = cwnd / delta; | ||
239 | if (ca->cnt > max_cnt) | ||
240 | ca->cnt = max_cnt; | ||
241 | } | ||
242 | } | ||
243 | |||
244 | ca->cnt = (ca->cnt << ACK_RATIO_SHIFT) / ca->delayed_ack; | ||
245 | if (ca->cnt == 0) /* cannot be zero */ | ||
246 | ca->cnt = 1; | ||
247 | } | ||
248 | |||
249 | |||
250 | /* Keep track of minimum rtt */ | ||
251 | static inline void measure_delay(struct sock *sk) | ||
252 | { | ||
253 | const struct tcp_sock *tp = tcp_sk(sk); | ||
254 | struct bictcp *ca = inet_csk_ca(sk); | ||
255 | u32 delay; | ||
256 | |||
257 | /* No time stamp */ | ||
258 | if (!(tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) || | ||
259 | /* Discard delay samples right after fast recovery */ | ||
260 | (s32)(tcp_time_stamp - ca->epoch_start) < HZ) | ||
261 | return; | ||
262 | |||
263 | delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr; | ||
264 | if (delay == 0) | ||
265 | delay = 1; | ||
266 | |||
267 | /* first time call or link delay decreases */ | ||
268 | if (ca->delay_min == 0 || ca->delay_min > delay) | ||
269 | ca->delay_min = delay; | ||
270 | } | ||
271 | |||
272 | static void bictcp_cong_avoid(struct sock *sk, u32 ack, | ||
273 | u32 seq_rtt, u32 in_flight, int data_acked) | ||
274 | { | ||
275 | struct tcp_sock *tp = tcp_sk(sk); | ||
276 | struct bictcp *ca = inet_csk_ca(sk); | ||
277 | |||
278 | if (data_acked) | ||
279 | measure_delay(sk); | ||
280 | |||
281 | if (!tcp_is_cwnd_limited(sk, in_flight)) | ||
282 | return; | ||
283 | |||
284 | if (tp->snd_cwnd <= tp->snd_ssthresh) | ||
285 | tcp_slow_start(tp); | ||
286 | else { | ||
287 | bictcp_update(ca, tp->snd_cwnd); | ||
288 | |||
289 | /* In dangerous area, increase slowly. | ||
290 | * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd | ||
291 | */ | ||
292 | if (tp->snd_cwnd_cnt >= ca->cnt) { | ||
293 | if (tp->snd_cwnd < tp->snd_cwnd_clamp) | ||
294 | tp->snd_cwnd++; | ||
295 | tp->snd_cwnd_cnt = 0; | ||
296 | } else | ||
297 | tp->snd_cwnd_cnt++; | ||
298 | } | ||
299 | |||
300 | } | ||
301 | |||
302 | static u32 bictcp_recalc_ssthresh(struct sock *sk) | ||
303 | { | ||
304 | const struct tcp_sock *tp = tcp_sk(sk); | ||
305 | struct bictcp *ca = inet_csk_ca(sk); | ||
306 | |||
307 | ca->epoch_start = 0; /* end of epoch */ | ||
308 | |||
309 | /* Wmax and fast convergence */ | ||
310 | if (tp->snd_cwnd < ca->last_max_cwnd && fast_convergence) | ||
311 | ca->last_max_cwnd = (tp->snd_cwnd * (BICTCP_BETA_SCALE + beta)) | ||
312 | / (2 * BICTCP_BETA_SCALE); | ||
313 | else | ||
314 | ca->last_max_cwnd = tp->snd_cwnd; | ||
315 | |||
316 | ca->loss_cwnd = tp->snd_cwnd; | ||
317 | |||
318 | return max((tp->snd_cwnd * beta) / BICTCP_BETA_SCALE, 2U); | ||
319 | } | ||
320 | |||
321 | static u32 bictcp_undo_cwnd(struct sock *sk) | ||
322 | { | ||
323 | struct bictcp *ca = inet_csk_ca(sk); | ||
324 | |||
325 | return max(tcp_sk(sk)->snd_cwnd, ca->last_max_cwnd); | ||
326 | } | ||
327 | |||
328 | static u32 bictcp_min_cwnd(struct sock *sk) | ||
329 | { | ||
330 | return tcp_sk(sk)->snd_ssthresh; | ||
331 | } | ||
332 | |||
333 | static void bictcp_state(struct sock *sk, u8 new_state) | ||
334 | { | ||
335 | if (new_state == TCP_CA_Loss) | ||
336 | bictcp_reset(inet_csk_ca(sk)); | ||
337 | } | ||
338 | |||
339 | /* Track delayed acknowledgment ratio using sliding window | ||
340 | * ratio = (15*ratio + sample) / 16 | ||
341 | */ | ||
342 | static void bictcp_acked(struct sock *sk, u32 cnt) | ||
343 | { | ||
344 | const struct inet_connection_sock *icsk = inet_csk(sk); | ||
345 | |||
346 | if (cnt > 0 && icsk->icsk_ca_state == TCP_CA_Open) { | ||
347 | struct bictcp *ca = inet_csk_ca(sk); | ||
348 | cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT; | ||
349 | ca->delayed_ack += cnt; | ||
350 | } | ||
351 | } | ||
352 | |||
353 | |||
354 | static struct tcp_congestion_ops cubictcp = { | ||
355 | .init = bictcp_init, | ||
356 | .ssthresh = bictcp_recalc_ssthresh, | ||
357 | .cong_avoid = bictcp_cong_avoid, | ||
358 | .set_state = bictcp_state, | ||
359 | .undo_cwnd = bictcp_undo_cwnd, | ||
360 | .min_cwnd = bictcp_min_cwnd, | ||
361 | .pkts_acked = bictcp_acked, | ||
362 | .owner = THIS_MODULE, | ||
363 | .name = "cubic", | ||
364 | }; | ||
365 | |||
366 | static int __init cubictcp_register(void) | ||
367 | { | ||
368 | BUG_ON(sizeof(struct bictcp) > ICSK_CA_PRIV_SIZE); | ||
369 | |||
370 | /* Precompute a bunch of the scaling factors that are used per-packet | ||
371 | * based on SRTT of 100ms | ||
372 | */ | ||
373 | |||
374 | beta_scale = 8*(BICTCP_BETA_SCALE+beta)/ 3 / (BICTCP_BETA_SCALE - beta); | ||
375 | |||
376 | cube_rtt_scale = (bic_scale << 3) / 10; /* 1024*c/rtt */ | ||
377 | |||
378 | /* calculate the "K" for (wmax-cwnd) = c/rtt * K^3 | ||
379 | * so K = cubic_root( (wmax-cwnd)*rtt/c ) | ||
380 | * the unit of K is bictcp_HZ=2^10, not HZ | ||
381 | * | ||
382 | * c = bic_scale >> 10 | ||
383 | * rtt = 100ms | ||
384 | * | ||
385 | * the following code has been designed and tested for | ||
386 | * cwnd < 1 million packets | ||
387 | * RTT < 100 seconds | ||
388 | * HZ < 1,000,00 (corresponding to 10 nano-second) | ||
389 | */ | ||
390 | |||
391 | /* 1/c * 2^2*bictcp_HZ * srtt */ | ||
392 | cube_factor = 1ull << (10+3*BICTCP_HZ); /* 2^40 */ | ||
393 | |||
394 | /* divide by bic_scale and by constant Srtt (100ms) */ | ||
395 | do_div(cube_factor, bic_scale * 10); | ||
396 | |||
397 | return tcp_register_congestion_control(&cubictcp); | ||
398 | } | ||
399 | |||
400 | static void __exit cubictcp_unregister(void) | ||
401 | { | ||
402 | tcp_unregister_congestion_control(&cubictcp); | ||
403 | } | ||
404 | |||
405 | module_init(cubictcp_register); | ||
406 | module_exit(cubictcp_unregister); | ||
407 | |||
408 | MODULE_AUTHOR("Sangtae Ha, Stephen Hemminger"); | ||
409 | MODULE_LICENSE("GPL"); | ||
410 | MODULE_DESCRIPTION("CUBIC TCP"); | ||
411 | MODULE_VERSION("2.0"); | ||
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index bf2e23086bce..0a461232329f 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -115,8 +115,8 @@ int sysctl_tcp_abc = 1; | |||
115 | /* Adapt the MSS value used to make delayed ack decision to the | 115 | /* Adapt the MSS value used to make delayed ack decision to the |
116 | * real world. | 116 | * real world. |
117 | */ | 117 | */ |
118 | static inline void tcp_measure_rcv_mss(struct sock *sk, | 118 | static void tcp_measure_rcv_mss(struct sock *sk, |
119 | const struct sk_buff *skb) | 119 | const struct sk_buff *skb) |
120 | { | 120 | { |
121 | struct inet_connection_sock *icsk = inet_csk(sk); | 121 | struct inet_connection_sock *icsk = inet_csk(sk); |
122 | const unsigned int lss = icsk->icsk_ack.last_seg_size; | 122 | const unsigned int lss = icsk->icsk_ack.last_seg_size; |
@@ -246,8 +246,8 @@ static int __tcp_grow_window(const struct sock *sk, struct tcp_sock *tp, | |||
246 | return 0; | 246 | return 0; |
247 | } | 247 | } |
248 | 248 | ||
249 | static inline void tcp_grow_window(struct sock *sk, struct tcp_sock *tp, | 249 | static void tcp_grow_window(struct sock *sk, struct tcp_sock *tp, |
250 | struct sk_buff *skb) | 250 | struct sk_buff *skb) |
251 | { | 251 | { |
252 | /* Check #1 */ | 252 | /* Check #1 */ |
253 | if (tp->rcv_ssthresh < tp->window_clamp && | 253 | if (tp->rcv_ssthresh < tp->window_clamp && |
@@ -341,6 +341,26 @@ static void tcp_clamp_window(struct sock *sk, struct tcp_sock *tp) | |||
341 | tp->rcv_ssthresh = min(tp->window_clamp, 2U*tp->advmss); | 341 | tp->rcv_ssthresh = min(tp->window_clamp, 2U*tp->advmss); |
342 | } | 342 | } |
343 | 343 | ||
344 | |||
345 | /* Initialize RCV_MSS value. | ||
346 | * RCV_MSS is an our guess about MSS used by the peer. | ||
347 | * We haven't any direct information about the MSS. | ||
348 | * It's better to underestimate the RCV_MSS rather than overestimate. | ||
349 | * Overestimations make us ACKing less frequently than needed. | ||
350 | * Underestimations are more easy to detect and fix by tcp_measure_rcv_mss(). | ||
351 | */ | ||
352 | void tcp_initialize_rcv_mss(struct sock *sk) | ||
353 | { | ||
354 | struct tcp_sock *tp = tcp_sk(sk); | ||
355 | unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache); | ||
356 | |||
357 | hint = min(hint, tp->rcv_wnd/2); | ||
358 | hint = min(hint, TCP_MIN_RCVMSS); | ||
359 | hint = max(hint, TCP_MIN_MSS); | ||
360 | |||
361 | inet_csk(sk)->icsk_ack.rcv_mss = hint; | ||
362 | } | ||
363 | |||
344 | /* Receiver "autotuning" code. | 364 | /* Receiver "autotuning" code. |
345 | * | 365 | * |
346 | * The algorithm for RTT estimation w/o timestamps is based on | 366 | * The algorithm for RTT estimation w/o timestamps is based on |
@@ -735,6 +755,27 @@ __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst) | |||
735 | return min_t(__u32, cwnd, tp->snd_cwnd_clamp); | 755 | return min_t(__u32, cwnd, tp->snd_cwnd_clamp); |
736 | } | 756 | } |
737 | 757 | ||
758 | /* Set slow start threshold and cwnd not falling to slow start */ | ||
759 | void tcp_enter_cwr(struct sock *sk) | ||
760 | { | ||
761 | struct tcp_sock *tp = tcp_sk(sk); | ||
762 | |||
763 | tp->prior_ssthresh = 0; | ||
764 | tp->bytes_acked = 0; | ||
765 | if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) { | ||
766 | tp->undo_marker = 0; | ||
767 | tp->snd_ssthresh = inet_csk(sk)->icsk_ca_ops->ssthresh(sk); | ||
768 | tp->snd_cwnd = min(tp->snd_cwnd, | ||
769 | tcp_packets_in_flight(tp) + 1U); | ||
770 | tp->snd_cwnd_cnt = 0; | ||
771 | tp->high_seq = tp->snd_nxt; | ||
772 | tp->snd_cwnd_stamp = tcp_time_stamp; | ||
773 | TCP_ECN_queue_cwr(tp); | ||
774 | |||
775 | tcp_set_ca_state(sk, TCP_CA_CWR); | ||
776 | } | ||
777 | } | ||
778 | |||
738 | /* Initialize metrics on socket. */ | 779 | /* Initialize metrics on socket. */ |
739 | 780 | ||
740 | static void tcp_init_metrics(struct sock *sk) | 781 | static void tcp_init_metrics(struct sock *sk) |
@@ -2070,8 +2111,8 @@ static inline void tcp_ack_update_rtt(struct sock *sk, const int flag, | |||
2070 | tcp_ack_no_tstamp(sk, seq_rtt, flag); | 2111 | tcp_ack_no_tstamp(sk, seq_rtt, flag); |
2071 | } | 2112 | } |
2072 | 2113 | ||
2073 | static inline void tcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt, | 2114 | static void tcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt, |
2074 | u32 in_flight, int good) | 2115 | u32 in_flight, int good) |
2075 | { | 2116 | { |
2076 | const struct inet_connection_sock *icsk = inet_csk(sk); | 2117 | const struct inet_connection_sock *icsk = inet_csk(sk); |
2077 | icsk->icsk_ca_ops->cong_avoid(sk, ack, rtt, in_flight, good); | 2118 | icsk->icsk_ca_ops->cong_avoid(sk, ack, rtt, in_flight, good); |
@@ -2082,7 +2123,7 @@ static inline void tcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt, | |||
2082 | * RFC2988 recommends to restart timer to now+rto. | 2123 | * RFC2988 recommends to restart timer to now+rto. |
2083 | */ | 2124 | */ |
2084 | 2125 | ||
2085 | static inline void tcp_ack_packets_out(struct sock *sk, struct tcp_sock *tp) | 2126 | static void tcp_ack_packets_out(struct sock *sk, struct tcp_sock *tp) |
2086 | { | 2127 | { |
2087 | if (!tp->packets_out) { | 2128 | if (!tp->packets_out) { |
2088 | inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS); | 2129 | inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS); |
@@ -2147,7 +2188,7 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb, | |||
2147 | return acked; | 2188 | return acked; |
2148 | } | 2189 | } |
2149 | 2190 | ||
2150 | static inline u32 tcp_usrtt(const struct sk_buff *skb) | 2191 | static u32 tcp_usrtt(const struct sk_buff *skb) |
2151 | { | 2192 | { |
2152 | struct timeval tv, now; | 2193 | struct timeval tv, now; |
2153 | 2194 | ||
@@ -2342,7 +2383,7 @@ static int tcp_ack_update_window(struct sock *sk, struct tcp_sock *tp, | |||
2342 | 2383 | ||
2343 | if (nwin > tp->max_window) { | 2384 | if (nwin > tp->max_window) { |
2344 | tp->max_window = nwin; | 2385 | tp->max_window = nwin; |
2345 | tcp_sync_mss(sk, tp->pmtu_cookie); | 2386 | tcp_sync_mss(sk, inet_csk(sk)->icsk_pmtu_cookie); |
2346 | } | 2387 | } |
2347 | } | 2388 | } |
2348 | } | 2389 | } |
@@ -2583,8 +2624,8 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx, | |||
2583 | /* Fast parse options. This hopes to only see timestamps. | 2624 | /* Fast parse options. This hopes to only see timestamps. |
2584 | * If it is wrong it falls back on tcp_parse_options(). | 2625 | * If it is wrong it falls back on tcp_parse_options(). |
2585 | */ | 2626 | */ |
2586 | static inline int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th, | 2627 | static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th, |
2587 | struct tcp_sock *tp) | 2628 | struct tcp_sock *tp) |
2588 | { | 2629 | { |
2589 | if (th->doff == sizeof(struct tcphdr)>>2) { | 2630 | if (th->doff == sizeof(struct tcphdr)>>2) { |
2590 | tp->rx_opt.saw_tstamp = 0; | 2631 | tp->rx_opt.saw_tstamp = 0; |
@@ -2804,8 +2845,7 @@ static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th) | |||
2804 | } | 2845 | } |
2805 | } | 2846 | } |
2806 | 2847 | ||
2807 | static __inline__ int | 2848 | static inline int tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, u32 end_seq) |
2808 | tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, u32 end_seq) | ||
2809 | { | 2849 | { |
2810 | if (!after(seq, sp->end_seq) && !after(sp->start_seq, end_seq)) { | 2850 | if (!after(seq, sp->end_seq) && !after(sp->start_seq, end_seq)) { |
2811 | if (before(seq, sp->start_seq)) | 2851 | if (before(seq, sp->start_seq)) |
@@ -2817,7 +2857,7 @@ tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, u32 end_seq) | |||
2817 | return 0; | 2857 | return 0; |
2818 | } | 2858 | } |
2819 | 2859 | ||
2820 | static inline void tcp_dsack_set(struct tcp_sock *tp, u32 seq, u32 end_seq) | 2860 | static void tcp_dsack_set(struct tcp_sock *tp, u32 seq, u32 end_seq) |
2821 | { | 2861 | { |
2822 | if (tp->rx_opt.sack_ok && sysctl_tcp_dsack) { | 2862 | if (tp->rx_opt.sack_ok && sysctl_tcp_dsack) { |
2823 | if (before(seq, tp->rcv_nxt)) | 2863 | if (before(seq, tp->rcv_nxt)) |
@@ -2832,7 +2872,7 @@ static inline void tcp_dsack_set(struct tcp_sock *tp, u32 seq, u32 end_seq) | |||
2832 | } | 2872 | } |
2833 | } | 2873 | } |
2834 | 2874 | ||
2835 | static inline void tcp_dsack_extend(struct tcp_sock *tp, u32 seq, u32 end_seq) | 2875 | static void tcp_dsack_extend(struct tcp_sock *tp, u32 seq, u32 end_seq) |
2836 | { | 2876 | { |
2837 | if (!tp->rx_opt.dsack) | 2877 | if (!tp->rx_opt.dsack) |
2838 | tcp_dsack_set(tp, seq, end_seq); | 2878 | tcp_dsack_set(tp, seq, end_seq); |
@@ -2890,7 +2930,7 @@ static void tcp_sack_maybe_coalesce(struct tcp_sock *tp) | |||
2890 | } | 2930 | } |
2891 | } | 2931 | } |
2892 | 2932 | ||
2893 | static __inline__ void tcp_sack_swap(struct tcp_sack_block *sack1, struct tcp_sack_block *sack2) | 2933 | static inline void tcp_sack_swap(struct tcp_sack_block *sack1, struct tcp_sack_block *sack2) |
2894 | { | 2934 | { |
2895 | __u32 tmp; | 2935 | __u32 tmp; |
2896 | 2936 | ||
@@ -3455,7 +3495,7 @@ void tcp_cwnd_application_limited(struct sock *sk) | |||
3455 | tp->snd_cwnd_stamp = tcp_time_stamp; | 3495 | tp->snd_cwnd_stamp = tcp_time_stamp; |
3456 | } | 3496 | } |
3457 | 3497 | ||
3458 | static inline int tcp_should_expand_sndbuf(struct sock *sk, struct tcp_sock *tp) | 3498 | static int tcp_should_expand_sndbuf(struct sock *sk, struct tcp_sock *tp) |
3459 | { | 3499 | { |
3460 | /* If the user specified a specific send buffer setting, do | 3500 | /* If the user specified a specific send buffer setting, do |
3461 | * not modify it. | 3501 | * not modify it. |
@@ -3502,7 +3542,7 @@ static void tcp_new_space(struct sock *sk) | |||
3502 | sk->sk_write_space(sk); | 3542 | sk->sk_write_space(sk); |
3503 | } | 3543 | } |
3504 | 3544 | ||
3505 | static inline void tcp_check_space(struct sock *sk) | 3545 | static void tcp_check_space(struct sock *sk) |
3506 | { | 3546 | { |
3507 | if (sock_flag(sk, SOCK_QUEUE_SHRUNK)) { | 3547 | if (sock_flag(sk, SOCK_QUEUE_SHRUNK)) { |
3508 | sock_reset_flag(sk, SOCK_QUEUE_SHRUNK); | 3548 | sock_reset_flag(sk, SOCK_QUEUE_SHRUNK); |
@@ -3512,7 +3552,7 @@ static inline void tcp_check_space(struct sock *sk) | |||
3512 | } | 3552 | } |
3513 | } | 3553 | } |
3514 | 3554 | ||
3515 | static __inline__ void tcp_data_snd_check(struct sock *sk, struct tcp_sock *tp) | 3555 | static inline void tcp_data_snd_check(struct sock *sk, struct tcp_sock *tp) |
3516 | { | 3556 | { |
3517 | tcp_push_pending_frames(sk, tp); | 3557 | tcp_push_pending_frames(sk, tp); |
3518 | tcp_check_space(sk); | 3558 | tcp_check_space(sk); |
@@ -3544,7 +3584,7 @@ static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible) | |||
3544 | } | 3584 | } |
3545 | } | 3585 | } |
3546 | 3586 | ||
3547 | static __inline__ void tcp_ack_snd_check(struct sock *sk) | 3587 | static inline void tcp_ack_snd_check(struct sock *sk) |
3548 | { | 3588 | { |
3549 | if (!inet_csk_ack_scheduled(sk)) { | 3589 | if (!inet_csk_ack_scheduled(sk)) { |
3550 | /* We sent a data segment already. */ | 3590 | /* We sent a data segment already. */ |
@@ -3692,8 +3732,7 @@ static int __tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb) | |||
3692 | return result; | 3732 | return result; |
3693 | } | 3733 | } |
3694 | 3734 | ||
3695 | static __inline__ int | 3735 | static inline int tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb) |
3696 | tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb) | ||
3697 | { | 3736 | { |
3698 | return skb->ip_summed != CHECKSUM_UNNECESSARY && | 3737 | return skb->ip_summed != CHECKSUM_UNNECESSARY && |
3699 | __tcp_checksum_complete_user(sk, skb); | 3738 | __tcp_checksum_complete_user(sk, skb); |
@@ -3967,12 +4006,12 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, | |||
3967 | struct tcphdr *th, unsigned len) | 4006 | struct tcphdr *th, unsigned len) |
3968 | { | 4007 | { |
3969 | struct tcp_sock *tp = tcp_sk(sk); | 4008 | struct tcp_sock *tp = tcp_sk(sk); |
4009 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
3970 | int saved_clamp = tp->rx_opt.mss_clamp; | 4010 | int saved_clamp = tp->rx_opt.mss_clamp; |
3971 | 4011 | ||
3972 | tcp_parse_options(skb, &tp->rx_opt, 0); | 4012 | tcp_parse_options(skb, &tp->rx_opt, 0); |
3973 | 4013 | ||
3974 | if (th->ack) { | 4014 | if (th->ack) { |
3975 | struct inet_connection_sock *icsk; | ||
3976 | /* rfc793: | 4015 | /* rfc793: |
3977 | * "If the state is SYN-SENT then | 4016 | * "If the state is SYN-SENT then |
3978 | * first check the ACK bit | 4017 | * first check the ACK bit |
@@ -4061,7 +4100,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, | |||
4061 | if (tp->rx_opt.sack_ok && sysctl_tcp_fack) | 4100 | if (tp->rx_opt.sack_ok && sysctl_tcp_fack) |
4062 | tp->rx_opt.sack_ok |= 2; | 4101 | tp->rx_opt.sack_ok |= 2; |
4063 | 4102 | ||
4064 | tcp_sync_mss(sk, tp->pmtu_cookie); | 4103 | tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); |
4065 | tcp_initialize_rcv_mss(sk); | 4104 | tcp_initialize_rcv_mss(sk); |
4066 | 4105 | ||
4067 | /* Remember, tcp_poll() does not lock socket! | 4106 | /* Remember, tcp_poll() does not lock socket! |
@@ -4072,7 +4111,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, | |||
4072 | tcp_set_state(sk, TCP_ESTABLISHED); | 4111 | tcp_set_state(sk, TCP_ESTABLISHED); |
4073 | 4112 | ||
4074 | /* Make sure socket is routed, for correct metrics. */ | 4113 | /* Make sure socket is routed, for correct metrics. */ |
4075 | tp->af_specific->rebuild_header(sk); | 4114 | icsk->icsk_af_ops->rebuild_header(sk); |
4076 | 4115 | ||
4077 | tcp_init_metrics(sk); | 4116 | tcp_init_metrics(sk); |
4078 | 4117 | ||
@@ -4098,8 +4137,6 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, | |||
4098 | sk_wake_async(sk, 0, POLL_OUT); | 4137 | sk_wake_async(sk, 0, POLL_OUT); |
4099 | } | 4138 | } |
4100 | 4139 | ||
4101 | icsk = inet_csk(sk); | ||
4102 | |||
4103 | if (sk->sk_write_pending || | 4140 | if (sk->sk_write_pending || |
4104 | icsk->icsk_accept_queue.rskq_defer_accept || | 4141 | icsk->icsk_accept_queue.rskq_defer_accept || |
4105 | icsk->icsk_ack.pingpong) { | 4142 | icsk->icsk_ack.pingpong) { |
@@ -4173,7 +4210,7 @@ discard: | |||
4173 | if (tp->ecn_flags&TCP_ECN_OK) | 4210 | if (tp->ecn_flags&TCP_ECN_OK) |
4174 | sock_set_flag(sk, SOCK_NO_LARGESEND); | 4211 | sock_set_flag(sk, SOCK_NO_LARGESEND); |
4175 | 4212 | ||
4176 | tcp_sync_mss(sk, tp->pmtu_cookie); | 4213 | tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); |
4177 | tcp_initialize_rcv_mss(sk); | 4214 | tcp_initialize_rcv_mss(sk); |
4178 | 4215 | ||
4179 | 4216 | ||
@@ -4220,6 +4257,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
4220 | struct tcphdr *th, unsigned len) | 4257 | struct tcphdr *th, unsigned len) |
4221 | { | 4258 | { |
4222 | struct tcp_sock *tp = tcp_sk(sk); | 4259 | struct tcp_sock *tp = tcp_sk(sk); |
4260 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
4223 | int queued = 0; | 4261 | int queued = 0; |
4224 | 4262 | ||
4225 | tp->rx_opt.saw_tstamp = 0; | 4263 | tp->rx_opt.saw_tstamp = 0; |
@@ -4236,7 +4274,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
4236 | goto discard; | 4274 | goto discard; |
4237 | 4275 | ||
4238 | if(th->syn) { | 4276 | if(th->syn) { |
4239 | if(tp->af_specific->conn_request(sk, skb) < 0) | 4277 | if (icsk->icsk_af_ops->conn_request(sk, skb) < 0) |
4240 | return 1; | 4278 | return 1; |
4241 | 4279 | ||
4242 | /* Now we have several options: In theory there is | 4280 | /* Now we have several options: In theory there is |
@@ -4349,7 +4387,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
4349 | /* Make sure socket is routed, for | 4387 | /* Make sure socket is routed, for |
4350 | * correct metrics. | 4388 | * correct metrics. |
4351 | */ | 4389 | */ |
4352 | tp->af_specific->rebuild_header(sk); | 4390 | icsk->icsk_af_ops->rebuild_header(sk); |
4353 | 4391 | ||
4354 | tcp_init_metrics(sk); | 4392 | tcp_init_metrics(sk); |
4355 | 4393 | ||
@@ -4475,3 +4513,4 @@ EXPORT_SYMBOL(sysctl_tcp_abc); | |||
4475 | EXPORT_SYMBOL(tcp_parse_options); | 4513 | EXPORT_SYMBOL(tcp_parse_options); |
4476 | EXPORT_SYMBOL(tcp_rcv_established); | 4514 | EXPORT_SYMBOL(tcp_rcv_established); |
4477 | EXPORT_SYMBOL(tcp_rcv_state_process); | 4515 | EXPORT_SYMBOL(tcp_rcv_state_process); |
4516 | EXPORT_SYMBOL(tcp_initialize_rcv_mss); | ||
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 4d5021e1929b..e9f83e5b28ce 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -69,6 +69,7 @@ | |||
69 | #include <net/transp_v6.h> | 69 | #include <net/transp_v6.h> |
70 | #include <net/ipv6.h> | 70 | #include <net/ipv6.h> |
71 | #include <net/inet_common.h> | 71 | #include <net/inet_common.h> |
72 | #include <net/timewait_sock.h> | ||
72 | #include <net/xfrm.h> | 73 | #include <net/xfrm.h> |
73 | 74 | ||
74 | #include <linux/inet.h> | 75 | #include <linux/inet.h> |
@@ -86,8 +87,7 @@ int sysctl_tcp_low_latency; | |||
86 | /* Socket used for sending RSTs */ | 87 | /* Socket used for sending RSTs */ |
87 | static struct socket *tcp_socket; | 88 | static struct socket *tcp_socket; |
88 | 89 | ||
89 | void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len, | 90 | void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb); |
90 | struct sk_buff *skb); | ||
91 | 91 | ||
92 | struct inet_hashinfo __cacheline_aligned tcp_hashinfo = { | 92 | struct inet_hashinfo __cacheline_aligned tcp_hashinfo = { |
93 | .lhash_lock = RW_LOCK_UNLOCKED, | 93 | .lhash_lock = RW_LOCK_UNLOCKED, |
@@ -97,7 +97,8 @@ struct inet_hashinfo __cacheline_aligned tcp_hashinfo = { | |||
97 | 97 | ||
98 | static int tcp_v4_get_port(struct sock *sk, unsigned short snum) | 98 | static int tcp_v4_get_port(struct sock *sk, unsigned short snum) |
99 | { | 99 | { |
100 | return inet_csk_get_port(&tcp_hashinfo, sk, snum); | 100 | return inet_csk_get_port(&tcp_hashinfo, sk, snum, |
101 | inet_csk_bind_conflict); | ||
101 | } | 102 | } |
102 | 103 | ||
103 | static void tcp_v4_hash(struct sock *sk) | 104 | static void tcp_v4_hash(struct sock *sk) |
@@ -118,202 +119,38 @@ static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb) | |||
118 | skb->h.th->source); | 119 | skb->h.th->source); |
119 | } | 120 | } |
120 | 121 | ||
121 | /* called with local bh disabled */ | 122 | int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp) |
122 | static int __tcp_v4_check_established(struct sock *sk, __u16 lport, | ||
123 | struct inet_timewait_sock **twp) | ||
124 | { | 123 | { |
125 | struct inet_sock *inet = inet_sk(sk); | 124 | const struct tcp_timewait_sock *tcptw = tcp_twsk(sktw); |
126 | u32 daddr = inet->rcv_saddr; | 125 | struct tcp_sock *tp = tcp_sk(sk); |
127 | u32 saddr = inet->daddr; | ||
128 | int dif = sk->sk_bound_dev_if; | ||
129 | INET_ADDR_COOKIE(acookie, saddr, daddr) | ||
130 | const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport); | ||
131 | unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport); | ||
132 | struct inet_ehash_bucket *head = inet_ehash_bucket(&tcp_hashinfo, hash); | ||
133 | struct sock *sk2; | ||
134 | const struct hlist_node *node; | ||
135 | struct inet_timewait_sock *tw; | ||
136 | |||
137 | prefetch(head->chain.first); | ||
138 | write_lock(&head->lock); | ||
139 | |||
140 | /* Check TIME-WAIT sockets first. */ | ||
141 | sk_for_each(sk2, node, &(head + tcp_hashinfo.ehash_size)->chain) { | ||
142 | tw = inet_twsk(sk2); | ||
143 | |||
144 | if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) { | ||
145 | const struct tcp_timewait_sock *tcptw = tcp_twsk(sk2); | ||
146 | struct tcp_sock *tp = tcp_sk(sk); | ||
147 | |||
148 | /* With PAWS, it is safe from the viewpoint | ||
149 | of data integrity. Even without PAWS it | ||
150 | is safe provided sequence spaces do not | ||
151 | overlap i.e. at data rates <= 80Mbit/sec. | ||
152 | |||
153 | Actually, the idea is close to VJ's one, | ||
154 | only timestamp cache is held not per host, | ||
155 | but per port pair and TW bucket is used | ||
156 | as state holder. | ||
157 | 126 | ||
158 | If TW bucket has been already destroyed we | 127 | /* With PAWS, it is safe from the viewpoint |
159 | fall back to VJ's scheme and use initial | 128 | of data integrity. Even without PAWS it is safe provided sequence |
160 | timestamp retrieved from peer table. | 129 | spaces do not overlap i.e. at data rates <= 80Mbit/sec. |
161 | */ | ||
162 | if (tcptw->tw_ts_recent_stamp && | ||
163 | (!twp || (sysctl_tcp_tw_reuse && | ||
164 | xtime.tv_sec - | ||
165 | tcptw->tw_ts_recent_stamp > 1))) { | ||
166 | tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2; | ||
167 | if (tp->write_seq == 0) | ||
168 | tp->write_seq = 1; | ||
169 | tp->rx_opt.ts_recent = tcptw->tw_ts_recent; | ||
170 | tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp; | ||
171 | sock_hold(sk2); | ||
172 | goto unique; | ||
173 | } else | ||
174 | goto not_unique; | ||
175 | } | ||
176 | } | ||
177 | tw = NULL; | ||
178 | 130 | ||
179 | /* And established part... */ | 131 | Actually, the idea is close to VJ's one, only timestamp cache is |
180 | sk_for_each(sk2, node, &head->chain) { | 132 | held not per host, but per port pair and TW bucket is used as state |
181 | if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) | 133 | holder. |
182 | goto not_unique; | ||
183 | } | ||
184 | 134 | ||
185 | unique: | 135 | If TW bucket has been already destroyed we fall back to VJ's scheme |
186 | /* Must record num and sport now. Otherwise we will see | 136 | and use initial timestamp retrieved from peer table. |
187 | * in hash table socket with a funny identity. */ | 137 | */ |
188 | inet->num = lport; | 138 | if (tcptw->tw_ts_recent_stamp && |
189 | inet->sport = htons(lport); | 139 | (twp == NULL || (sysctl_tcp_tw_reuse && |
190 | sk->sk_hash = hash; | 140 | xtime.tv_sec - tcptw->tw_ts_recent_stamp > 1))) { |
191 | BUG_TRAP(sk_unhashed(sk)); | 141 | tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2; |
192 | __sk_add_node(sk, &head->chain); | 142 | if (tp->write_seq == 0) |
193 | sock_prot_inc_use(sk->sk_prot); | 143 | tp->write_seq = 1; |
194 | write_unlock(&head->lock); | 144 | tp->rx_opt.ts_recent = tcptw->tw_ts_recent; |
195 | 145 | tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp; | |
196 | if (twp) { | 146 | sock_hold(sktw); |
197 | *twp = tw; | 147 | return 1; |
198 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); | ||
199 | } else if (tw) { | ||
200 | /* Silly. Should hash-dance instead... */ | ||
201 | inet_twsk_deschedule(tw, &tcp_death_row); | ||
202 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); | ||
203 | |||
204 | inet_twsk_put(tw); | ||
205 | } | 148 | } |
206 | 149 | ||
207 | return 0; | 150 | return 0; |
208 | |||
209 | not_unique: | ||
210 | write_unlock(&head->lock); | ||
211 | return -EADDRNOTAVAIL; | ||
212 | } | 151 | } |
213 | 152 | ||
214 | static inline u32 connect_port_offset(const struct sock *sk) | 153 | EXPORT_SYMBOL_GPL(tcp_twsk_unique); |
215 | { | ||
216 | const struct inet_sock *inet = inet_sk(sk); | ||
217 | |||
218 | return secure_tcp_port_ephemeral(inet->rcv_saddr, inet->daddr, | ||
219 | inet->dport); | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | * Bind a port for a connect operation and hash it. | ||
224 | */ | ||
225 | static inline int tcp_v4_hash_connect(struct sock *sk) | ||
226 | { | ||
227 | const unsigned short snum = inet_sk(sk)->num; | ||
228 | struct inet_bind_hashbucket *head; | ||
229 | struct inet_bind_bucket *tb; | ||
230 | int ret; | ||
231 | |||
232 | if (!snum) { | ||
233 | int low = sysctl_local_port_range[0]; | ||
234 | int high = sysctl_local_port_range[1]; | ||
235 | int range = high - low; | ||
236 | int i; | ||
237 | int port; | ||
238 | static u32 hint; | ||
239 | u32 offset = hint + connect_port_offset(sk); | ||
240 | struct hlist_node *node; | ||
241 | struct inet_timewait_sock *tw = NULL; | ||
242 | |||
243 | local_bh_disable(); | ||
244 | for (i = 1; i <= range; i++) { | ||
245 | port = low + (i + offset) % range; | ||
246 | head = &tcp_hashinfo.bhash[inet_bhashfn(port, tcp_hashinfo.bhash_size)]; | ||
247 | spin_lock(&head->lock); | ||
248 | |||
249 | /* Does not bother with rcv_saddr checks, | ||
250 | * because the established check is already | ||
251 | * unique enough. | ||
252 | */ | ||
253 | inet_bind_bucket_for_each(tb, node, &head->chain) { | ||
254 | if (tb->port == port) { | ||
255 | BUG_TRAP(!hlist_empty(&tb->owners)); | ||
256 | if (tb->fastreuse >= 0) | ||
257 | goto next_port; | ||
258 | if (!__tcp_v4_check_established(sk, | ||
259 | port, | ||
260 | &tw)) | ||
261 | goto ok; | ||
262 | goto next_port; | ||
263 | } | ||
264 | } | ||
265 | |||
266 | tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, port); | ||
267 | if (!tb) { | ||
268 | spin_unlock(&head->lock); | ||
269 | break; | ||
270 | } | ||
271 | tb->fastreuse = -1; | ||
272 | goto ok; | ||
273 | |||
274 | next_port: | ||
275 | spin_unlock(&head->lock); | ||
276 | } | ||
277 | local_bh_enable(); | ||
278 | |||
279 | return -EADDRNOTAVAIL; | ||
280 | |||
281 | ok: | ||
282 | hint += i; | ||
283 | |||
284 | /* Head lock still held and bh's disabled */ | ||
285 | inet_bind_hash(sk, tb, port); | ||
286 | if (sk_unhashed(sk)) { | ||
287 | inet_sk(sk)->sport = htons(port); | ||
288 | __inet_hash(&tcp_hashinfo, sk, 0); | ||
289 | } | ||
290 | spin_unlock(&head->lock); | ||
291 | |||
292 | if (tw) { | ||
293 | inet_twsk_deschedule(tw, &tcp_death_row);; | ||
294 | inet_twsk_put(tw); | ||
295 | } | ||
296 | |||
297 | ret = 0; | ||
298 | goto out; | ||
299 | } | ||
300 | |||
301 | head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)]; | ||
302 | tb = inet_csk(sk)->icsk_bind_hash; | ||
303 | spin_lock_bh(&head->lock); | ||
304 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { | ||
305 | __inet_hash(&tcp_hashinfo, sk, 0); | ||
306 | spin_unlock_bh(&head->lock); | ||
307 | return 0; | ||
308 | } else { | ||
309 | spin_unlock(&head->lock); | ||
310 | /* No definite answer... Walk to established hash table */ | ||
311 | ret = __tcp_v4_check_established(sk, snum, NULL); | ||
312 | out: | ||
313 | local_bh_enable(); | ||
314 | return ret; | ||
315 | } | ||
316 | } | ||
317 | 154 | ||
318 | /* This will initiate an outgoing connection. */ | 155 | /* This will initiate an outgoing connection. */ |
319 | int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | 156 | int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
@@ -383,9 +220,9 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
383 | inet->dport = usin->sin_port; | 220 | inet->dport = usin->sin_port; |
384 | inet->daddr = daddr; | 221 | inet->daddr = daddr; |
385 | 222 | ||
386 | tp->ext_header_len = 0; | 223 | inet_csk(sk)->icsk_ext_hdr_len = 0; |
387 | if (inet->opt) | 224 | if (inet->opt) |
388 | tp->ext_header_len = inet->opt->optlen; | 225 | inet_csk(sk)->icsk_ext_hdr_len = inet->opt->optlen; |
389 | 226 | ||
390 | tp->rx_opt.mss_clamp = 536; | 227 | tp->rx_opt.mss_clamp = 536; |
391 | 228 | ||
@@ -395,7 +232,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
395 | * complete initialization after this. | 232 | * complete initialization after this. |
396 | */ | 233 | */ |
397 | tcp_set_state(sk, TCP_SYN_SENT); | 234 | tcp_set_state(sk, TCP_SYN_SENT); |
398 | err = tcp_v4_hash_connect(sk); | 235 | err = inet_hash_connect(&tcp_death_row, sk); |
399 | if (err) | 236 | if (err) |
400 | goto failure; | 237 | goto failure; |
401 | 238 | ||
@@ -433,12 +270,10 @@ failure: | |||
433 | /* | 270 | /* |
434 | * This routine does path mtu discovery as defined in RFC1191. | 271 | * This routine does path mtu discovery as defined in RFC1191. |
435 | */ | 272 | */ |
436 | static inline void do_pmtu_discovery(struct sock *sk, struct iphdr *iph, | 273 | static void do_pmtu_discovery(struct sock *sk, struct iphdr *iph, u32 mtu) |
437 | u32 mtu) | ||
438 | { | 274 | { |
439 | struct dst_entry *dst; | 275 | struct dst_entry *dst; |
440 | struct inet_sock *inet = inet_sk(sk); | 276 | struct inet_sock *inet = inet_sk(sk); |
441 | struct tcp_sock *tp = tcp_sk(sk); | ||
442 | 277 | ||
443 | /* We are not interested in TCP_LISTEN and open_requests (SYN-ACKs | 278 | /* We are not interested in TCP_LISTEN and open_requests (SYN-ACKs |
444 | * send out by Linux are always <576bytes so they should go through | 279 | * send out by Linux are always <576bytes so they should go through |
@@ -467,7 +302,7 @@ static inline void do_pmtu_discovery(struct sock *sk, struct iphdr *iph, | |||
467 | mtu = dst_mtu(dst); | 302 | mtu = dst_mtu(dst); |
468 | 303 | ||
469 | if (inet->pmtudisc != IP_PMTUDISC_DONT && | 304 | if (inet->pmtudisc != IP_PMTUDISC_DONT && |
470 | tp->pmtu_cookie > mtu) { | 305 | inet_csk(sk)->icsk_pmtu_cookie > mtu) { |
471 | tcp_sync_mss(sk, mtu); | 306 | tcp_sync_mss(sk, mtu); |
472 | 307 | ||
473 | /* Resend the TCP packet because it's | 308 | /* Resend the TCP packet because it's |
@@ -644,10 +479,10 @@ out: | |||
644 | } | 479 | } |
645 | 480 | ||
646 | /* This routine computes an IPv4 TCP checksum. */ | 481 | /* This routine computes an IPv4 TCP checksum. */ |
647 | void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len, | 482 | void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb) |
648 | struct sk_buff *skb) | ||
649 | { | 483 | { |
650 | struct inet_sock *inet = inet_sk(sk); | 484 | struct inet_sock *inet = inet_sk(sk); |
485 | struct tcphdr *th = skb->h.th; | ||
651 | 486 | ||
652 | if (skb->ip_summed == CHECKSUM_HW) { | 487 | if (skb->ip_summed == CHECKSUM_HW) { |
653 | th->check = ~tcp_v4_check(th, len, inet->saddr, inet->daddr, 0); | 488 | th->check = ~tcp_v4_check(th, len, inet->saddr, inet->daddr, 0); |
@@ -826,7 +661,8 @@ static void tcp_v4_reqsk_destructor(struct request_sock *req) | |||
826 | kfree(inet_rsk(req)->opt); | 661 | kfree(inet_rsk(req)->opt); |
827 | } | 662 | } |
828 | 663 | ||
829 | static inline void syn_flood_warning(struct sk_buff *skb) | 664 | #ifdef CONFIG_SYN_COOKIES |
665 | static void syn_flood_warning(struct sk_buff *skb) | ||
830 | { | 666 | { |
831 | static unsigned long warntime; | 667 | static unsigned long warntime; |
832 | 668 | ||
@@ -837,12 +673,13 @@ static inline void syn_flood_warning(struct sk_buff *skb) | |||
837 | ntohs(skb->h.th->dest)); | 673 | ntohs(skb->h.th->dest)); |
838 | } | 674 | } |
839 | } | 675 | } |
676 | #endif | ||
840 | 677 | ||
841 | /* | 678 | /* |
842 | * Save and compile IPv4 options into the request_sock if needed. | 679 | * Save and compile IPv4 options into the request_sock if needed. |
843 | */ | 680 | */ |
844 | static inline struct ip_options *tcp_v4_save_options(struct sock *sk, | 681 | static struct ip_options *tcp_v4_save_options(struct sock *sk, |
845 | struct sk_buff *skb) | 682 | struct sk_buff *skb) |
846 | { | 683 | { |
847 | struct ip_options *opt = &(IPCB(skb)->opt); | 684 | struct ip_options *opt = &(IPCB(skb)->opt); |
848 | struct ip_options *dopt = NULL; | 685 | struct ip_options *dopt = NULL; |
@@ -869,6 +706,11 @@ struct request_sock_ops tcp_request_sock_ops = { | |||
869 | .send_reset = tcp_v4_send_reset, | 706 | .send_reset = tcp_v4_send_reset, |
870 | }; | 707 | }; |
871 | 708 | ||
709 | static struct timewait_sock_ops tcp_timewait_sock_ops = { | ||
710 | .twsk_obj_size = sizeof(struct tcp_timewait_sock), | ||
711 | .twsk_unique = tcp_twsk_unique, | ||
712 | }; | ||
713 | |||
872 | int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | 714 | int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) |
873 | { | 715 | { |
874 | struct inet_request_sock *ireq; | 716 | struct inet_request_sock *ireq; |
@@ -1053,9 +895,9 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1053 | ireq->opt = NULL; | 895 | ireq->opt = NULL; |
1054 | newinet->mc_index = inet_iif(skb); | 896 | newinet->mc_index = inet_iif(skb); |
1055 | newinet->mc_ttl = skb->nh.iph->ttl; | 897 | newinet->mc_ttl = skb->nh.iph->ttl; |
1056 | newtp->ext_header_len = 0; | 898 | inet_csk(newsk)->icsk_ext_hdr_len = 0; |
1057 | if (newinet->opt) | 899 | if (newinet->opt) |
1058 | newtp->ext_header_len = newinet->opt->optlen; | 900 | inet_csk(newsk)->icsk_ext_hdr_len = newinet->opt->optlen; |
1059 | newinet->id = newtp->write_seq ^ jiffies; | 901 | newinet->id = newtp->write_seq ^ jiffies; |
1060 | 902 | ||
1061 | tcp_sync_mss(newsk, dst_mtu(dst)); | 903 | tcp_sync_mss(newsk, dst_mtu(dst)); |
@@ -1314,16 +1156,6 @@ do_time_wait: | |||
1314 | goto discard_it; | 1156 | goto discard_it; |
1315 | } | 1157 | } |
1316 | 1158 | ||
1317 | static void v4_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr) | ||
1318 | { | ||
1319 | struct sockaddr_in *sin = (struct sockaddr_in *) uaddr; | ||
1320 | struct inet_sock *inet = inet_sk(sk); | ||
1321 | |||
1322 | sin->sin_family = AF_INET; | ||
1323 | sin->sin_addr.s_addr = inet->daddr; | ||
1324 | sin->sin_port = inet->dport; | ||
1325 | } | ||
1326 | |||
1327 | /* VJ's idea. Save last timestamp seen from this destination | 1159 | /* VJ's idea. Save last timestamp seen from this destination |
1328 | * and hold it at least for normal timewait interval to use for duplicate | 1160 | * and hold it at least for normal timewait interval to use for duplicate |
1329 | * segment detection in subsequent connections, before they enter synchronized | 1161 | * segment detection in subsequent connections, before they enter synchronized |
@@ -1382,7 +1214,7 @@ int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw) | |||
1382 | return 0; | 1214 | return 0; |
1383 | } | 1215 | } |
1384 | 1216 | ||
1385 | struct tcp_func ipv4_specific = { | 1217 | struct inet_connection_sock_af_ops ipv4_specific = { |
1386 | .queue_xmit = ip_queue_xmit, | 1218 | .queue_xmit = ip_queue_xmit, |
1387 | .send_check = tcp_v4_send_check, | 1219 | .send_check = tcp_v4_send_check, |
1388 | .rebuild_header = inet_sk_rebuild_header, | 1220 | .rebuild_header = inet_sk_rebuild_header, |
@@ -1392,7 +1224,7 @@ struct tcp_func ipv4_specific = { | |||
1392 | .net_header_len = sizeof(struct iphdr), | 1224 | .net_header_len = sizeof(struct iphdr), |
1393 | .setsockopt = ip_setsockopt, | 1225 | .setsockopt = ip_setsockopt, |
1394 | .getsockopt = ip_getsockopt, | 1226 | .getsockopt = ip_getsockopt, |
1395 | .addr2sockaddr = v4_addr2sockaddr, | 1227 | .addr2sockaddr = inet_csk_addr2sockaddr, |
1396 | .sockaddr_len = sizeof(struct sockaddr_in), | 1228 | .sockaddr_len = sizeof(struct sockaddr_in), |
1397 | }; | 1229 | }; |
1398 | 1230 | ||
@@ -1433,7 +1265,8 @@ static int tcp_v4_init_sock(struct sock *sk) | |||
1433 | sk->sk_write_space = sk_stream_write_space; | 1265 | sk->sk_write_space = sk_stream_write_space; |
1434 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); | 1266 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); |
1435 | 1267 | ||
1436 | tp->af_specific = &ipv4_specific; | 1268 | icsk->icsk_af_ops = &ipv4_specific; |
1269 | icsk->icsk_sync_mss = tcp_sync_mss; | ||
1437 | 1270 | ||
1438 | sk->sk_sndbuf = sysctl_tcp_wmem[1]; | 1271 | sk->sk_sndbuf = sysctl_tcp_wmem[1]; |
1439 | sk->sk_rcvbuf = sysctl_tcp_rmem[1]; | 1272 | sk->sk_rcvbuf = sysctl_tcp_rmem[1]; |
@@ -1989,7 +1822,7 @@ struct proto tcp_prot = { | |||
1989 | .sysctl_rmem = sysctl_tcp_rmem, | 1822 | .sysctl_rmem = sysctl_tcp_rmem, |
1990 | .max_header = MAX_TCP_HEADER, | 1823 | .max_header = MAX_TCP_HEADER, |
1991 | .obj_size = sizeof(struct tcp_sock), | 1824 | .obj_size = sizeof(struct tcp_sock), |
1992 | .twsk_obj_size = sizeof(struct tcp_timewait_sock), | 1825 | .twsk_prot = &tcp_timewait_sock_ops, |
1993 | .rsk_prot = &tcp_request_sock_ops, | 1826 | .rsk_prot = &tcp_request_sock_ops, |
1994 | }; | 1827 | }; |
1995 | 1828 | ||
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 1b66a2ac4321..2b9b7f6c7f7c 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -274,18 +274,18 @@ kill: | |||
274 | void tcp_time_wait(struct sock *sk, int state, int timeo) | 274 | void tcp_time_wait(struct sock *sk, int state, int timeo) |
275 | { | 275 | { |
276 | struct inet_timewait_sock *tw = NULL; | 276 | struct inet_timewait_sock *tw = NULL; |
277 | const struct inet_connection_sock *icsk = inet_csk(sk); | ||
277 | const struct tcp_sock *tp = tcp_sk(sk); | 278 | const struct tcp_sock *tp = tcp_sk(sk); |
278 | int recycle_ok = 0; | 279 | int recycle_ok = 0; |
279 | 280 | ||
280 | if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp) | 281 | if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp) |
281 | recycle_ok = tp->af_specific->remember_stamp(sk); | 282 | recycle_ok = icsk->icsk_af_ops->remember_stamp(sk); |
282 | 283 | ||
283 | if (tcp_death_row.tw_count < tcp_death_row.sysctl_max_tw_buckets) | 284 | if (tcp_death_row.tw_count < tcp_death_row.sysctl_max_tw_buckets) |
284 | tw = inet_twsk_alloc(sk, state); | 285 | tw = inet_twsk_alloc(sk, state); |
285 | 286 | ||
286 | if (tw != NULL) { | 287 | if (tw != NULL) { |
287 | struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); | 288 | struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); |
288 | const struct inet_connection_sock *icsk = inet_csk(sk); | ||
289 | const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1); | 289 | const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1); |
290 | 290 | ||
291 | tw->tw_rcv_wscale = tp->rx_opt.rcv_wscale; | 291 | tw->tw_rcv_wscale = tp->rx_opt.rcv_wscale; |
@@ -298,10 +298,12 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) | |||
298 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 298 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
299 | if (tw->tw_family == PF_INET6) { | 299 | if (tw->tw_family == PF_INET6) { |
300 | struct ipv6_pinfo *np = inet6_sk(sk); | 300 | struct ipv6_pinfo *np = inet6_sk(sk); |
301 | struct tcp6_timewait_sock *tcp6tw = tcp6_twsk((struct sock *)tw); | 301 | struct inet6_timewait_sock *tw6; |
302 | 302 | ||
303 | ipv6_addr_copy(&tcp6tw->tw_v6_daddr, &np->daddr); | 303 | tw->tw_ipv6_offset = inet6_tw_offset(sk->sk_prot); |
304 | ipv6_addr_copy(&tcp6tw->tw_v6_rcv_saddr, &np->rcv_saddr); | 304 | tw6 = inet6_twsk((struct sock *)tw); |
305 | ipv6_addr_copy(&tw6->tw_v6_daddr, &np->daddr); | ||
306 | ipv6_addr_copy(&tw6->tw_v6_rcv_saddr, &np->rcv_saddr); | ||
305 | tw->tw_ipv6only = np->ipv6only; | 307 | tw->tw_ipv6only = np->ipv6only; |
306 | } | 308 | } |
307 | #endif | 309 | #endif |
@@ -456,7 +458,6 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb, | |||
456 | struct request_sock **prev) | 458 | struct request_sock **prev) |
457 | { | 459 | { |
458 | struct tcphdr *th = skb->h.th; | 460 | struct tcphdr *th = skb->h.th; |
459 | struct tcp_sock *tp = tcp_sk(sk); | ||
460 | u32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); | 461 | u32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); |
461 | int paws_reject = 0; | 462 | int paws_reject = 0; |
462 | struct tcp_options_received tmp_opt; | 463 | struct tcp_options_received tmp_opt; |
@@ -613,7 +614,8 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb, | |||
613 | * ESTABLISHED STATE. If it will be dropped after | 614 | * ESTABLISHED STATE. If it will be dropped after |
614 | * socket is created, wait for troubles. | 615 | * socket is created, wait for troubles. |
615 | */ | 616 | */ |
616 | child = tp->af_specific->syn_recv_sock(sk, skb, req, NULL); | 617 | child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, |
618 | req, NULL); | ||
617 | if (child == NULL) | 619 | if (child == NULL) |
618 | goto listen_overflow; | 620 | goto listen_overflow; |
619 | 621 | ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index b7325e0b406a..a7623ead39a8 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -51,8 +51,8 @@ int sysctl_tcp_retrans_collapse = 1; | |||
51 | */ | 51 | */ |
52 | int sysctl_tcp_tso_win_divisor = 3; | 52 | int sysctl_tcp_tso_win_divisor = 3; |
53 | 53 | ||
54 | static inline void update_send_head(struct sock *sk, struct tcp_sock *tp, | 54 | static void update_send_head(struct sock *sk, struct tcp_sock *tp, |
55 | struct sk_buff *skb) | 55 | struct sk_buff *skb) |
56 | { | 56 | { |
57 | sk->sk_send_head = skb->next; | 57 | sk->sk_send_head = skb->next; |
58 | if (sk->sk_send_head == (struct sk_buff *)&sk->sk_write_queue) | 58 | if (sk->sk_send_head == (struct sk_buff *)&sk->sk_write_queue) |
@@ -124,8 +124,8 @@ static void tcp_cwnd_restart(struct sock *sk, struct dst_entry *dst) | |||
124 | tp->snd_cwnd_used = 0; | 124 | tp->snd_cwnd_used = 0; |
125 | } | 125 | } |
126 | 126 | ||
127 | static inline void tcp_event_data_sent(struct tcp_sock *tp, | 127 | static void tcp_event_data_sent(struct tcp_sock *tp, |
128 | struct sk_buff *skb, struct sock *sk) | 128 | struct sk_buff *skb, struct sock *sk) |
129 | { | 129 | { |
130 | struct inet_connection_sock *icsk = inet_csk(sk); | 130 | struct inet_connection_sock *icsk = inet_csk(sk); |
131 | const u32 now = tcp_time_stamp; | 131 | const u32 now = tcp_time_stamp; |
@@ -142,7 +142,7 @@ static inline void tcp_event_data_sent(struct tcp_sock *tp, | |||
142 | icsk->icsk_ack.pingpong = 1; | 142 | icsk->icsk_ack.pingpong = 1; |
143 | } | 143 | } |
144 | 144 | ||
145 | static __inline__ void tcp_event_ack_sent(struct sock *sk, unsigned int pkts) | 145 | static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts) |
146 | { | 146 | { |
147 | tcp_dec_quickack_mode(sk, pkts); | 147 | tcp_dec_quickack_mode(sk, pkts); |
148 | inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); | 148 | inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); |
@@ -212,7 +212,7 @@ void tcp_select_initial_window(int __space, __u32 mss, | |||
212 | * value can be stuffed directly into th->window for an outgoing | 212 | * value can be stuffed directly into th->window for an outgoing |
213 | * frame. | 213 | * frame. |
214 | */ | 214 | */ |
215 | static __inline__ u16 tcp_select_window(struct sock *sk) | 215 | static u16 tcp_select_window(struct sock *sk) |
216 | { | 216 | { |
217 | struct tcp_sock *tp = tcp_sk(sk); | 217 | struct tcp_sock *tp = tcp_sk(sk); |
218 | u32 cur_win = tcp_receive_window(tp); | 218 | u32 cur_win = tcp_receive_window(tp); |
@@ -250,6 +250,75 @@ static __inline__ u16 tcp_select_window(struct sock *sk) | |||
250 | return new_win; | 250 | return new_win; |
251 | } | 251 | } |
252 | 252 | ||
253 | static void tcp_build_and_update_options(__u32 *ptr, struct tcp_sock *tp, | ||
254 | __u32 tstamp) | ||
255 | { | ||
256 | if (tp->rx_opt.tstamp_ok) { | ||
257 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | | ||
258 | (TCPOPT_NOP << 16) | | ||
259 | (TCPOPT_TIMESTAMP << 8) | | ||
260 | TCPOLEN_TIMESTAMP); | ||
261 | *ptr++ = htonl(tstamp); | ||
262 | *ptr++ = htonl(tp->rx_opt.ts_recent); | ||
263 | } | ||
264 | if (tp->rx_opt.eff_sacks) { | ||
265 | struct tcp_sack_block *sp = tp->rx_opt.dsack ? tp->duplicate_sack : tp->selective_acks; | ||
266 | int this_sack; | ||
267 | |||
268 | *ptr++ = htonl((TCPOPT_NOP << 24) | | ||
269 | (TCPOPT_NOP << 16) | | ||
270 | (TCPOPT_SACK << 8) | | ||
271 | (TCPOLEN_SACK_BASE + (tp->rx_opt.eff_sacks * | ||
272 | TCPOLEN_SACK_PERBLOCK))); | ||
273 | for(this_sack = 0; this_sack < tp->rx_opt.eff_sacks; this_sack++) { | ||
274 | *ptr++ = htonl(sp[this_sack].start_seq); | ||
275 | *ptr++ = htonl(sp[this_sack].end_seq); | ||
276 | } | ||
277 | if (tp->rx_opt.dsack) { | ||
278 | tp->rx_opt.dsack = 0; | ||
279 | tp->rx_opt.eff_sacks--; | ||
280 | } | ||
281 | } | ||
282 | } | ||
283 | |||
284 | /* Construct a tcp options header for a SYN or SYN_ACK packet. | ||
285 | * If this is every changed make sure to change the definition of | ||
286 | * MAX_SYN_SIZE to match the new maximum number of options that you | ||
287 | * can generate. | ||
288 | */ | ||
289 | static void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack, | ||
290 | int offer_wscale, int wscale, __u32 tstamp, | ||
291 | __u32 ts_recent) | ||
292 | { | ||
293 | /* We always get an MSS option. | ||
294 | * The option bytes which will be seen in normal data | ||
295 | * packets should timestamps be used, must be in the MSS | ||
296 | * advertised. But we subtract them from tp->mss_cache so | ||
297 | * that calculations in tcp_sendmsg are simpler etc. | ||
298 | * So account for this fact here if necessary. If we | ||
299 | * don't do this correctly, as a receiver we won't | ||
300 | * recognize data packets as being full sized when we | ||
301 | * should, and thus we won't abide by the delayed ACK | ||
302 | * rules correctly. | ||
303 | * SACKs don't matter, we never delay an ACK when we | ||
304 | * have any of those going out. | ||
305 | */ | ||
306 | *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss); | ||
307 | if (ts) { | ||
308 | if(sack) | ||
309 | *ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) | | ||
310 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); | ||
311 | else | ||
312 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | | ||
313 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); | ||
314 | *ptr++ = htonl(tstamp); /* TSVAL */ | ||
315 | *ptr++ = htonl(ts_recent); /* TSECR */ | ||
316 | } else if(sack) | ||
317 | *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | | ||
318 | (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM); | ||
319 | if (offer_wscale) | ||
320 | *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale)); | ||
321 | } | ||
253 | 322 | ||
254 | /* This routine actually transmits TCP packets queued in by | 323 | /* This routine actually transmits TCP packets queued in by |
255 | * tcp_do_sendmsg(). This is used by both the initial | 324 | * tcp_do_sendmsg(). This is used by both the initial |
@@ -371,7 +440,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
371 | TCP_ECN_send(sk, tp, skb, tcp_header_size); | 440 | TCP_ECN_send(sk, tp, skb, tcp_header_size); |
372 | } | 441 | } |
373 | 442 | ||
374 | tp->af_specific->send_check(sk, th, skb->len, skb); | 443 | icsk->icsk_af_ops->send_check(sk, skb->len, skb); |
375 | 444 | ||
376 | if (likely(tcb->flags & TCPCB_FLAG_ACK)) | 445 | if (likely(tcb->flags & TCPCB_FLAG_ACK)) |
377 | tcp_event_ack_sent(sk, tcp_skb_pcount(skb)); | 446 | tcp_event_ack_sent(sk, tcp_skb_pcount(skb)); |
@@ -381,7 +450,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
381 | 450 | ||
382 | TCP_INC_STATS(TCP_MIB_OUTSEGS); | 451 | TCP_INC_STATS(TCP_MIB_OUTSEGS); |
383 | 452 | ||
384 | err = tp->af_specific->queue_xmit(skb, 0); | 453 | err = icsk->icsk_af_ops->queue_xmit(skb, 0); |
385 | if (unlikely(err <= 0)) | 454 | if (unlikely(err <= 0)) |
386 | return err; | 455 | return err; |
387 | 456 | ||
@@ -621,7 +690,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) | |||
621 | It is minimum of user_mss and mss received with SYN. | 690 | It is minimum of user_mss and mss received with SYN. |
622 | It also does not include TCP options. | 691 | It also does not include TCP options. |
623 | 692 | ||
624 | tp->pmtu_cookie is last pmtu, seen by this function. | 693 | inet_csk(sk)->icsk_pmtu_cookie is last pmtu, seen by this function. |
625 | 694 | ||
626 | tp->mss_cache is current effective sending mss, including | 695 | tp->mss_cache is current effective sending mss, including |
627 | all tcp options except for SACKs. It is evaluated, | 696 | all tcp options except for SACKs. It is evaluated, |
@@ -631,26 +700,26 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) | |||
631 | NOTE1. rfc1122 clearly states that advertised MSS | 700 | NOTE1. rfc1122 clearly states that advertised MSS |
632 | DOES NOT include either tcp or ip options. | 701 | DOES NOT include either tcp or ip options. |
633 | 702 | ||
634 | NOTE2. tp->pmtu_cookie and tp->mss_cache are READ ONLY outside | 703 | NOTE2. inet_csk(sk)->icsk_pmtu_cookie and tp->mss_cache |
635 | this function. --ANK (980731) | 704 | are READ ONLY outside this function. --ANK (980731) |
636 | */ | 705 | */ |
637 | 706 | ||
638 | unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu) | 707 | unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu) |
639 | { | 708 | { |
640 | struct tcp_sock *tp = tcp_sk(sk); | 709 | struct tcp_sock *tp = tcp_sk(sk); |
641 | int mss_now; | 710 | struct inet_connection_sock *icsk = inet_csk(sk); |
642 | |||
643 | /* Calculate base mss without TCP options: | 711 | /* Calculate base mss without TCP options: |
644 | It is MMS_S - sizeof(tcphdr) of rfc1122 | 712 | It is MMS_S - sizeof(tcphdr) of rfc1122 |
645 | */ | 713 | */ |
646 | mss_now = pmtu - tp->af_specific->net_header_len - sizeof(struct tcphdr); | 714 | int mss_now = (pmtu - icsk->icsk_af_ops->net_header_len - |
715 | sizeof(struct tcphdr)); | ||
647 | 716 | ||
648 | /* Clamp it (mss_clamp does not include tcp options) */ | 717 | /* Clamp it (mss_clamp does not include tcp options) */ |
649 | if (mss_now > tp->rx_opt.mss_clamp) | 718 | if (mss_now > tp->rx_opt.mss_clamp) |
650 | mss_now = tp->rx_opt.mss_clamp; | 719 | mss_now = tp->rx_opt.mss_clamp; |
651 | 720 | ||
652 | /* Now subtract optional transport overhead */ | 721 | /* Now subtract optional transport overhead */ |
653 | mss_now -= tp->ext_header_len; | 722 | mss_now -= icsk->icsk_ext_hdr_len; |
654 | 723 | ||
655 | /* Then reserve room for full set of TCP options and 8 bytes of data */ | 724 | /* Then reserve room for full set of TCP options and 8 bytes of data */ |
656 | if (mss_now < 48) | 725 | if (mss_now < 48) |
@@ -664,7 +733,7 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu) | |||
664 | mss_now = max((tp->max_window>>1), 68U - tp->tcp_header_len); | 733 | mss_now = max((tp->max_window>>1), 68U - tp->tcp_header_len); |
665 | 734 | ||
666 | /* And store cached results */ | 735 | /* And store cached results */ |
667 | tp->pmtu_cookie = pmtu; | 736 | icsk->icsk_pmtu_cookie = pmtu; |
668 | tp->mss_cache = mss_now; | 737 | tp->mss_cache = mss_now; |
669 | 738 | ||
670 | return mss_now; | 739 | return mss_now; |
@@ -694,7 +763,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed) | |||
694 | 763 | ||
695 | if (dst) { | 764 | if (dst) { |
696 | u32 mtu = dst_mtu(dst); | 765 | u32 mtu = dst_mtu(dst); |
697 | if (mtu != tp->pmtu_cookie) | 766 | if (mtu != inet_csk(sk)->icsk_pmtu_cookie) |
698 | mss_now = tcp_sync_mss(sk, mtu); | 767 | mss_now = tcp_sync_mss(sk, mtu); |
699 | } | 768 | } |
700 | 769 | ||
@@ -705,9 +774,10 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed) | |||
705 | xmit_size_goal = mss_now; | 774 | xmit_size_goal = mss_now; |
706 | 775 | ||
707 | if (doing_tso) { | 776 | if (doing_tso) { |
708 | xmit_size_goal = 65535 - | 777 | xmit_size_goal = (65535 - |
709 | tp->af_specific->net_header_len - | 778 | inet_csk(sk)->icsk_af_ops->net_header_len - |
710 | tp->ext_header_len - tp->tcp_header_len; | 779 | inet_csk(sk)->icsk_ext_hdr_len - |
780 | tp->tcp_header_len); | ||
711 | 781 | ||
712 | if (tp->max_window && | 782 | if (tp->max_window && |
713 | (xmit_size_goal > (tp->max_window >> 1))) | 783 | (xmit_size_goal > (tp->max_window >> 1))) |
@@ -723,7 +793,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed) | |||
723 | 793 | ||
724 | /* Congestion window validation. (RFC2861) */ | 794 | /* Congestion window validation. (RFC2861) */ |
725 | 795 | ||
726 | static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp) | 796 | static void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp) |
727 | { | 797 | { |
728 | __u32 packets_out = tp->packets_out; | 798 | __u32 packets_out = tp->packets_out; |
729 | 799 | ||
@@ -772,7 +842,7 @@ static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp, struct sk_buff *sk | |||
772 | /* This must be invoked the first time we consider transmitting | 842 | /* This must be invoked the first time we consider transmitting |
773 | * SKB onto the wire. | 843 | * SKB onto the wire. |
774 | */ | 844 | */ |
775 | static inline int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned int mss_now) | 845 | static int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned int mss_now) |
776 | { | 846 | { |
777 | int tso_segs = tcp_skb_pcount(skb); | 847 | int tso_segs = tcp_skb_pcount(skb); |
778 | 848 | ||
@@ -1422,7 +1492,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
1422 | (sysctl_tcp_retrans_collapse != 0)) | 1492 | (sysctl_tcp_retrans_collapse != 0)) |
1423 | tcp_retrans_try_collapse(sk, skb, cur_mss); | 1493 | tcp_retrans_try_collapse(sk, skb, cur_mss); |
1424 | 1494 | ||
1425 | if(tp->af_specific->rebuild_header(sk)) | 1495 | if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk)) |
1426 | return -EHOSTUNREACH; /* Routing failure or similar. */ | 1496 | return -EHOSTUNREACH; /* Routing failure or similar. */ |
1427 | 1497 | ||
1428 | /* Some Solaris stacks overoptimize and ignore the FIN on a | 1498 | /* Some Solaris stacks overoptimize and ignore the FIN on a |
@@ -1793,7 +1863,7 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
1793 | /* | 1863 | /* |
1794 | * Do all connect socket setups that can be done AF independent. | 1864 | * Do all connect socket setups that can be done AF independent. |
1795 | */ | 1865 | */ |
1796 | static inline void tcp_connect_init(struct sock *sk) | 1866 | static void tcp_connect_init(struct sock *sk) |
1797 | { | 1867 | { |
1798 | struct dst_entry *dst = __sk_dst_get(sk); | 1868 | struct dst_entry *dst = __sk_dst_get(sk); |
1799 | struct tcp_sock *tp = tcp_sk(sk); | 1869 | struct tcp_sock *tp = tcp_sk(sk); |
diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c index 13e7e6e8df16..3b7403495052 100644 --- a/net/ipv4/tcp_vegas.c +++ b/net/ipv4/tcp_vegas.c | |||
@@ -330,6 +330,10 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, | |||
330 | vegas->cntRTT = 0; | 330 | vegas->cntRTT = 0; |
331 | vegas->minRTT = 0x7fffffff; | 331 | vegas->minRTT = 0x7fffffff; |
332 | } | 332 | } |
333 | /* Use normal slow start */ | ||
334 | else if (tp->snd_cwnd <= tp->snd_ssthresh) | ||
335 | tcp_slow_start(tp); | ||
336 | |||
333 | } | 337 | } |
334 | 338 | ||
335 | /* Extract info for Tcp socket info provided via netlink. */ | 339 | /* Extract info for Tcp socket info provided via netlink. */ |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 2422a5f7195d..223abaa72bc5 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -86,6 +86,7 @@ | |||
86 | #include <linux/module.h> | 86 | #include <linux/module.h> |
87 | #include <linux/socket.h> | 87 | #include <linux/socket.h> |
88 | #include <linux/sockios.h> | 88 | #include <linux/sockios.h> |
89 | #include <linux/igmp.h> | ||
89 | #include <linux/in.h> | 90 | #include <linux/in.h> |
90 | #include <linux/errno.h> | 91 | #include <linux/errno.h> |
91 | #include <linux/timer.h> | 92 | #include <linux/timer.h> |
@@ -846,20 +847,7 @@ out: | |||
846 | csum_copy_err: | 847 | csum_copy_err: |
847 | UDP_INC_STATS_BH(UDP_MIB_INERRORS); | 848 | UDP_INC_STATS_BH(UDP_MIB_INERRORS); |
848 | 849 | ||
849 | /* Clear queue. */ | 850 | skb_kill_datagram(sk, skb, flags); |
850 | if (flags&MSG_PEEK) { | ||
851 | int clear = 0; | ||
852 | spin_lock_bh(&sk->sk_receive_queue.lock); | ||
853 | if (skb == skb_peek(&sk->sk_receive_queue)) { | ||
854 | __skb_unlink(skb, &sk->sk_receive_queue); | ||
855 | clear = 1; | ||
856 | } | ||
857 | spin_unlock_bh(&sk->sk_receive_queue.lock); | ||
858 | if (clear) | ||
859 | kfree_skb(skb); | ||
860 | } | ||
861 | |||
862 | skb_free_datagram(sk, skb); | ||
863 | 851 | ||
864 | if (noblock) | 852 | if (noblock) |
865 | return -EAGAIN; | 853 | return -EAGAIN; |
@@ -1094,7 +1082,7 @@ static int udp_v4_mcast_deliver(struct sk_buff *skb, struct udphdr *uh, | |||
1094 | * Otherwise, csum completion requires chacksumming packet body, | 1082 | * Otherwise, csum completion requires chacksumming packet body, |
1095 | * including udp header and folding it to skb->csum. | 1083 | * including udp header and folding it to skb->csum. |
1096 | */ | 1084 | */ |
1097 | static int udp_checksum_init(struct sk_buff *skb, struct udphdr *uh, | 1085 | static void udp_checksum_init(struct sk_buff *skb, struct udphdr *uh, |
1098 | unsigned short ulen, u32 saddr, u32 daddr) | 1086 | unsigned short ulen, u32 saddr, u32 daddr) |
1099 | { | 1087 | { |
1100 | if (uh->check == 0) { | 1088 | if (uh->check == 0) { |
@@ -1108,7 +1096,6 @@ static int udp_checksum_init(struct sk_buff *skb, struct udphdr *uh, | |||
1108 | /* Probably, we should checksum udp header (it should be in cache | 1096 | /* Probably, we should checksum udp header (it should be in cache |
1109 | * in any case) and data in tiny packets (< rx copybreak). | 1097 | * in any case) and data in tiny packets (< rx copybreak). |
1110 | */ | 1098 | */ |
1111 | return 0; | ||
1112 | } | 1099 | } |
1113 | 1100 | ||
1114 | /* | 1101 | /* |
@@ -1141,8 +1128,7 @@ int udp_rcv(struct sk_buff *skb) | |||
1141 | if (pskb_trim_rcsum(skb, ulen)) | 1128 | if (pskb_trim_rcsum(skb, ulen)) |
1142 | goto short_packet; | 1129 | goto short_packet; |
1143 | 1130 | ||
1144 | if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0) | 1131 | udp_checksum_init(skb, uh, ulen, saddr, daddr); |
1145 | goto csum_error; | ||
1146 | 1132 | ||
1147 | if(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) | 1133 | if(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) |
1148 | return udp_v4_mcast_deliver(skb, uh, saddr, daddr); | 1134 | return udp_v4_mcast_deliver(skb, uh, saddr, daddr); |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index b2b60f3e9cdd..42196ba3b0b9 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -182,6 +182,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl) | |||
182 | case IPPROTO_UDP: | 182 | case IPPROTO_UDP: |
183 | case IPPROTO_TCP: | 183 | case IPPROTO_TCP: |
184 | case IPPROTO_SCTP: | 184 | case IPPROTO_SCTP: |
185 | case IPPROTO_DCCP: | ||
185 | if (pskb_may_pull(skb, xprth + 4 - skb->data)) { | 186 | if (pskb_may_pull(skb, xprth + 4 - skb->data)) { |
186 | u16 *ports = (u16 *)xprth; | 187 | u16 *ports = (u16 *)xprth; |
187 | 188 | ||
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile index 6460eec834b7..9601fd7f9d66 100644 --- a/net/ipv6/Makefile +++ b/net/ipv6/Makefile | |||
@@ -8,7 +8,8 @@ ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o sit.o \ | |||
8 | route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \ | 8 | route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \ |
9 | protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \ | 9 | protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \ |
10 | exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \ | 10 | exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \ |
11 | ip6_flowlabel.o ipv6_syms.o netfilter.o | 11 | ip6_flowlabel.o ipv6_syms.o netfilter.o \ |
12 | inet6_connection_sock.o | ||
12 | 13 | ||
13 | ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \ | 14 | ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \ |
14 | xfrm6_output.o | 15 | xfrm6_output.o |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 73a23b4130a5..704fb73e6c5f 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -137,6 +137,7 @@ static int addrconf_ifdown(struct net_device *dev, int how); | |||
137 | static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags); | 137 | static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags); |
138 | static void addrconf_dad_timer(unsigned long data); | 138 | static void addrconf_dad_timer(unsigned long data); |
139 | static void addrconf_dad_completed(struct inet6_ifaddr *ifp); | 139 | static void addrconf_dad_completed(struct inet6_ifaddr *ifp); |
140 | static void addrconf_dad_run(struct inet6_dev *idev); | ||
140 | static void addrconf_rs_timer(unsigned long data); | 141 | static void addrconf_rs_timer(unsigned long data); |
141 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa); | 142 | static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa); |
142 | static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa); | 143 | static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa); |
@@ -388,6 +389,9 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | |||
388 | } | 389 | } |
389 | #endif | 390 | #endif |
390 | 391 | ||
392 | if (netif_carrier_ok(dev)) | ||
393 | ndev->if_flags |= IF_READY; | ||
394 | |||
391 | write_lock_bh(&addrconf_lock); | 395 | write_lock_bh(&addrconf_lock); |
392 | dev->ip6_ptr = ndev; | 396 | dev->ip6_ptr = ndev; |
393 | write_unlock_bh(&addrconf_lock); | 397 | write_unlock_bh(&addrconf_lock); |
@@ -415,6 +419,7 @@ static struct inet6_dev * ipv6_find_idev(struct net_device *dev) | |||
415 | if ((idev = ipv6_add_dev(dev)) == NULL) | 419 | if ((idev = ipv6_add_dev(dev)) == NULL) |
416 | return NULL; | 420 | return NULL; |
417 | } | 421 | } |
422 | |||
418 | if (dev->flags&IFF_UP) | 423 | if (dev->flags&IFF_UP) |
419 | ipv6_mc_up(idev); | 424 | ipv6_mc_up(idev); |
420 | return idev; | 425 | return idev; |
@@ -634,8 +639,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
634 | } | 639 | } |
635 | #endif | 640 | #endif |
636 | 641 | ||
637 | for (ifap = &idev->addr_list; (ifa=*ifap) != NULL; | 642 | for (ifap = &idev->addr_list; (ifa=*ifap) != NULL;) { |
638 | ifap = &ifa->if_next) { | ||
639 | if (ifa == ifp) { | 643 | if (ifa == ifp) { |
640 | *ifap = ifa->if_next; | 644 | *ifap = ifa->if_next; |
641 | __in6_ifa_put(ifp); | 645 | __in6_ifa_put(ifp); |
@@ -643,6 +647,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
643 | if (!(ifp->flags & IFA_F_PERMANENT) || onlink > 0) | 647 | if (!(ifp->flags & IFA_F_PERMANENT) || onlink > 0) |
644 | break; | 648 | break; |
645 | deleted = 1; | 649 | deleted = 1; |
650 | continue; | ||
646 | } else if (ifp->flags & IFA_F_PERMANENT) { | 651 | } else if (ifp->flags & IFA_F_PERMANENT) { |
647 | if (ipv6_prefix_equal(&ifa->addr, &ifp->addr, | 652 | if (ipv6_prefix_equal(&ifa->addr, &ifp->addr, |
648 | ifp->prefix_len)) { | 653 | ifp->prefix_len)) { |
@@ -666,6 +671,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
666 | } | 671 | } |
667 | } | 672 | } |
668 | } | 673 | } |
674 | ifap = &ifa->if_next; | ||
669 | } | 675 | } |
670 | write_unlock_bh(&idev->lock); | 676 | write_unlock_bh(&idev->lock); |
671 | 677 | ||
@@ -903,11 +909,18 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
903 | 909 | ||
904 | score.addr_type = __ipv6_addr_type(&ifa->addr); | 910 | score.addr_type = __ipv6_addr_type(&ifa->addr); |
905 | 911 | ||
906 | /* Rule 0: Candidate Source Address (section 4) | 912 | /* Rule 0: |
913 | * - Tentative Address (RFC2462 section 5.4) | ||
914 | * - A tentative address is not considered | ||
915 | * "assigned to an interface" in the traditional | ||
916 | * sense. | ||
917 | * - Candidate Source Address (section 4) | ||
907 | * - In any case, anycast addresses, multicast | 918 | * - In any case, anycast addresses, multicast |
908 | * addresses, and the unspecified address MUST | 919 | * addresses, and the unspecified address MUST |
909 | * NOT be included in a candidate set. | 920 | * NOT be included in a candidate set. |
910 | */ | 921 | */ |
922 | if (ifa->flags & IFA_F_TENTATIVE) | ||
923 | continue; | ||
911 | if (unlikely(score.addr_type == IPV6_ADDR_ANY || | 924 | if (unlikely(score.addr_type == IPV6_ADDR_ANY || |
912 | score.addr_type & IPV6_ADDR_MULTICAST)) { | 925 | score.addr_type & IPV6_ADDR_MULTICAST)) { |
913 | LIMIT_NETDEBUG(KERN_DEBUG | 926 | LIMIT_NETDEBUG(KERN_DEBUG |
@@ -1182,7 +1195,7 @@ struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, struct net_device * | |||
1182 | int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) | 1195 | int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) |
1183 | { | 1196 | { |
1184 | const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr; | 1197 | const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr; |
1185 | const struct in6_addr *sk2_rcv_saddr6 = tcp_v6_rcv_saddr(sk2); | 1198 | const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2); |
1186 | u32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr; | 1199 | u32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr; |
1187 | u32 sk2_rcv_saddr = inet_rcv_saddr(sk2); | 1200 | u32 sk2_rcv_saddr = inet_rcv_saddr(sk2); |
1188 | int sk_ipv6only = ipv6_only_sock(sk); | 1201 | int sk_ipv6only = ipv6_only_sock(sk); |
@@ -1215,10 +1228,8 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) | |||
1215 | 1228 | ||
1216 | /* Gets referenced address, destroys ifaddr */ | 1229 | /* Gets referenced address, destroys ifaddr */ |
1217 | 1230 | ||
1218 | void addrconf_dad_failure(struct inet6_ifaddr *ifp) | 1231 | void addrconf_dad_stop(struct inet6_ifaddr *ifp) |
1219 | { | 1232 | { |
1220 | if (net_ratelimit()) | ||
1221 | printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name); | ||
1222 | if (ifp->flags&IFA_F_PERMANENT) { | 1233 | if (ifp->flags&IFA_F_PERMANENT) { |
1223 | spin_lock_bh(&ifp->lock); | 1234 | spin_lock_bh(&ifp->lock); |
1224 | addrconf_del_timer(ifp); | 1235 | addrconf_del_timer(ifp); |
@@ -1244,6 +1255,12 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp) | |||
1244 | ipv6_del_addr(ifp); | 1255 | ipv6_del_addr(ifp); |
1245 | } | 1256 | } |
1246 | 1257 | ||
1258 | void addrconf_dad_failure(struct inet6_ifaddr *ifp) | ||
1259 | { | ||
1260 | if (net_ratelimit()) | ||
1261 | printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name); | ||
1262 | addrconf_dad_stop(ifp); | ||
1263 | } | ||
1247 | 1264 | ||
1248 | /* Join to solicited addr multicast group. */ | 1265 | /* Join to solicited addr multicast group. */ |
1249 | 1266 | ||
@@ -1596,9 +1613,17 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1596 | not good. | 1613 | not good. |
1597 | */ | 1614 | */ |
1598 | if (valid_lft >= 0x7FFFFFFF/HZ) | 1615 | if (valid_lft >= 0x7FFFFFFF/HZ) |
1599 | rt_expires = 0; | 1616 | rt_expires = 0x7FFFFFFF - (0x7FFFFFFF % HZ); |
1600 | else | 1617 | else |
1601 | rt_expires = jiffies + valid_lft * HZ; | 1618 | rt_expires = valid_lft * HZ; |
1619 | |||
1620 | /* | ||
1621 | * We convert this (in jiffies) to clock_t later. | ||
1622 | * Avoid arithmetic overflow there as well. | ||
1623 | * Overflow can happen only if HZ < USER_HZ. | ||
1624 | */ | ||
1625 | if (HZ < USER_HZ && rt_expires > 0x7FFFFFFF / USER_HZ) | ||
1626 | rt_expires = 0x7FFFFFFF / USER_HZ; | ||
1602 | 1627 | ||
1603 | if (pinfo->onlink) { | 1628 | if (pinfo->onlink) { |
1604 | struct rt6_info *rt; | 1629 | struct rt6_info *rt; |
@@ -1610,12 +1635,12 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1610 | ip6_del_rt(rt, NULL, NULL, NULL); | 1635 | ip6_del_rt(rt, NULL, NULL, NULL); |
1611 | rt = NULL; | 1636 | rt = NULL; |
1612 | } else { | 1637 | } else { |
1613 | rt->rt6i_expires = rt_expires; | 1638 | rt->rt6i_expires = jiffies + rt_expires; |
1614 | } | 1639 | } |
1615 | } | 1640 | } |
1616 | } else if (valid_lft) { | 1641 | } else if (valid_lft) { |
1617 | addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len, | 1642 | addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len, |
1618 | dev, rt_expires, RTF_ADDRCONF|RTF_EXPIRES|RTF_PREFIX_RT); | 1643 | dev, jiffies_to_clock_t(rt_expires), RTF_ADDRCONF|RTF_EXPIRES|RTF_PREFIX_RT); |
1619 | } | 1644 | } |
1620 | if (rt) | 1645 | if (rt) |
1621 | dst_release(&rt->u.dst); | 1646 | dst_release(&rt->u.dst); |
@@ -2125,9 +2150,42 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2125 | { | 2150 | { |
2126 | struct net_device *dev = (struct net_device *) data; | 2151 | struct net_device *dev = (struct net_device *) data; |
2127 | struct inet6_dev *idev = __in6_dev_get(dev); | 2152 | struct inet6_dev *idev = __in6_dev_get(dev); |
2153 | int run_pending = 0; | ||
2128 | 2154 | ||
2129 | switch(event) { | 2155 | switch(event) { |
2130 | case NETDEV_UP: | 2156 | case NETDEV_UP: |
2157 | case NETDEV_CHANGE: | ||
2158 | if (event == NETDEV_UP) { | ||
2159 | if (!netif_carrier_ok(dev)) { | ||
2160 | /* device is not ready yet. */ | ||
2161 | printk(KERN_INFO | ||
2162 | "ADDRCONF(NETDEV_UP): %s: " | ||
2163 | "link is not ready\n", | ||
2164 | dev->name); | ||
2165 | break; | ||
2166 | } | ||
2167 | } else { | ||
2168 | if (!netif_carrier_ok(dev)) { | ||
2169 | /* device is still not ready. */ | ||
2170 | break; | ||
2171 | } | ||
2172 | |||
2173 | if (idev) { | ||
2174 | if (idev->if_flags & IF_READY) { | ||
2175 | /* device is already configured. */ | ||
2176 | break; | ||
2177 | } | ||
2178 | idev->if_flags |= IF_READY; | ||
2179 | } | ||
2180 | |||
2181 | printk(KERN_INFO | ||
2182 | "ADDRCONF(NETDEV_CHANGE): %s: " | ||
2183 | "link becomes ready\n", | ||
2184 | dev->name); | ||
2185 | |||
2186 | run_pending = 1; | ||
2187 | } | ||
2188 | |||
2131 | switch(dev->type) { | 2189 | switch(dev->type) { |
2132 | case ARPHRD_SIT: | 2190 | case ARPHRD_SIT: |
2133 | addrconf_sit_config(dev); | 2191 | addrconf_sit_config(dev); |
@@ -2144,6 +2202,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2144 | break; | 2202 | break; |
2145 | }; | 2203 | }; |
2146 | if (idev) { | 2204 | if (idev) { |
2205 | if (run_pending) | ||
2206 | addrconf_dad_run(idev); | ||
2207 | |||
2147 | /* If the MTU changed during the interface down, when the | 2208 | /* If the MTU changed during the interface down, when the |
2148 | interface up, the changed MTU must be reflected in the | 2209 | interface up, the changed MTU must be reflected in the |
2149 | idev as well as routers. | 2210 | idev as well as routers. |
@@ -2178,8 +2239,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2178 | */ | 2239 | */ |
2179 | addrconf_ifdown(dev, event != NETDEV_DOWN); | 2240 | addrconf_ifdown(dev, event != NETDEV_DOWN); |
2180 | break; | 2241 | break; |
2181 | case NETDEV_CHANGE: | 2242 | |
2182 | break; | ||
2183 | case NETDEV_CHANGENAME: | 2243 | case NETDEV_CHANGENAME: |
2184 | #ifdef CONFIG_SYSCTL | 2244 | #ifdef CONFIG_SYSCTL |
2185 | if (idev) { | 2245 | if (idev) { |
@@ -2260,7 +2320,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2260 | 2320 | ||
2261 | /* Step 3: clear flags for stateless addrconf */ | 2321 | /* Step 3: clear flags for stateless addrconf */ |
2262 | if (how != 1) | 2322 | if (how != 1) |
2263 | idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD); | 2323 | idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY); |
2264 | 2324 | ||
2265 | /* Step 4: clear address list */ | 2325 | /* Step 4: clear address list */ |
2266 | #ifdef CONFIG_IPV6_PRIVACY | 2326 | #ifdef CONFIG_IPV6_PRIVACY |
@@ -2369,11 +2429,20 @@ out: | |||
2369 | /* | 2429 | /* |
2370 | * Duplicate Address Detection | 2430 | * Duplicate Address Detection |
2371 | */ | 2431 | */ |
2432 | static void addrconf_dad_kick(struct inet6_ifaddr *ifp) | ||
2433 | { | ||
2434 | unsigned long rand_num; | ||
2435 | struct inet6_dev *idev = ifp->idev; | ||
2436 | |||
2437 | rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1); | ||
2438 | ifp->probes = idev->cnf.dad_transmits; | ||
2439 | addrconf_mod_timer(ifp, AC_DAD, rand_num); | ||
2440 | } | ||
2441 | |||
2372 | static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) | 2442 | static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) |
2373 | { | 2443 | { |
2374 | struct inet6_dev *idev = ifp->idev; | 2444 | struct inet6_dev *idev = ifp->idev; |
2375 | struct net_device *dev = idev->dev; | 2445 | struct net_device *dev = idev->dev; |
2376 | unsigned long rand_num; | ||
2377 | 2446 | ||
2378 | addrconf_join_solict(dev, &ifp->addr); | 2447 | addrconf_join_solict(dev, &ifp->addr); |
2379 | 2448 | ||
@@ -2382,7 +2451,6 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) | |||
2382 | flags); | 2451 | flags); |
2383 | 2452 | ||
2384 | net_srandom(ifp->addr.s6_addr32[3]); | 2453 | net_srandom(ifp->addr.s6_addr32[3]); |
2385 | rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1); | ||
2386 | 2454 | ||
2387 | read_lock_bh(&idev->lock); | 2455 | read_lock_bh(&idev->lock); |
2388 | if (ifp->dead) | 2456 | if (ifp->dead) |
@@ -2399,9 +2467,19 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) | |||
2399 | return; | 2467 | return; |
2400 | } | 2468 | } |
2401 | 2469 | ||
2402 | ifp->probes = idev->cnf.dad_transmits; | 2470 | if (!(idev->if_flags & IF_READY)) { |
2403 | addrconf_mod_timer(ifp, AC_DAD, rand_num); | 2471 | spin_unlock_bh(&ifp->lock); |
2404 | 2472 | read_unlock_bh(&idev->lock); | |
2473 | /* | ||
2474 | * If the defice is not ready: | ||
2475 | * - keep it tentative if it is a permanent address. | ||
2476 | * - otherwise, kill it. | ||
2477 | */ | ||
2478 | in6_ifa_hold(ifp); | ||
2479 | addrconf_dad_stop(ifp); | ||
2480 | return; | ||
2481 | } | ||
2482 | addrconf_dad_kick(ifp); | ||
2405 | spin_unlock_bh(&ifp->lock); | 2483 | spin_unlock_bh(&ifp->lock); |
2406 | out: | 2484 | out: |
2407 | read_unlock_bh(&idev->lock); | 2485 | read_unlock_bh(&idev->lock); |
@@ -2484,6 +2562,22 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp) | |||
2484 | } | 2562 | } |
2485 | } | 2563 | } |
2486 | 2564 | ||
2565 | static void addrconf_dad_run(struct inet6_dev *idev) { | ||
2566 | struct inet6_ifaddr *ifp; | ||
2567 | |||
2568 | read_lock_bh(&idev->lock); | ||
2569 | for (ifp = idev->addr_list; ifp; ifp = ifp->if_next) { | ||
2570 | spin_lock_bh(&ifp->lock); | ||
2571 | if (!(ifp->flags & IFA_F_TENTATIVE)) { | ||
2572 | spin_unlock_bh(&ifp->lock); | ||
2573 | continue; | ||
2574 | } | ||
2575 | spin_unlock_bh(&ifp->lock); | ||
2576 | addrconf_dad_kick(ifp); | ||
2577 | } | ||
2578 | read_unlock_bh(&idev->lock); | ||
2579 | } | ||
2580 | |||
2487 | #ifdef CONFIG_PROC_FS | 2581 | #ifdef CONFIG_PROC_FS |
2488 | struct if6_iter_state { | 2582 | struct if6_iter_state { |
2489 | int bucket; | 2583 | int bucket; |
@@ -2689,6 +2783,9 @@ restart: | |||
2689 | in6_ifa_hold(ifpub); | 2783 | in6_ifa_hold(ifpub); |
2690 | spin_unlock(&ifp->lock); | 2784 | spin_unlock(&ifp->lock); |
2691 | read_unlock(&addrconf_hash_lock); | 2785 | read_unlock(&addrconf_hash_lock); |
2786 | spin_lock(&ifpub->lock); | ||
2787 | ifpub->regen_count = 0; | ||
2788 | spin_unlock(&ifpub->lock); | ||
2692 | ipv6_create_tempaddr(ifpub, ifp); | 2789 | ipv6_create_tempaddr(ifpub, ifp); |
2693 | in6_ifa_put(ifpub); | 2790 | in6_ifa_put(ifpub); |
2694 | in6_ifa_put(ifp); | 2791 | in6_ifa_put(ifp); |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index d9546380fa04..68afc53be662 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -167,6 +167,7 @@ lookup_protocol: | |||
167 | sk->sk_reuse = 1; | 167 | sk->sk_reuse = 1; |
168 | 168 | ||
169 | inet = inet_sk(sk); | 169 | inet = inet_sk(sk); |
170 | inet->is_icsk = INET_PROTOSW_ICSK & answer_flags; | ||
170 | 171 | ||
171 | if (SOCK_RAW == sock->type) { | 172 | if (SOCK_RAW == sock->type) { |
172 | inet->num = protocol; | 173 | inet->num = protocol; |
@@ -389,6 +390,8 @@ int inet6_destroy_sock(struct sock *sk) | |||
389 | return 0; | 390 | return 0; |
390 | } | 391 | } |
391 | 392 | ||
393 | EXPORT_SYMBOL_GPL(inet6_destroy_sock); | ||
394 | |||
392 | /* | 395 | /* |
393 | * This does both peername and sockname. | 396 | * This does both peername and sockname. |
394 | */ | 397 | */ |
@@ -431,7 +434,6 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr, | |||
431 | int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | 434 | int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
432 | { | 435 | { |
433 | struct sock *sk = sock->sk; | 436 | struct sock *sk = sock->sk; |
434 | int err = -EINVAL; | ||
435 | 437 | ||
436 | switch(cmd) | 438 | switch(cmd) |
437 | { | 439 | { |
@@ -450,16 +452,15 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
450 | case SIOCSIFDSTADDR: | 452 | case SIOCSIFDSTADDR: |
451 | return addrconf_set_dstaddr((void __user *) arg); | 453 | return addrconf_set_dstaddr((void __user *) arg); |
452 | default: | 454 | default: |
453 | if (!sk->sk_prot->ioctl || | 455 | if (!sk->sk_prot->ioctl) |
454 | (err = sk->sk_prot->ioctl(sk, cmd, arg)) == -ENOIOCTLCMD) | 456 | return -ENOIOCTLCMD; |
455 | return(dev_ioctl(cmd,(void __user *) arg)); | 457 | return sk->sk_prot->ioctl(sk, cmd, arg); |
456 | return err; | ||
457 | } | 458 | } |
458 | /*NOTREACHED*/ | 459 | /*NOTREACHED*/ |
459 | return(0); | 460 | return(0); |
460 | } | 461 | } |
461 | 462 | ||
462 | struct proto_ops inet6_stream_ops = { | 463 | const struct proto_ops inet6_stream_ops = { |
463 | .family = PF_INET6, | 464 | .family = PF_INET6, |
464 | .owner = THIS_MODULE, | 465 | .owner = THIS_MODULE, |
465 | .release = inet6_release, | 466 | .release = inet6_release, |
@@ -480,7 +481,7 @@ struct proto_ops inet6_stream_ops = { | |||
480 | .sendpage = tcp_sendpage | 481 | .sendpage = tcp_sendpage |
481 | }; | 482 | }; |
482 | 483 | ||
483 | struct proto_ops inet6_dgram_ops = { | 484 | const struct proto_ops inet6_dgram_ops = { |
484 | .family = PF_INET6, | 485 | .family = PF_INET6, |
485 | .owner = THIS_MODULE, | 486 | .owner = THIS_MODULE, |
486 | .release = inet6_release, | 487 | .release = inet6_release, |
@@ -508,7 +509,7 @@ static struct net_proto_family inet6_family_ops = { | |||
508 | }; | 509 | }; |
509 | 510 | ||
510 | /* Same as inet6_dgram_ops, sans udp_poll. */ | 511 | /* Same as inet6_dgram_ops, sans udp_poll. */ |
511 | static struct proto_ops inet6_sockraw_ops = { | 512 | static const struct proto_ops inet6_sockraw_ops = { |
512 | .family = PF_INET6, | 513 | .family = PF_INET6, |
513 | .owner = THIS_MODULE, | 514 | .owner = THIS_MODULE, |
514 | .release = inet6_release, | 515 | .release = inet6_release, |
@@ -609,6 +610,79 @@ inet6_unregister_protosw(struct inet_protosw *p) | |||
609 | } | 610 | } |
610 | } | 611 | } |
611 | 612 | ||
613 | int inet6_sk_rebuild_header(struct sock *sk) | ||
614 | { | ||
615 | int err; | ||
616 | struct dst_entry *dst; | ||
617 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
618 | |||
619 | dst = __sk_dst_check(sk, np->dst_cookie); | ||
620 | |||
621 | if (dst == NULL) { | ||
622 | struct inet_sock *inet = inet_sk(sk); | ||
623 | struct in6_addr *final_p = NULL, final; | ||
624 | struct flowi fl; | ||
625 | |||
626 | memset(&fl, 0, sizeof(fl)); | ||
627 | fl.proto = sk->sk_protocol; | ||
628 | ipv6_addr_copy(&fl.fl6_dst, &np->daddr); | ||
629 | ipv6_addr_copy(&fl.fl6_src, &np->saddr); | ||
630 | fl.fl6_flowlabel = np->flow_label; | ||
631 | fl.oif = sk->sk_bound_dev_if; | ||
632 | fl.fl_ip_dport = inet->dport; | ||
633 | fl.fl_ip_sport = inet->sport; | ||
634 | |||
635 | if (np->opt && np->opt->srcrt) { | ||
636 | struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; | ||
637 | ipv6_addr_copy(&final, &fl.fl6_dst); | ||
638 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); | ||
639 | final_p = &final; | ||
640 | } | ||
641 | |||
642 | err = ip6_dst_lookup(sk, &dst, &fl); | ||
643 | if (err) { | ||
644 | sk->sk_route_caps = 0; | ||
645 | return err; | ||
646 | } | ||
647 | if (final_p) | ||
648 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
649 | |||
650 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | ||
651 | sk->sk_err_soft = -err; | ||
652 | return err; | ||
653 | } | ||
654 | |||
655 | ip6_dst_store(sk, dst, NULL); | ||
656 | sk->sk_route_caps = dst->dev->features & | ||
657 | ~(NETIF_F_IP_CSUM | NETIF_F_TSO); | ||
658 | } | ||
659 | |||
660 | return 0; | ||
661 | } | ||
662 | |||
663 | EXPORT_SYMBOL_GPL(inet6_sk_rebuild_header); | ||
664 | |||
665 | int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb) | ||
666 | { | ||
667 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
668 | struct inet6_skb_parm *opt = IP6CB(skb); | ||
669 | |||
670 | if (np->rxopt.all) { | ||
671 | if ((opt->hop && (np->rxopt.bits.hopopts || | ||
672 | np->rxopt.bits.ohopopts)) || | ||
673 | ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) && | ||
674 | np->rxopt.bits.rxflow) || | ||
675 | (opt->srcrt && (np->rxopt.bits.srcrt || | ||
676 | np->rxopt.bits.osrcrt)) || | ||
677 | ((opt->dst1 || opt->dst0) && | ||
678 | (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts))) | ||
679 | return 1; | ||
680 | } | ||
681 | return 0; | ||
682 | } | ||
683 | |||
684 | EXPORT_SYMBOL_GPL(ipv6_opt_accepted); | ||
685 | |||
612 | int | 686 | int |
613 | snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign) | 687 | snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign) |
614 | { | 688 | { |
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index f3629730eb15..13cc7f895583 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/string.h> | 33 | #include <linux/string.h> |
34 | #include <net/icmp.h> | 34 | #include <net/icmp.h> |
35 | #include <net/ipv6.h> | 35 | #include <net/ipv6.h> |
36 | #include <net/protocol.h> | ||
36 | #include <net/xfrm.h> | 37 | #include <net/xfrm.h> |
37 | #include <asm/scatterlist.h> | 38 | #include <asm/scatterlist.h> |
38 | 39 | ||
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 8bfbe9970793..6de8ee1a5ad9 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/random.h> | 36 | #include <linux/random.h> |
37 | #include <net/icmp.h> | 37 | #include <net/icmp.h> |
38 | #include <net/ipv6.h> | 38 | #include <net/ipv6.h> |
39 | #include <net/protocol.h> | ||
39 | #include <linux/icmpv6.h> | 40 | #include <linux/icmpv6.h> |
40 | 41 | ||
41 | static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) | 42 | static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index be6faf311387..113374dc342c 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -413,6 +413,8 @@ ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr) | |||
413 | return opt; | 413 | return opt; |
414 | } | 414 | } |
415 | 415 | ||
416 | EXPORT_SYMBOL_GPL(ipv6_invert_rthdr); | ||
417 | |||
416 | /********************************** | 418 | /********************************** |
417 | Hop-by-hop options. | 419 | Hop-by-hop options. |
418 | **********************************/ | 420 | **********************************/ |
@@ -579,6 +581,8 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt) | |||
579 | return opt2; | 581 | return opt2; |
580 | } | 582 | } |
581 | 583 | ||
584 | EXPORT_SYMBOL_GPL(ipv6_dup_options); | ||
585 | |||
582 | static int ipv6_renew_option(void *ohdr, | 586 | static int ipv6_renew_option(void *ohdr, |
583 | struct ipv6_opt_hdr __user *newopt, int newoptlen, | 587 | struct ipv6_opt_hdr __user *newopt, int newoptlen, |
584 | int inherit, | 588 | int inherit, |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 34a332225c17..6ec6a2b549bb 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -328,8 +328,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, | |||
328 | iif = skb->dev->ifindex; | 328 | iif = skb->dev->ifindex; |
329 | 329 | ||
330 | /* | 330 | /* |
331 | * Must not send if we know that source is Anycast also. | 331 | * Must not send error if the source does not uniquely |
332 | * for now we don't know that. | 332 | * identify a single node (RFC2463 Section 2.4). |
333 | * We check unspecified / multicast addresses here, | ||
334 | * and anycast addresses will be checked later. | ||
333 | */ | 335 | */ |
334 | if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) { | 336 | if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) { |
335 | LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n"); | 337 | LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n"); |
@@ -373,6 +375,16 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, | |||
373 | err = ip6_dst_lookup(sk, &dst, &fl); | 375 | err = ip6_dst_lookup(sk, &dst, &fl); |
374 | if (err) | 376 | if (err) |
375 | goto out; | 377 | goto out; |
378 | |||
379 | /* | ||
380 | * We won't send icmp if the destination is known | ||
381 | * anycast. | ||
382 | */ | ||
383 | if (((struct rt6_info *)dst)->rt6i_flags & RTF_ANYCAST) { | ||
384 | LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: acast source\n"); | ||
385 | goto out_dst_release; | ||
386 | } | ||
387 | |||
376 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) | 388 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) |
377 | goto out; | 389 | goto out; |
378 | 390 | ||
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c new file mode 100644 index 000000000000..792f90f0f9ec --- /dev/null +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -0,0 +1,199 @@ | |||
1 | /* | ||
2 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
3 | * operating system. INET is implemented using the BSD Socket | ||
4 | * interface as the means of communication with the user level. | ||
5 | * | ||
6 | * Support for INET6 connection oriented protocols. | ||
7 | * | ||
8 | * Authors: See the TCPv6 sources | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; either version | ||
13 | * 2 of the License, or(at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/config.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/in6.h> | ||
19 | #include <linux/ipv6.h> | ||
20 | #include <linux/jhash.h> | ||
21 | |||
22 | #include <net/addrconf.h> | ||
23 | #include <net/inet_connection_sock.h> | ||
24 | #include <net/inet_ecn.h> | ||
25 | #include <net/inet_hashtables.h> | ||
26 | #include <net/ip6_route.h> | ||
27 | #include <net/sock.h> | ||
28 | |||
29 | int inet6_csk_bind_conflict(const struct sock *sk, | ||
30 | const struct inet_bind_bucket *tb) | ||
31 | { | ||
32 | const struct sock *sk2; | ||
33 | const struct hlist_node *node; | ||
34 | |||
35 | /* We must walk the whole port owner list in this case. -DaveM */ | ||
36 | sk_for_each_bound(sk2, node, &tb->owners) { | ||
37 | if (sk != sk2 && | ||
38 | (!sk->sk_bound_dev_if || | ||
39 | !sk2->sk_bound_dev_if || | ||
40 | sk->sk_bound_dev_if == sk2->sk_bound_dev_if) && | ||
41 | (!sk->sk_reuse || !sk2->sk_reuse || | ||
42 | sk2->sk_state == TCP_LISTEN) && | ||
43 | ipv6_rcv_saddr_equal(sk, sk2)) | ||
44 | break; | ||
45 | } | ||
46 | |||
47 | return node != NULL; | ||
48 | } | ||
49 | |||
50 | EXPORT_SYMBOL_GPL(inet6_csk_bind_conflict); | ||
51 | |||
52 | /* | ||
53 | * request_sock (formerly open request) hash tables. | ||
54 | */ | ||
55 | static u32 inet6_synq_hash(const struct in6_addr *raddr, const u16 rport, | ||
56 | const u32 rnd, const u16 synq_hsize) | ||
57 | { | ||
58 | u32 a = raddr->s6_addr32[0]; | ||
59 | u32 b = raddr->s6_addr32[1]; | ||
60 | u32 c = raddr->s6_addr32[2]; | ||
61 | |||
62 | a += JHASH_GOLDEN_RATIO; | ||
63 | b += JHASH_GOLDEN_RATIO; | ||
64 | c += rnd; | ||
65 | __jhash_mix(a, b, c); | ||
66 | |||
67 | a += raddr->s6_addr32[3]; | ||
68 | b += (u32)rport; | ||
69 | __jhash_mix(a, b, c); | ||
70 | |||
71 | return c & (synq_hsize - 1); | ||
72 | } | ||
73 | |||
74 | struct request_sock *inet6_csk_search_req(const struct sock *sk, | ||
75 | struct request_sock ***prevp, | ||
76 | const __u16 rport, | ||
77 | const struct in6_addr *raddr, | ||
78 | const struct in6_addr *laddr, | ||
79 | const int iif) | ||
80 | { | ||
81 | const struct inet_connection_sock *icsk = inet_csk(sk); | ||
82 | struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt; | ||
83 | struct request_sock *req, **prev; | ||
84 | |||
85 | for (prev = &lopt->syn_table[inet6_synq_hash(raddr, rport, | ||
86 | lopt->hash_rnd, | ||
87 | lopt->nr_table_entries)]; | ||
88 | (req = *prev) != NULL; | ||
89 | prev = &req->dl_next) { | ||
90 | const struct inet6_request_sock *treq = inet6_rsk(req); | ||
91 | |||
92 | if (inet_rsk(req)->rmt_port == rport && | ||
93 | req->rsk_ops->family == AF_INET6 && | ||
94 | ipv6_addr_equal(&treq->rmt_addr, raddr) && | ||
95 | ipv6_addr_equal(&treq->loc_addr, laddr) && | ||
96 | (!treq->iif || treq->iif == iif)) { | ||
97 | BUG_TRAP(req->sk == NULL); | ||
98 | *prevp = prev; | ||
99 | return req; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | return NULL; | ||
104 | } | ||
105 | |||
106 | EXPORT_SYMBOL_GPL(inet6_csk_search_req); | ||
107 | |||
108 | void inet6_csk_reqsk_queue_hash_add(struct sock *sk, | ||
109 | struct request_sock *req, | ||
110 | const unsigned long timeout) | ||
111 | { | ||
112 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
113 | struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt; | ||
114 | const u32 h = inet6_synq_hash(&inet6_rsk(req)->rmt_addr, | ||
115 | inet_rsk(req)->rmt_port, | ||
116 | lopt->hash_rnd, lopt->nr_table_entries); | ||
117 | |||
118 | reqsk_queue_hash_req(&icsk->icsk_accept_queue, h, req, timeout); | ||
119 | inet_csk_reqsk_queue_added(sk, timeout); | ||
120 | } | ||
121 | |||
122 | EXPORT_SYMBOL_GPL(inet6_csk_reqsk_queue_hash_add); | ||
123 | |||
124 | void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr) | ||
125 | { | ||
126 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
127 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr; | ||
128 | |||
129 | sin6->sin6_family = AF_INET6; | ||
130 | ipv6_addr_copy(&sin6->sin6_addr, &np->daddr); | ||
131 | sin6->sin6_port = inet_sk(sk)->dport; | ||
132 | /* We do not store received flowlabel for TCP */ | ||
133 | sin6->sin6_flowinfo = 0; | ||
134 | sin6->sin6_scope_id = 0; | ||
135 | if (sk->sk_bound_dev_if && | ||
136 | ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) | ||
137 | sin6->sin6_scope_id = sk->sk_bound_dev_if; | ||
138 | } | ||
139 | |||
140 | EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr); | ||
141 | |||
142 | int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) | ||
143 | { | ||
144 | struct sock *sk = skb->sk; | ||
145 | struct inet_sock *inet = inet_sk(sk); | ||
146 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
147 | struct flowi fl; | ||
148 | struct dst_entry *dst; | ||
149 | struct in6_addr *final_p = NULL, final; | ||
150 | |||
151 | memset(&fl, 0, sizeof(fl)); | ||
152 | fl.proto = sk->sk_protocol; | ||
153 | ipv6_addr_copy(&fl.fl6_dst, &np->daddr); | ||
154 | ipv6_addr_copy(&fl.fl6_src, &np->saddr); | ||
155 | fl.fl6_flowlabel = np->flow_label; | ||
156 | IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel); | ||
157 | fl.oif = sk->sk_bound_dev_if; | ||
158 | fl.fl_ip_sport = inet->sport; | ||
159 | fl.fl_ip_dport = inet->dport; | ||
160 | |||
161 | if (np->opt && np->opt->srcrt) { | ||
162 | struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt; | ||
163 | ipv6_addr_copy(&final, &fl.fl6_dst); | ||
164 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); | ||
165 | final_p = &final; | ||
166 | } | ||
167 | |||
168 | dst = __sk_dst_check(sk, np->dst_cookie); | ||
169 | |||
170 | if (dst == NULL) { | ||
171 | int err = ip6_dst_lookup(sk, &dst, &fl); | ||
172 | |||
173 | if (err) { | ||
174 | sk->sk_err_soft = -err; | ||
175 | return err; | ||
176 | } | ||
177 | |||
178 | if (final_p) | ||
179 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
180 | |||
181 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | ||
182 | sk->sk_route_caps = 0; | ||
183 | return err; | ||
184 | } | ||
185 | |||
186 | ip6_dst_store(sk, dst, NULL); | ||
187 | sk->sk_route_caps = dst->dev->features & | ||
188 | ~(NETIF_F_IP_CSUM | NETIF_F_TSO); | ||
189 | } | ||
190 | |||
191 | skb->dst = dst_clone(dst); | ||
192 | |||
193 | /* Restore final destination back after routing done */ | ||
194 | ipv6_addr_copy(&fl.fl6_dst, &np->daddr); | ||
195 | |||
196 | return ip6_xmit(sk, skb, &fl, np->opt, 0); | ||
197 | } | ||
198 | |||
199 | EXPORT_SYMBOL_GPL(inet6_csk_xmit); | ||
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index 01d5f46d4e40..4154f3a8b6cf 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c | |||
@@ -5,7 +5,8 @@ | |||
5 | * | 5 | * |
6 | * Generic INET6 transport hashtables | 6 | * Generic INET6 transport hashtables |
7 | * | 7 | * |
8 | * Authors: Lotsa people, from code originally in tcp | 8 | * Authors: Lotsa people, from code originally in tcp, generalised here |
9 | * by Arnaldo Carvalho de Melo <acme@mandriva.com> | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
11 | * modify it under the terms of the GNU General Public License | 12 | * modify it under the terms of the GNU General Public License |
@@ -14,12 +15,13 @@ | |||
14 | */ | 15 | */ |
15 | 16 | ||
16 | #include <linux/config.h> | 17 | #include <linux/config.h> |
17 | |||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/random.h> | ||
19 | 20 | ||
20 | #include <net/inet_connection_sock.h> | 21 | #include <net/inet_connection_sock.h> |
21 | #include <net/inet_hashtables.h> | 22 | #include <net/inet_hashtables.h> |
22 | #include <net/inet6_hashtables.h> | 23 | #include <net/inet6_hashtables.h> |
24 | #include <net/ip.h> | ||
23 | 25 | ||
24 | struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo, | 26 | struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo, |
25 | const struct in6_addr *daddr, | 27 | const struct in6_addr *daddr, |
@@ -79,3 +81,180 @@ struct sock *inet6_lookup(struct inet_hashinfo *hashinfo, | |||
79 | } | 81 | } |
80 | 82 | ||
81 | EXPORT_SYMBOL_GPL(inet6_lookup); | 83 | EXPORT_SYMBOL_GPL(inet6_lookup); |
84 | |||
85 | static int __inet6_check_established(struct inet_timewait_death_row *death_row, | ||
86 | struct sock *sk, const __u16 lport, | ||
87 | struct inet_timewait_sock **twp) | ||
88 | { | ||
89 | struct inet_hashinfo *hinfo = death_row->hashinfo; | ||
90 | const struct inet_sock *inet = inet_sk(sk); | ||
91 | const struct ipv6_pinfo *np = inet6_sk(sk); | ||
92 | const struct in6_addr *daddr = &np->rcv_saddr; | ||
93 | const struct in6_addr *saddr = &np->daddr; | ||
94 | const int dif = sk->sk_bound_dev_if; | ||
95 | const u32 ports = INET_COMBINED_PORTS(inet->dport, lport); | ||
96 | const unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr, | ||
97 | inet->dport); | ||
98 | struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); | ||
99 | struct sock *sk2; | ||
100 | const struct hlist_node *node; | ||
101 | struct inet_timewait_sock *tw; | ||
102 | |||
103 | prefetch(head->chain.first); | ||
104 | write_lock(&head->lock); | ||
105 | |||
106 | /* Check TIME-WAIT sockets first. */ | ||
107 | sk_for_each(sk2, node, &(head + hinfo->ehash_size)->chain) { | ||
108 | const struct inet6_timewait_sock *tw6 = inet6_twsk(sk2); | ||
109 | |||
110 | tw = inet_twsk(sk2); | ||
111 | |||
112 | if(*((__u32 *)&(tw->tw_dport)) == ports && | ||
113 | sk2->sk_family == PF_INET6 && | ||
114 | ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) && | ||
115 | ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) && | ||
116 | sk2->sk_bound_dev_if == sk->sk_bound_dev_if) { | ||
117 | if (twsk_unique(sk, sk2, twp)) | ||
118 | goto unique; | ||
119 | else | ||
120 | goto not_unique; | ||
121 | } | ||
122 | } | ||
123 | tw = NULL; | ||
124 | |||
125 | /* And established part... */ | ||
126 | sk_for_each(sk2, node, &head->chain) { | ||
127 | if (INET6_MATCH(sk2, hash, saddr, daddr, ports, dif)) | ||
128 | goto not_unique; | ||
129 | } | ||
130 | |||
131 | unique: | ||
132 | BUG_TRAP(sk_unhashed(sk)); | ||
133 | __sk_add_node(sk, &head->chain); | ||
134 | sk->sk_hash = hash; | ||
135 | sock_prot_inc_use(sk->sk_prot); | ||
136 | write_unlock(&head->lock); | ||
137 | |||
138 | if (twp != NULL) { | ||
139 | *twp = tw; | ||
140 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); | ||
141 | } else if (tw != NULL) { | ||
142 | /* Silly. Should hash-dance instead... */ | ||
143 | inet_twsk_deschedule(tw, death_row); | ||
144 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); | ||
145 | |||
146 | inet_twsk_put(tw); | ||
147 | } | ||
148 | return 0; | ||
149 | |||
150 | not_unique: | ||
151 | write_unlock(&head->lock); | ||
152 | return -EADDRNOTAVAIL; | ||
153 | } | ||
154 | |||
155 | static inline u32 inet6_sk_port_offset(const struct sock *sk) | ||
156 | { | ||
157 | const struct inet_sock *inet = inet_sk(sk); | ||
158 | const struct ipv6_pinfo *np = inet6_sk(sk); | ||
159 | return secure_ipv6_port_ephemeral(np->rcv_saddr.s6_addr32, | ||
160 | np->daddr.s6_addr32, | ||
161 | inet->dport); | ||
162 | } | ||
163 | |||
164 | int inet6_hash_connect(struct inet_timewait_death_row *death_row, | ||
165 | struct sock *sk) | ||
166 | { | ||
167 | struct inet_hashinfo *hinfo = death_row->hashinfo; | ||
168 | const unsigned short snum = inet_sk(sk)->num; | ||
169 | struct inet_bind_hashbucket *head; | ||
170 | struct inet_bind_bucket *tb; | ||
171 | int ret; | ||
172 | |||
173 | if (snum == 0) { | ||
174 | const int low = sysctl_local_port_range[0]; | ||
175 | const int high = sysctl_local_port_range[1]; | ||
176 | const int range = high - low; | ||
177 | int i, port; | ||
178 | static u32 hint; | ||
179 | const u32 offset = hint + inet6_sk_port_offset(sk); | ||
180 | struct hlist_node *node; | ||
181 | struct inet_timewait_sock *tw = NULL; | ||
182 | |||
183 | local_bh_disable(); | ||
184 | for (i = 1; i <= range; i++) { | ||
185 | port = low + (i + offset) % range; | ||
186 | head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)]; | ||
187 | spin_lock(&head->lock); | ||
188 | |||
189 | /* Does not bother with rcv_saddr checks, | ||
190 | * because the established check is already | ||
191 | * unique enough. | ||
192 | */ | ||
193 | inet_bind_bucket_for_each(tb, node, &head->chain) { | ||
194 | if (tb->port == port) { | ||
195 | BUG_TRAP(!hlist_empty(&tb->owners)); | ||
196 | if (tb->fastreuse >= 0) | ||
197 | goto next_port; | ||
198 | if (!__inet6_check_established(death_row, | ||
199 | sk, port, | ||
200 | &tw)) | ||
201 | goto ok; | ||
202 | goto next_port; | ||
203 | } | ||
204 | } | ||
205 | |||
206 | tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep, | ||
207 | head, port); | ||
208 | if (!tb) { | ||
209 | spin_unlock(&head->lock); | ||
210 | break; | ||
211 | } | ||
212 | tb->fastreuse = -1; | ||
213 | goto ok; | ||
214 | |||
215 | next_port: | ||
216 | spin_unlock(&head->lock); | ||
217 | } | ||
218 | local_bh_enable(); | ||
219 | |||
220 | return -EADDRNOTAVAIL; | ||
221 | |||
222 | ok: | ||
223 | hint += i; | ||
224 | |||
225 | /* Head lock still held and bh's disabled */ | ||
226 | inet_bind_hash(sk, tb, port); | ||
227 | if (sk_unhashed(sk)) { | ||
228 | inet_sk(sk)->sport = htons(port); | ||
229 | __inet6_hash(hinfo, sk); | ||
230 | } | ||
231 | spin_unlock(&head->lock); | ||
232 | |||
233 | if (tw) { | ||
234 | inet_twsk_deschedule(tw, death_row); | ||
235 | inet_twsk_put(tw); | ||
236 | } | ||
237 | |||
238 | ret = 0; | ||
239 | goto out; | ||
240 | } | ||
241 | |||
242 | head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)]; | ||
243 | tb = inet_csk(sk)->icsk_bind_hash; | ||
244 | spin_lock_bh(&head->lock); | ||
245 | |||
246 | if (sk_head(&tb->owners) == sk && sk->sk_bind_node.next == NULL) { | ||
247 | __inet6_hash(hinfo, sk); | ||
248 | spin_unlock_bh(&head->lock); | ||
249 | return 0; | ||
250 | } else { | ||
251 | spin_unlock(&head->lock); | ||
252 | /* No definite answer... Walk to established hash table */ | ||
253 | ret = __inet6_check_established(death_row, sk, snum, NULL); | ||
254 | out: | ||
255 | local_bh_enable(); | ||
256 | return ret; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | EXPORT_SYMBOL_GPL(inet6_hash_connect); | ||
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 1cf02765fb5c..89d12b4817a9 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -200,6 +200,8 @@ struct ip6_flowlabel * fl6_sock_lookup(struct sock *sk, u32 label) | |||
200 | return NULL; | 200 | return NULL; |
201 | } | 201 | } |
202 | 202 | ||
203 | EXPORT_SYMBOL_GPL(fl6_sock_lookup); | ||
204 | |||
203 | void fl6_free_socklist(struct sock *sk) | 205 | void fl6_free_socklist(struct sock *sk) |
204 | { | 206 | { |
205 | struct ipv6_pinfo *np = inet6_sk(sk); | 207 | struct ipv6_pinfo *np = inet6_sk(sk); |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 8523c76ebf76..b4c4beba0ede 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -775,6 +775,8 @@ out_err_release: | |||
775 | return err; | 775 | return err; |
776 | } | 776 | } |
777 | 777 | ||
778 | EXPORT_SYMBOL_GPL(ip6_dst_lookup); | ||
779 | |||
778 | static inline int ip6_ufo_append_data(struct sock *sk, | 780 | static inline int ip6_ufo_append_data(struct sock *sk, |
779 | int getfrag(void *from, char *to, int offset, int len, | 781 | int getfrag(void *from, char *to, int offset, int len, |
780 | int odd, struct sk_buff *skb), | 782 | int odd, struct sk_buff *skb), |
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 55917fb17094..626dd39685f2 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/rtnetlink.h> | 47 | #include <linux/rtnetlink.h> |
48 | #include <net/icmp.h> | 48 | #include <net/icmp.h> |
49 | #include <net/ipv6.h> | 49 | #include <net/ipv6.h> |
50 | #include <net/protocol.h> | ||
50 | #include <linux/ipv6.h> | 51 | #include <linux/ipv6.h> |
51 | #include <linux/icmpv6.h> | 52 | #include <linux/icmpv6.h> |
52 | 53 | ||
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 3620718defe6..c63868dd2ca2 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -163,17 +163,17 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
163 | sk_refcnt_debug_dec(sk); | 163 | sk_refcnt_debug_dec(sk); |
164 | 164 | ||
165 | if (sk->sk_protocol == IPPROTO_TCP) { | 165 | if (sk->sk_protocol == IPPROTO_TCP) { |
166 | struct tcp_sock *tp = tcp_sk(sk); | 166 | struct inet_connection_sock *icsk = inet_csk(sk); |
167 | 167 | ||
168 | local_bh_disable(); | 168 | local_bh_disable(); |
169 | sock_prot_dec_use(sk->sk_prot); | 169 | sock_prot_dec_use(sk->sk_prot); |
170 | sock_prot_inc_use(&tcp_prot); | 170 | sock_prot_inc_use(&tcp_prot); |
171 | local_bh_enable(); | 171 | local_bh_enable(); |
172 | sk->sk_prot = &tcp_prot; | 172 | sk->sk_prot = &tcp_prot; |
173 | tp->af_specific = &ipv4_specific; | 173 | icsk->icsk_af_ops = &ipv4_specific; |
174 | sk->sk_socket->ops = &inet_stream_ops; | 174 | sk->sk_socket->ops = &inet_stream_ops; |
175 | sk->sk_family = PF_INET; | 175 | sk->sk_family = PF_INET; |
176 | tcp_sync_mss(sk, tp->pmtu_cookie); | 176 | tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); |
177 | } else { | 177 | } else { |
178 | local_bh_disable(); | 178 | local_bh_disable(); |
179 | sock_prot_dec_use(sk->sk_prot); | 179 | sock_prot_dec_use(sk->sk_prot); |
@@ -317,14 +317,15 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
317 | } | 317 | } |
318 | 318 | ||
319 | retv = 0; | 319 | retv = 0; |
320 | if (sk->sk_type == SOCK_STREAM) { | 320 | if (inet_sk(sk)->is_icsk) { |
321 | if (opt) { | 321 | if (opt) { |
322 | struct tcp_sock *tp = tcp_sk(sk); | 322 | struct inet_connection_sock *icsk = inet_csk(sk); |
323 | if (!((1 << sk->sk_state) & | 323 | if (!((1 << sk->sk_state) & |
324 | (TCPF_LISTEN | TCPF_CLOSE)) | 324 | (TCPF_LISTEN | TCPF_CLOSE)) |
325 | && inet_sk(sk)->daddr != LOOPBACK4_IPV6) { | 325 | && inet_sk(sk)->daddr != LOOPBACK4_IPV6) { |
326 | tp->ext_header_len = opt->opt_flen + opt->opt_nflen; | 326 | icsk->icsk_ext_hdr_len = |
327 | tcp_sync_mss(sk, tp->pmtu_cookie); | 327 | opt->opt_flen + opt->opt_nflen; |
328 | icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie); | ||
328 | } | 329 | } |
329 | } | 330 | } |
330 | opt = xchg(&np->opt, opt); | 331 | opt = xchg(&np->opt, opt); |
@@ -380,14 +381,15 @@ sticky_done: | |||
380 | goto done; | 381 | goto done; |
381 | update: | 382 | update: |
382 | retv = 0; | 383 | retv = 0; |
383 | if (sk->sk_type == SOCK_STREAM) { | 384 | if (inet_sk(sk)->is_icsk) { |
384 | if (opt) { | 385 | if (opt) { |
385 | struct tcp_sock *tp = tcp_sk(sk); | 386 | struct inet_connection_sock *icsk = inet_csk(sk); |
386 | if (!((1 << sk->sk_state) & | 387 | if (!((1 << sk->sk_state) & |
387 | (TCPF_LISTEN | TCPF_CLOSE)) | 388 | (TCPF_LISTEN | TCPF_CLOSE)) |
388 | && inet_sk(sk)->daddr != LOOPBACK4_IPV6) { | 389 | && inet_sk(sk)->daddr != LOOPBACK4_IPV6) { |
389 | tp->ext_header_len = opt->opt_flen + opt->opt_nflen; | 390 | icsk->icsk_ext_hdr_len = |
390 | tcp_sync_mss(sk, tp->pmtu_cookie); | 391 | opt->opt_flen + opt->opt_nflen; |
392 | icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie); | ||
391 | } | 393 | } |
392 | } | 394 | } |
393 | opt = xchg(&np->opt, opt); | 395 | opt = xchg(&np->opt, opt); |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index fd939da090c4..1cf305a9f8dd 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -170,7 +170,7 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml, | |||
170 | #define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value) | 170 | #define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value) |
171 | #define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value) | 171 | #define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value) |
172 | 172 | ||
173 | #define IPV6_MLD_MAX_MSF 10 | 173 | #define IPV6_MLD_MAX_MSF 64 |
174 | 174 | ||
175 | int sysctl_mld_max_msf = IPV6_MLD_MAX_MSF; | 175 | int sysctl_mld_max_msf = IPV6_MLD_MAX_MSF; |
176 | 176 | ||
@@ -224,6 +224,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr) | |||
224 | 224 | ||
225 | mc_lst->ifindex = dev->ifindex; | 225 | mc_lst->ifindex = dev->ifindex; |
226 | mc_lst->sfmode = MCAST_EXCLUDE; | 226 | mc_lst->sfmode = MCAST_EXCLUDE; |
227 | rwlock_init(&mc_lst->sflock); | ||
227 | mc_lst->sflist = NULL; | 228 | mc_lst->sflist = NULL; |
228 | 229 | ||
229 | /* | 230 | /* |
@@ -360,6 +361,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk, | |||
360 | struct ip6_sf_socklist *psl; | 361 | struct ip6_sf_socklist *psl; |
361 | int i, j, rv; | 362 | int i, j, rv; |
362 | int leavegroup = 0; | 363 | int leavegroup = 0; |
364 | int pmclocked = 0; | ||
363 | int err; | 365 | int err; |
364 | 366 | ||
365 | if (pgsr->gsr_group.ss_family != AF_INET6 || | 367 | if (pgsr->gsr_group.ss_family != AF_INET6 || |
@@ -403,6 +405,9 @@ int ip6_mc_source(int add, int omode, struct sock *sk, | |||
403 | pmc->sfmode = omode; | 405 | pmc->sfmode = omode; |
404 | } | 406 | } |
405 | 407 | ||
408 | write_lock_bh(&pmc->sflock); | ||
409 | pmclocked = 1; | ||
410 | |||
406 | psl = pmc->sflist; | 411 | psl = pmc->sflist; |
407 | if (!add) { | 412 | if (!add) { |
408 | if (!psl) | 413 | if (!psl) |
@@ -475,6 +480,8 @@ int ip6_mc_source(int add, int omode, struct sock *sk, | |||
475 | /* update the interface list */ | 480 | /* update the interface list */ |
476 | ip6_mc_add_src(idev, group, omode, 1, source, 1); | 481 | ip6_mc_add_src(idev, group, omode, 1, source, 1); |
477 | done: | 482 | done: |
483 | if (pmclocked) | ||
484 | write_unlock_bh(&pmc->sflock); | ||
478 | read_unlock_bh(&ipv6_sk_mc_lock); | 485 | read_unlock_bh(&ipv6_sk_mc_lock); |
479 | read_unlock_bh(&idev->lock); | 486 | read_unlock_bh(&idev->lock); |
480 | in6_dev_put(idev); | 487 | in6_dev_put(idev); |
@@ -510,6 +517,8 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) | |||
510 | dev = idev->dev; | 517 | dev = idev->dev; |
511 | 518 | ||
512 | err = 0; | 519 | err = 0; |
520 | read_lock_bh(&ipv6_sk_mc_lock); | ||
521 | |||
513 | if (gsf->gf_fmode == MCAST_INCLUDE && gsf->gf_numsrc == 0) { | 522 | if (gsf->gf_fmode == MCAST_INCLUDE && gsf->gf_numsrc == 0) { |
514 | leavegroup = 1; | 523 | leavegroup = 1; |
515 | goto done; | 524 | goto done; |
@@ -549,6 +558,8 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) | |||
549 | newpsl = NULL; | 558 | newpsl = NULL; |
550 | (void) ip6_mc_add_src(idev, group, gsf->gf_fmode, 0, NULL, 0); | 559 | (void) ip6_mc_add_src(idev, group, gsf->gf_fmode, 0, NULL, 0); |
551 | } | 560 | } |
561 | |||
562 | write_lock_bh(&pmc->sflock); | ||
552 | psl = pmc->sflist; | 563 | psl = pmc->sflist; |
553 | if (psl) { | 564 | if (psl) { |
554 | (void) ip6_mc_del_src(idev, group, pmc->sfmode, | 565 | (void) ip6_mc_del_src(idev, group, pmc->sfmode, |
@@ -558,8 +569,10 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) | |||
558 | (void) ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0); | 569 | (void) ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0); |
559 | pmc->sflist = newpsl; | 570 | pmc->sflist = newpsl; |
560 | pmc->sfmode = gsf->gf_fmode; | 571 | pmc->sfmode = gsf->gf_fmode; |
572 | write_unlock_bh(&pmc->sflock); | ||
561 | err = 0; | 573 | err = 0; |
562 | done: | 574 | done: |
575 | read_unlock_bh(&ipv6_sk_mc_lock); | ||
563 | read_unlock_bh(&idev->lock); | 576 | read_unlock_bh(&idev->lock); |
564 | in6_dev_put(idev); | 577 | in6_dev_put(idev); |
565 | dev_put(dev); | 578 | dev_put(dev); |
@@ -592,6 +605,11 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf, | |||
592 | dev = idev->dev; | 605 | dev = idev->dev; |
593 | 606 | ||
594 | err = -EADDRNOTAVAIL; | 607 | err = -EADDRNOTAVAIL; |
608 | /* | ||
609 | * changes to the ipv6_mc_list require the socket lock and | ||
610 | * a read lock on ip6_sk_mc_lock. We have the socket lock, | ||
611 | * so reading the list is safe. | ||
612 | */ | ||
595 | 613 | ||
596 | for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { | 614 | for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { |
597 | if (pmc->ifindex != gsf->gf_interface) | 615 | if (pmc->ifindex != gsf->gf_interface) |
@@ -614,6 +632,10 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf, | |||
614 | copy_to_user(optval, gsf, GROUP_FILTER_SIZE(0))) { | 632 | copy_to_user(optval, gsf, GROUP_FILTER_SIZE(0))) { |
615 | return -EFAULT; | 633 | return -EFAULT; |
616 | } | 634 | } |
635 | /* changes to psl require the socket lock, a read lock on | ||
636 | * on ipv6_sk_mc_lock and a write lock on pmc->sflock. We | ||
637 | * have the socket lock, so reading here is safe. | ||
638 | */ | ||
617 | for (i=0; i<copycount; i++) { | 639 | for (i=0; i<copycount; i++) { |
618 | struct sockaddr_in6 *psin6; | 640 | struct sockaddr_in6 *psin6; |
619 | struct sockaddr_storage ss; | 641 | struct sockaddr_storage ss; |
@@ -650,6 +672,7 @@ int inet6_mc_check(struct sock *sk, struct in6_addr *mc_addr, | |||
650 | read_unlock(&ipv6_sk_mc_lock); | 672 | read_unlock(&ipv6_sk_mc_lock); |
651 | return 1; | 673 | return 1; |
652 | } | 674 | } |
675 | read_lock(&mc->sflock); | ||
653 | psl = mc->sflist; | 676 | psl = mc->sflist; |
654 | if (!psl) { | 677 | if (!psl) { |
655 | rv = mc->sfmode == MCAST_EXCLUDE; | 678 | rv = mc->sfmode == MCAST_EXCLUDE; |
@@ -665,6 +688,7 @@ int inet6_mc_check(struct sock *sk, struct in6_addr *mc_addr, | |||
665 | if (mc->sfmode == MCAST_EXCLUDE && i < psl->sl_count) | 688 | if (mc->sfmode == MCAST_EXCLUDE && i < psl->sl_count) |
666 | rv = 0; | 689 | rv = 0; |
667 | } | 690 | } |
691 | read_unlock(&mc->sflock); | ||
668 | read_unlock(&ipv6_sk_mc_lock); | 692 | read_unlock(&ipv6_sk_mc_lock); |
669 | 693 | ||
670 | return rv; | 694 | return rv; |
@@ -1068,7 +1092,8 @@ static void igmp6_group_queried(struct ifmcaddr6 *ma, unsigned long resptime) | |||
1068 | ma->mca_flags |= MAF_TIMER_RUNNING; | 1092 | ma->mca_flags |= MAF_TIMER_RUNNING; |
1069 | } | 1093 | } |
1070 | 1094 | ||
1071 | static void mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, | 1095 | /* mark EXCLUDE-mode sources */ |
1096 | static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs, | ||
1072 | struct in6_addr *srcs) | 1097 | struct in6_addr *srcs) |
1073 | { | 1098 | { |
1074 | struct ip6_sf_list *psf; | 1099 | struct ip6_sf_list *psf; |
@@ -1078,13 +1103,53 @@ static void mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, | |||
1078 | for (psf=pmc->mca_sources; psf; psf=psf->sf_next) { | 1103 | for (psf=pmc->mca_sources; psf; psf=psf->sf_next) { |
1079 | if (scount == nsrcs) | 1104 | if (scount == nsrcs) |
1080 | break; | 1105 | break; |
1081 | for (i=0; i<nsrcs; i++) | 1106 | for (i=0; i<nsrcs; i++) { |
1107 | /* skip inactive filters */ | ||
1108 | if (pmc->mca_sfcount[MCAST_INCLUDE] || | ||
1109 | pmc->mca_sfcount[MCAST_EXCLUDE] != | ||
1110 | psf->sf_count[MCAST_EXCLUDE]) | ||
1111 | continue; | ||
1112 | if (ipv6_addr_equal(&srcs[i], &psf->sf_addr)) { | ||
1113 | scount++; | ||
1114 | break; | ||
1115 | } | ||
1116 | } | ||
1117 | } | ||
1118 | pmc->mca_flags &= ~MAF_GSQUERY; | ||
1119 | if (scount == nsrcs) /* all sources excluded */ | ||
1120 | return 0; | ||
1121 | return 1; | ||
1122 | } | ||
1123 | |||
1124 | static int mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, | ||
1125 | struct in6_addr *srcs) | ||
1126 | { | ||
1127 | struct ip6_sf_list *psf; | ||
1128 | int i, scount; | ||
1129 | |||
1130 | if (pmc->mca_sfmode == MCAST_EXCLUDE) | ||
1131 | return mld_xmarksources(pmc, nsrcs, srcs); | ||
1132 | |||
1133 | /* mark INCLUDE-mode sources */ | ||
1134 | |||
1135 | scount = 0; | ||
1136 | for (psf=pmc->mca_sources; psf; psf=psf->sf_next) { | ||
1137 | if (scount == nsrcs) | ||
1138 | break; | ||
1139 | for (i=0; i<nsrcs; i++) { | ||
1082 | if (ipv6_addr_equal(&srcs[i], &psf->sf_addr)) { | 1140 | if (ipv6_addr_equal(&srcs[i], &psf->sf_addr)) { |
1083 | psf->sf_gsresp = 1; | 1141 | psf->sf_gsresp = 1; |
1084 | scount++; | 1142 | scount++; |
1085 | break; | 1143 | break; |
1086 | } | 1144 | } |
1145 | } | ||
1146 | } | ||
1147 | if (!scount) { | ||
1148 | pmc->mca_flags &= ~MAF_GSQUERY; | ||
1149 | return 0; | ||
1087 | } | 1150 | } |
1151 | pmc->mca_flags |= MAF_GSQUERY; | ||
1152 | return 1; | ||
1088 | } | 1153 | } |
1089 | 1154 | ||
1090 | int igmp6_event_query(struct sk_buff *skb) | 1155 | int igmp6_event_query(struct sk_buff *skb) |
@@ -1167,7 +1232,7 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1167 | /* mark sources to include, if group & source-specific */ | 1232 | /* mark sources to include, if group & source-specific */ |
1168 | if (mlh2->nsrcs != 0) { | 1233 | if (mlh2->nsrcs != 0) { |
1169 | if (!pskb_may_pull(skb, srcs_offset + | 1234 | if (!pskb_may_pull(skb, srcs_offset + |
1170 | mlh2->nsrcs * sizeof(struct in6_addr))) { | 1235 | ntohs(mlh2->nsrcs) * sizeof(struct in6_addr))) { |
1171 | in6_dev_put(idev); | 1236 | in6_dev_put(idev); |
1172 | return -EINVAL; | 1237 | return -EINVAL; |
1173 | } | 1238 | } |
@@ -1203,10 +1268,9 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1203 | else | 1268 | else |
1204 | ma->mca_flags &= ~MAF_GSQUERY; | 1269 | ma->mca_flags &= ~MAF_GSQUERY; |
1205 | } | 1270 | } |
1206 | if (ma->mca_flags & MAF_GSQUERY) | 1271 | if (!(ma->mca_flags & MAF_GSQUERY) || |
1207 | mld_marksources(ma, ntohs(mlh2->nsrcs), | 1272 | mld_marksources(ma, ntohs(mlh2->nsrcs), mlh2->srcs)) |
1208 | mlh2->srcs); | 1273 | igmp6_group_queried(ma, max_delay); |
1209 | igmp6_group_queried(ma, max_delay); | ||
1210 | spin_unlock_bh(&ma->mca_lock); | 1274 | spin_unlock_bh(&ma->mca_lock); |
1211 | if (group_type != IPV6_ADDR_ANY) | 1275 | if (group_type != IPV6_ADDR_ANY) |
1212 | break; | 1276 | break; |
@@ -1281,7 +1345,18 @@ static int is_in(struct ifmcaddr6 *pmc, struct ip6_sf_list *psf, int type, | |||
1281 | case MLD2_MODE_IS_EXCLUDE: | 1345 | case MLD2_MODE_IS_EXCLUDE: |
1282 | if (gdeleted || sdeleted) | 1346 | if (gdeleted || sdeleted) |
1283 | return 0; | 1347 | return 0; |
1284 | return !((pmc->mca_flags & MAF_GSQUERY) && !psf->sf_gsresp); | 1348 | if (!((pmc->mca_flags & MAF_GSQUERY) && !psf->sf_gsresp)) { |
1349 | if (pmc->mca_sfmode == MCAST_INCLUDE) | ||
1350 | return 1; | ||
1351 | /* don't include if this source is excluded | ||
1352 | * in all filters | ||
1353 | */ | ||
1354 | if (psf->sf_count[MCAST_INCLUDE]) | ||
1355 | return 0; | ||
1356 | return pmc->mca_sfcount[MCAST_EXCLUDE] == | ||
1357 | psf->sf_count[MCAST_EXCLUDE]; | ||
1358 | } | ||
1359 | return 0; | ||
1285 | case MLD2_CHANGE_TO_INCLUDE: | 1360 | case MLD2_CHANGE_TO_INCLUDE: |
1286 | if (gdeleted || sdeleted) | 1361 | if (gdeleted || sdeleted) |
1287 | return 0; | 1362 | return 0; |
@@ -1450,7 +1525,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1450 | struct mld2_report *pmr; | 1525 | struct mld2_report *pmr; |
1451 | struct mld2_grec *pgr = NULL; | 1526 | struct mld2_grec *pgr = NULL; |
1452 | struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list; | 1527 | struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list; |
1453 | int scount, first, isquery, truncate; | 1528 | int scount, stotal, first, isquery, truncate; |
1454 | 1529 | ||
1455 | if (pmc->mca_flags & MAF_NOREPORT) | 1530 | if (pmc->mca_flags & MAF_NOREPORT) |
1456 | return skb; | 1531 | return skb; |
@@ -1460,25 +1535,13 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1460 | truncate = type == MLD2_MODE_IS_EXCLUDE || | 1535 | truncate = type == MLD2_MODE_IS_EXCLUDE || |
1461 | type == MLD2_CHANGE_TO_EXCLUDE; | 1536 | type == MLD2_CHANGE_TO_EXCLUDE; |
1462 | 1537 | ||
1538 | stotal = scount = 0; | ||
1539 | |||
1463 | psf_list = sdeleted ? &pmc->mca_tomb : &pmc->mca_sources; | 1540 | psf_list = sdeleted ? &pmc->mca_tomb : &pmc->mca_sources; |
1464 | 1541 | ||
1465 | if (!*psf_list) { | 1542 | if (!*psf_list) |
1466 | if (type == MLD2_ALLOW_NEW_SOURCES || | 1543 | goto empty_source; |
1467 | type == MLD2_BLOCK_OLD_SOURCES) | 1544 | |
1468 | return skb; | ||
1469 | if (pmc->mca_crcount || isquery) { | ||
1470 | /* make sure we have room for group header and at | ||
1471 | * least one source. | ||
1472 | */ | ||
1473 | if (skb && AVAILABLE(skb) < sizeof(struct mld2_grec)+ | ||
1474 | sizeof(struct in6_addr)) { | ||
1475 | mld_sendpack(skb); | ||
1476 | skb = NULL; /* add_grhead will get a new one */ | ||
1477 | } | ||
1478 | skb = add_grhead(skb, pmc, type, &pgr); | ||
1479 | } | ||
1480 | return skb; | ||
1481 | } | ||
1482 | pmr = skb ? (struct mld2_report *)skb->h.raw : NULL; | 1545 | pmr = skb ? (struct mld2_report *)skb->h.raw : NULL; |
1483 | 1546 | ||
1484 | /* EX and TO_EX get a fresh packet, if needed */ | 1547 | /* EX and TO_EX get a fresh packet, if needed */ |
@@ -1491,7 +1554,6 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1491 | } | 1554 | } |
1492 | } | 1555 | } |
1493 | first = 1; | 1556 | first = 1; |
1494 | scount = 0; | ||
1495 | psf_prev = NULL; | 1557 | psf_prev = NULL; |
1496 | for (psf=*psf_list; psf; psf=psf_next) { | 1558 | for (psf=*psf_list; psf; psf=psf_next) { |
1497 | struct in6_addr *psrc; | 1559 | struct in6_addr *psrc; |
@@ -1525,7 +1587,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1525 | } | 1587 | } |
1526 | psrc = (struct in6_addr *)skb_put(skb, sizeof(*psrc)); | 1588 | psrc = (struct in6_addr *)skb_put(skb, sizeof(*psrc)); |
1527 | *psrc = psf->sf_addr; | 1589 | *psrc = psf->sf_addr; |
1528 | scount++; | 1590 | scount++; stotal++; |
1529 | if ((type == MLD2_ALLOW_NEW_SOURCES || | 1591 | if ((type == MLD2_ALLOW_NEW_SOURCES || |
1530 | type == MLD2_BLOCK_OLD_SOURCES) && psf->sf_crcount) { | 1592 | type == MLD2_BLOCK_OLD_SOURCES) && psf->sf_crcount) { |
1531 | psf->sf_crcount--; | 1593 | psf->sf_crcount--; |
@@ -1540,6 +1602,21 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1540 | } | 1602 | } |
1541 | psf_prev = psf; | 1603 | psf_prev = psf; |
1542 | } | 1604 | } |
1605 | |||
1606 | empty_source: | ||
1607 | if (!stotal) { | ||
1608 | if (type == MLD2_ALLOW_NEW_SOURCES || | ||
1609 | type == MLD2_BLOCK_OLD_SOURCES) | ||
1610 | return skb; | ||
1611 | if (pmc->mca_crcount || isquery) { | ||
1612 | /* make sure we have room for group header */ | ||
1613 | if (skb && AVAILABLE(skb) < sizeof(struct mld2_grec)) { | ||
1614 | mld_sendpack(skb); | ||
1615 | skb = NULL; /* add_grhead will get a new one */ | ||
1616 | } | ||
1617 | skb = add_grhead(skb, pmc, type, &pgr); | ||
1618 | } | ||
1619 | } | ||
1543 | if (pgr) | 1620 | if (pgr) |
1544 | pgr->grec_nsrcs = htons(scount); | 1621 | pgr->grec_nsrcs = htons(scount); |
1545 | 1622 | ||
@@ -1621,11 +1698,11 @@ static void mld_send_cr(struct inet6_dev *idev) | |||
1621 | skb = add_grec(skb, pmc, dtype, 1, 1); | 1698 | skb = add_grec(skb, pmc, dtype, 1, 1); |
1622 | } | 1699 | } |
1623 | if (pmc->mca_crcount) { | 1700 | if (pmc->mca_crcount) { |
1624 | pmc->mca_crcount--; | ||
1625 | if (pmc->mca_sfmode == MCAST_EXCLUDE) { | 1701 | if (pmc->mca_sfmode == MCAST_EXCLUDE) { |
1626 | type = MLD2_CHANGE_TO_INCLUDE; | 1702 | type = MLD2_CHANGE_TO_INCLUDE; |
1627 | skb = add_grec(skb, pmc, type, 1, 0); | 1703 | skb = add_grec(skb, pmc, type, 1, 0); |
1628 | } | 1704 | } |
1705 | pmc->mca_crcount--; | ||
1629 | if (pmc->mca_crcount == 0) { | 1706 | if (pmc->mca_crcount == 0) { |
1630 | mld_clear_zeros(&pmc->mca_tomb); | 1707 | mld_clear_zeros(&pmc->mca_tomb); |
1631 | mld_clear_zeros(&pmc->mca_sources); | 1708 | mld_clear_zeros(&pmc->mca_sources); |
@@ -1659,12 +1736,12 @@ static void mld_send_cr(struct inet6_dev *idev) | |||
1659 | 1736 | ||
1660 | /* filter mode changes */ | 1737 | /* filter mode changes */ |
1661 | if (pmc->mca_crcount) { | 1738 | if (pmc->mca_crcount) { |
1662 | pmc->mca_crcount--; | ||
1663 | if (pmc->mca_sfmode == MCAST_EXCLUDE) | 1739 | if (pmc->mca_sfmode == MCAST_EXCLUDE) |
1664 | type = MLD2_CHANGE_TO_EXCLUDE; | 1740 | type = MLD2_CHANGE_TO_EXCLUDE; |
1665 | else | 1741 | else |
1666 | type = MLD2_CHANGE_TO_INCLUDE; | 1742 | type = MLD2_CHANGE_TO_INCLUDE; |
1667 | skb = add_grec(skb, pmc, type, 0, 0); | 1743 | skb = add_grec(skb, pmc, type, 0, 0); |
1744 | pmc->mca_crcount--; | ||
1668 | } | 1745 | } |
1669 | spin_unlock_bh(&pmc->mca_lock); | 1746 | spin_unlock_bh(&pmc->mca_lock); |
1670 | } | 1747 | } |
@@ -2023,6 +2100,9 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml, | |||
2023 | { | 2100 | { |
2024 | int err; | 2101 | int err; |
2025 | 2102 | ||
2103 | /* callers have the socket lock and a write lock on ipv6_sk_mc_lock, | ||
2104 | * so no other readers or writers of iml or its sflist | ||
2105 | */ | ||
2026 | if (iml->sflist == 0) { | 2106 | if (iml->sflist == 0) { |
2027 | /* any-source empty exclude case */ | 2107 | /* any-source empty exclude case */ |
2028 | return ip6_mc_del_src(idev, &iml->addr, iml->sfmode, 0, NULL, 0); | 2108 | return ip6_mc_del_src(idev, &iml->addr, iml->sfmode, 0, NULL, 0); |
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 060d61202412..04912f9b35c3 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
@@ -211,7 +211,7 @@ config IP6_NF_TARGET_REJECT | |||
211 | 211 | ||
212 | config IP6_NF_TARGET_NFQUEUE | 212 | config IP6_NF_TARGET_NFQUEUE |
213 | tristate "NFQUEUE Target Support" | 213 | tristate "NFQUEUE Target Support" |
214 | depends on IP_NF_IPTABLES | 214 | depends on IP6_NF_IPTABLES |
215 | help | 215 | help |
216 | This Target replaced the old obsolete QUEUE target. | 216 | This Target replaced the old obsolete QUEUE target. |
217 | 217 | ||
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 95d469271c4d..ea43ef1d94a7 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * - new extension header parser code | 15 | * - new extension header parser code |
16 | */ | 16 | */ |
17 | #include <linux/config.h> | 17 | #include <linux/config.h> |
18 | #include <linux/in.h> | ||
18 | #include <linux/skbuff.h> | 19 | #include <linux/skbuff.h> |
19 | #include <linux/kmod.h> | 20 | #include <linux/kmod.h> |
20 | #include <linux/vmalloc.h> | 21 | #include <linux/vmalloc.h> |
@@ -86,11 +87,6 @@ static DECLARE_MUTEX(ip6t_mutex); | |||
86 | context stops packets coming through and allows user context to read | 87 | context stops packets coming through and allows user context to read |
87 | the counters or update the rules. | 88 | the counters or update the rules. |
88 | 89 | ||
89 | To be cache friendly on SMP, we arrange them like so: | ||
90 | [ n-entries ] | ||
91 | ... cache-align padding ... | ||
92 | [ n-entries ] | ||
93 | |||
94 | Hence the start of any table is given by get_table() below. */ | 90 | Hence the start of any table is given by get_table() below. */ |
95 | 91 | ||
96 | /* The table itself */ | 92 | /* The table itself */ |
@@ -108,20 +104,15 @@ struct ip6t_table_info | |||
108 | unsigned int underflow[NF_IP6_NUMHOOKS]; | 104 | unsigned int underflow[NF_IP6_NUMHOOKS]; |
109 | 105 | ||
110 | /* ip6t_entry tables: one per CPU */ | 106 | /* ip6t_entry tables: one per CPU */ |
111 | char entries[0] ____cacheline_aligned; | 107 | void *entries[NR_CPUS]; |
112 | }; | 108 | }; |
113 | 109 | ||
114 | static LIST_HEAD(ip6t_target); | 110 | static LIST_HEAD(ip6t_target); |
115 | static LIST_HEAD(ip6t_match); | 111 | static LIST_HEAD(ip6t_match); |
116 | static LIST_HEAD(ip6t_tables); | 112 | static LIST_HEAD(ip6t_tables); |
113 | #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) | ||
117 | #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) | 114 | #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) |
118 | 115 | ||
119 | #ifdef CONFIG_SMP | ||
120 | #define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p)) | ||
121 | #else | ||
122 | #define TABLE_OFFSET(t,p) 0 | ||
123 | #endif | ||
124 | |||
125 | #if 0 | 116 | #if 0 |
126 | #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) | 117 | #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) |
127 | #define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; }) | 118 | #define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; }) |
@@ -376,8 +367,7 @@ ip6t_do_table(struct sk_buff **pskb, | |||
376 | 367 | ||
377 | read_lock_bh(&table->lock); | 368 | read_lock_bh(&table->lock); |
378 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); | 369 | IP_NF_ASSERT(table->valid_hooks & (1 << hook)); |
379 | table_base = (void *)table->private->entries | 370 | table_base = (void *)table->private->entries[smp_processor_id()]; |
380 | + TABLE_OFFSET(table->private, smp_processor_id()); | ||
381 | e = get_entry(table_base, table->private->hook_entry[hook]); | 371 | e = get_entry(table_base, table->private->hook_entry[hook]); |
382 | 372 | ||
383 | #ifdef CONFIG_NETFILTER_DEBUG | 373 | #ifdef CONFIG_NETFILTER_DEBUG |
@@ -649,7 +639,8 @@ unconditional(const struct ip6t_ip6 *ipv6) | |||
649 | /* Figures out from what hook each rule can be called: returns 0 if | 639 | /* Figures out from what hook each rule can be called: returns 0 if |
650 | there are loops. Puts hook bitmask in comefrom. */ | 640 | there are loops. Puts hook bitmask in comefrom. */ |
651 | static int | 641 | static int |
652 | mark_source_chains(struct ip6t_table_info *newinfo, unsigned int valid_hooks) | 642 | mark_source_chains(struct ip6t_table_info *newinfo, |
643 | unsigned int valid_hooks, void *entry0) | ||
653 | { | 644 | { |
654 | unsigned int hook; | 645 | unsigned int hook; |
655 | 646 | ||
@@ -658,7 +649,7 @@ mark_source_chains(struct ip6t_table_info *newinfo, unsigned int valid_hooks) | |||
658 | for (hook = 0; hook < NF_IP6_NUMHOOKS; hook++) { | 649 | for (hook = 0; hook < NF_IP6_NUMHOOKS; hook++) { |
659 | unsigned int pos = newinfo->hook_entry[hook]; | 650 | unsigned int pos = newinfo->hook_entry[hook]; |
660 | struct ip6t_entry *e | 651 | struct ip6t_entry *e |
661 | = (struct ip6t_entry *)(newinfo->entries + pos); | 652 | = (struct ip6t_entry *)(entry0 + pos); |
662 | 653 | ||
663 | if (!(valid_hooks & (1 << hook))) | 654 | if (!(valid_hooks & (1 << hook))) |
664 | continue; | 655 | continue; |
@@ -708,13 +699,13 @@ mark_source_chains(struct ip6t_table_info *newinfo, unsigned int valid_hooks) | |||
708 | goto next; | 699 | goto next; |
709 | 700 | ||
710 | e = (struct ip6t_entry *) | 701 | e = (struct ip6t_entry *) |
711 | (newinfo->entries + pos); | 702 | (entry0 + pos); |
712 | } while (oldpos == pos + e->next_offset); | 703 | } while (oldpos == pos + e->next_offset); |
713 | 704 | ||
714 | /* Move along one */ | 705 | /* Move along one */ |
715 | size = e->next_offset; | 706 | size = e->next_offset; |
716 | e = (struct ip6t_entry *) | 707 | e = (struct ip6t_entry *) |
717 | (newinfo->entries + pos + size); | 708 | (entry0 + pos + size); |
718 | e->counters.pcnt = pos; | 709 | e->counters.pcnt = pos; |
719 | pos += size; | 710 | pos += size; |
720 | } else { | 711 | } else { |
@@ -731,7 +722,7 @@ mark_source_chains(struct ip6t_table_info *newinfo, unsigned int valid_hooks) | |||
731 | newpos = pos + e->next_offset; | 722 | newpos = pos + e->next_offset; |
732 | } | 723 | } |
733 | e = (struct ip6t_entry *) | 724 | e = (struct ip6t_entry *) |
734 | (newinfo->entries + newpos); | 725 | (entry0 + newpos); |
735 | e->counters.pcnt = pos; | 726 | e->counters.pcnt = pos; |
736 | pos = newpos; | 727 | pos = newpos; |
737 | } | 728 | } |
@@ -941,6 +932,7 @@ static int | |||
941 | translate_table(const char *name, | 932 | translate_table(const char *name, |
942 | unsigned int valid_hooks, | 933 | unsigned int valid_hooks, |
943 | struct ip6t_table_info *newinfo, | 934 | struct ip6t_table_info *newinfo, |
935 | void *entry0, | ||
944 | unsigned int size, | 936 | unsigned int size, |
945 | unsigned int number, | 937 | unsigned int number, |
946 | const unsigned int *hook_entries, | 938 | const unsigned int *hook_entries, |
@@ -961,11 +953,11 @@ translate_table(const char *name, | |||
961 | duprintf("translate_table: size %u\n", newinfo->size); | 953 | duprintf("translate_table: size %u\n", newinfo->size); |
962 | i = 0; | 954 | i = 0; |
963 | /* Walk through entries, checking offsets. */ | 955 | /* Walk through entries, checking offsets. */ |
964 | ret = IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size, | 956 | ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, |
965 | check_entry_size_and_hooks, | 957 | check_entry_size_and_hooks, |
966 | newinfo, | 958 | newinfo, |
967 | newinfo->entries, | 959 | entry0, |
968 | newinfo->entries + size, | 960 | entry0 + size, |
969 | hook_entries, underflows, &i); | 961 | hook_entries, underflows, &i); |
970 | if (ret != 0) | 962 | if (ret != 0) |
971 | return ret; | 963 | return ret; |
@@ -993,27 +985,24 @@ translate_table(const char *name, | |||
993 | } | 985 | } |
994 | } | 986 | } |
995 | 987 | ||
996 | if (!mark_source_chains(newinfo, valid_hooks)) | 988 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) |
997 | return -ELOOP; | 989 | return -ELOOP; |
998 | 990 | ||
999 | /* Finally, each sanity check must pass */ | 991 | /* Finally, each sanity check must pass */ |
1000 | i = 0; | 992 | i = 0; |
1001 | ret = IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size, | 993 | ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, |
1002 | check_entry, name, size, &i); | 994 | check_entry, name, size, &i); |
1003 | 995 | ||
1004 | if (ret != 0) { | 996 | if (ret != 0) { |
1005 | IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size, | 997 | IP6T_ENTRY_ITERATE(entry0, newinfo->size, |
1006 | cleanup_entry, &i); | 998 | cleanup_entry, &i); |
1007 | return ret; | 999 | return ret; |
1008 | } | 1000 | } |
1009 | 1001 | ||
1010 | /* And one copy for every other CPU */ | 1002 | /* And one copy for every other CPU */ |
1011 | for_each_cpu(i) { | 1003 | for_each_cpu(i) { |
1012 | if (i == 0) | 1004 | if (newinfo->entries[i] && newinfo->entries[i] != entry0) |
1013 | continue; | 1005 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
1014 | memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i, | ||
1015 | newinfo->entries, | ||
1016 | SMP_ALIGN(newinfo->size)); | ||
1017 | } | 1006 | } |
1018 | 1007 | ||
1019 | return ret; | 1008 | return ret; |
@@ -1029,15 +1018,12 @@ replace_table(struct ip6t_table *table, | |||
1029 | 1018 | ||
1030 | #ifdef CONFIG_NETFILTER_DEBUG | 1019 | #ifdef CONFIG_NETFILTER_DEBUG |
1031 | { | 1020 | { |
1032 | struct ip6t_entry *table_base; | 1021 | int cpu; |
1033 | unsigned int i; | ||
1034 | 1022 | ||
1035 | for_each_cpu(i) { | 1023 | for_each_cpu(cpu) { |
1036 | table_base = | 1024 | struct ip6t_entry *table_base = newinfo->entries[cpu]; |
1037 | (void *)newinfo->entries | 1025 | if (table_base) |
1038 | + TABLE_OFFSET(newinfo, i); | 1026 | table_base->comefrom = 0xdead57ac; |
1039 | |||
1040 | table_base->comefrom = 0xdead57ac; | ||
1041 | } | 1027 | } |
1042 | } | 1028 | } |
1043 | #endif | 1029 | #endif |
@@ -1072,16 +1058,44 @@ add_entry_to_counter(const struct ip6t_entry *e, | |||
1072 | return 0; | 1058 | return 0; |
1073 | } | 1059 | } |
1074 | 1060 | ||
1061 | static inline int | ||
1062 | set_entry_to_counter(const struct ip6t_entry *e, | ||
1063 | struct ip6t_counters total[], | ||
1064 | unsigned int *i) | ||
1065 | { | ||
1066 | SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); | ||
1067 | |||
1068 | (*i)++; | ||
1069 | return 0; | ||
1070 | } | ||
1071 | |||
1075 | static void | 1072 | static void |
1076 | get_counters(const struct ip6t_table_info *t, | 1073 | get_counters(const struct ip6t_table_info *t, |
1077 | struct ip6t_counters counters[]) | 1074 | struct ip6t_counters counters[]) |
1078 | { | 1075 | { |
1079 | unsigned int cpu; | 1076 | unsigned int cpu; |
1080 | unsigned int i; | 1077 | unsigned int i; |
1078 | unsigned int curcpu; | ||
1079 | |||
1080 | /* Instead of clearing (by a previous call to memset()) | ||
1081 | * the counters and using adds, we set the counters | ||
1082 | * with data used by 'current' CPU | ||
1083 | * We dont care about preemption here. | ||
1084 | */ | ||
1085 | curcpu = raw_smp_processor_id(); | ||
1086 | |||
1087 | i = 0; | ||
1088 | IP6T_ENTRY_ITERATE(t->entries[curcpu], | ||
1089 | t->size, | ||
1090 | set_entry_to_counter, | ||
1091 | counters, | ||
1092 | &i); | ||
1081 | 1093 | ||
1082 | for_each_cpu(cpu) { | 1094 | for_each_cpu(cpu) { |
1095 | if (cpu == curcpu) | ||
1096 | continue; | ||
1083 | i = 0; | 1097 | i = 0; |
1084 | IP6T_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu), | 1098 | IP6T_ENTRY_ITERATE(t->entries[cpu], |
1085 | t->size, | 1099 | t->size, |
1086 | add_entry_to_counter, | 1100 | add_entry_to_counter, |
1087 | counters, | 1101 | counters, |
@@ -1098,6 +1112,7 @@ copy_entries_to_user(unsigned int total_size, | |||
1098 | struct ip6t_entry *e; | 1112 | struct ip6t_entry *e; |
1099 | struct ip6t_counters *counters; | 1113 | struct ip6t_counters *counters; |
1100 | int ret = 0; | 1114 | int ret = 0; |
1115 | void *loc_cpu_entry; | ||
1101 | 1116 | ||
1102 | /* We need atomic snapshot of counters: rest doesn't change | 1117 | /* We need atomic snapshot of counters: rest doesn't change |
1103 | (other than comefrom, which userspace doesn't care | 1118 | (other than comefrom, which userspace doesn't care |
@@ -1109,13 +1124,13 @@ copy_entries_to_user(unsigned int total_size, | |||
1109 | return -ENOMEM; | 1124 | return -ENOMEM; |
1110 | 1125 | ||
1111 | /* First, sum counters... */ | 1126 | /* First, sum counters... */ |
1112 | memset(counters, 0, countersize); | ||
1113 | write_lock_bh(&table->lock); | 1127 | write_lock_bh(&table->lock); |
1114 | get_counters(table->private, counters); | 1128 | get_counters(table->private, counters); |
1115 | write_unlock_bh(&table->lock); | 1129 | write_unlock_bh(&table->lock); |
1116 | 1130 | ||
1117 | /* ... then copy entire thing from CPU 0... */ | 1131 | /* choose the copy that is on ourc node/cpu */ |
1118 | if (copy_to_user(userptr, table->private->entries, total_size) != 0) { | 1132 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; |
1133 | if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { | ||
1119 | ret = -EFAULT; | 1134 | ret = -EFAULT; |
1120 | goto free_counters; | 1135 | goto free_counters; |
1121 | } | 1136 | } |
@@ -1127,7 +1142,7 @@ copy_entries_to_user(unsigned int total_size, | |||
1127 | struct ip6t_entry_match *m; | 1142 | struct ip6t_entry_match *m; |
1128 | struct ip6t_entry_target *t; | 1143 | struct ip6t_entry_target *t; |
1129 | 1144 | ||
1130 | e = (struct ip6t_entry *)(table->private->entries + off); | 1145 | e = (struct ip6t_entry *)(loc_cpu_entry + off); |
1131 | if (copy_to_user(userptr + off | 1146 | if (copy_to_user(userptr + off |
1132 | + offsetof(struct ip6t_entry, counters), | 1147 | + offsetof(struct ip6t_entry, counters), |
1133 | &counters[num], | 1148 | &counters[num], |
@@ -1196,6 +1211,46 @@ get_entries(const struct ip6t_get_entries *entries, | |||
1196 | return ret; | 1211 | return ret; |
1197 | } | 1212 | } |
1198 | 1213 | ||
1214 | static void free_table_info(struct ip6t_table_info *info) | ||
1215 | { | ||
1216 | int cpu; | ||
1217 | for_each_cpu(cpu) { | ||
1218 | if (info->size <= PAGE_SIZE) | ||
1219 | kfree(info->entries[cpu]); | ||
1220 | else | ||
1221 | vfree(info->entries[cpu]); | ||
1222 | } | ||
1223 | kfree(info); | ||
1224 | } | ||
1225 | |||
1226 | static struct ip6t_table_info *alloc_table_info(unsigned int size) | ||
1227 | { | ||
1228 | struct ip6t_table_info *newinfo; | ||
1229 | int cpu; | ||
1230 | |||
1231 | newinfo = kzalloc(sizeof(struct ip6t_table_info), GFP_KERNEL); | ||
1232 | if (!newinfo) | ||
1233 | return NULL; | ||
1234 | |||
1235 | newinfo->size = size; | ||
1236 | |||
1237 | for_each_cpu(cpu) { | ||
1238 | if (size <= PAGE_SIZE) | ||
1239 | newinfo->entries[cpu] = kmalloc_node(size, | ||
1240 | GFP_KERNEL, | ||
1241 | cpu_to_node(cpu)); | ||
1242 | else | ||
1243 | newinfo->entries[cpu] = vmalloc_node(size, | ||
1244 | cpu_to_node(cpu)); | ||
1245 | if (newinfo->entries[cpu] == NULL) { | ||
1246 | free_table_info(newinfo); | ||
1247 | return NULL; | ||
1248 | } | ||
1249 | } | ||
1250 | |||
1251 | return newinfo; | ||
1252 | } | ||
1253 | |||
1199 | static int | 1254 | static int |
1200 | do_replace(void __user *user, unsigned int len) | 1255 | do_replace(void __user *user, unsigned int len) |
1201 | { | 1256 | { |
@@ -1204,6 +1259,7 @@ do_replace(void __user *user, unsigned int len) | |||
1204 | struct ip6t_table *t; | 1259 | struct ip6t_table *t; |
1205 | struct ip6t_table_info *newinfo, *oldinfo; | 1260 | struct ip6t_table_info *newinfo, *oldinfo; |
1206 | struct ip6t_counters *counters; | 1261 | struct ip6t_counters *counters; |
1262 | void *loc_cpu_entry, *loc_cpu_old_entry; | ||
1207 | 1263 | ||
1208 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1264 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
1209 | return -EFAULT; | 1265 | return -EFAULT; |
@@ -1212,13 +1268,13 @@ do_replace(void __user *user, unsigned int len) | |||
1212 | if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) | 1268 | if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) |
1213 | return -ENOMEM; | 1269 | return -ENOMEM; |
1214 | 1270 | ||
1215 | newinfo = vmalloc(sizeof(struct ip6t_table_info) | 1271 | newinfo = alloc_table_info(tmp.size); |
1216 | + SMP_ALIGN(tmp.size) * | ||
1217 | (highest_possible_processor_id()+1)); | ||
1218 | if (!newinfo) | 1272 | if (!newinfo) |
1219 | return -ENOMEM; | 1273 | return -ENOMEM; |
1220 | 1274 | ||
1221 | if (copy_from_user(newinfo->entries, user + sizeof(tmp), | 1275 | /* choose the copy that is on our node/cpu */ |
1276 | loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; | ||
1277 | if (copy_from_user(loc_cpu_entry, user + sizeof(tmp), | ||
1222 | tmp.size) != 0) { | 1278 | tmp.size) != 0) { |
1223 | ret = -EFAULT; | 1279 | ret = -EFAULT; |
1224 | goto free_newinfo; | 1280 | goto free_newinfo; |
@@ -1229,10 +1285,9 @@ do_replace(void __user *user, unsigned int len) | |||
1229 | ret = -ENOMEM; | 1285 | ret = -ENOMEM; |
1230 | goto free_newinfo; | 1286 | goto free_newinfo; |
1231 | } | 1287 | } |
1232 | memset(counters, 0, tmp.num_counters * sizeof(struct ip6t_counters)); | ||
1233 | 1288 | ||
1234 | ret = translate_table(tmp.name, tmp.valid_hooks, | 1289 | ret = translate_table(tmp.name, tmp.valid_hooks, |
1235 | newinfo, tmp.size, tmp.num_entries, | 1290 | newinfo, loc_cpu_entry, tmp.size, tmp.num_entries, |
1236 | tmp.hook_entry, tmp.underflow); | 1291 | tmp.hook_entry, tmp.underflow); |
1237 | if (ret != 0) | 1292 | if (ret != 0) |
1238 | goto free_newinfo_counters; | 1293 | goto free_newinfo_counters; |
@@ -1271,8 +1326,9 @@ do_replace(void __user *user, unsigned int len) | |||
1271 | /* Get the old counters. */ | 1326 | /* Get the old counters. */ |
1272 | get_counters(oldinfo, counters); | 1327 | get_counters(oldinfo, counters); |
1273 | /* Decrease module usage counts and free resource */ | 1328 | /* Decrease module usage counts and free resource */ |
1274 | IP6T_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL); | 1329 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; |
1275 | vfree(oldinfo); | 1330 | IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); |
1331 | free_table_info(oldinfo); | ||
1276 | if (copy_to_user(tmp.counters, counters, | 1332 | if (copy_to_user(tmp.counters, counters, |
1277 | sizeof(struct ip6t_counters) * tmp.num_counters) != 0) | 1333 | sizeof(struct ip6t_counters) * tmp.num_counters) != 0) |
1278 | ret = -EFAULT; | 1334 | ret = -EFAULT; |
@@ -1284,11 +1340,11 @@ do_replace(void __user *user, unsigned int len) | |||
1284 | module_put(t->me); | 1340 | module_put(t->me); |
1285 | up(&ip6t_mutex); | 1341 | up(&ip6t_mutex); |
1286 | free_newinfo_counters_untrans: | 1342 | free_newinfo_counters_untrans: |
1287 | IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry,NULL); | 1343 | IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); |
1288 | free_newinfo_counters: | 1344 | free_newinfo_counters: |
1289 | vfree(counters); | 1345 | vfree(counters); |
1290 | free_newinfo: | 1346 | free_newinfo: |
1291 | vfree(newinfo); | 1347 | free_table_info(newinfo); |
1292 | return ret; | 1348 | return ret; |
1293 | } | 1349 | } |
1294 | 1350 | ||
@@ -1321,6 +1377,7 @@ do_add_counters(void __user *user, unsigned int len) | |||
1321 | struct ip6t_counters_info tmp, *paddc; | 1377 | struct ip6t_counters_info tmp, *paddc; |
1322 | struct ip6t_table *t; | 1378 | struct ip6t_table *t; |
1323 | int ret = 0; | 1379 | int ret = 0; |
1380 | void *loc_cpu_entry; | ||
1324 | 1381 | ||
1325 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1382 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
1326 | return -EFAULT; | 1383 | return -EFAULT; |
@@ -1350,7 +1407,9 @@ do_add_counters(void __user *user, unsigned int len) | |||
1350 | } | 1407 | } |
1351 | 1408 | ||
1352 | i = 0; | 1409 | i = 0; |
1353 | IP6T_ENTRY_ITERATE(t->private->entries, | 1410 | /* Choose the copy that is on our node */ |
1411 | loc_cpu_entry = t->private->entries[smp_processor_id()]; | ||
1412 | IP6T_ENTRY_ITERATE(loc_cpu_entry, | ||
1354 | t->private->size, | 1413 | t->private->size, |
1355 | add_counter_to_entry, | 1414 | add_counter_to_entry, |
1356 | paddc->counters, | 1415 | paddc->counters, |
@@ -1543,28 +1602,29 @@ int ip6t_register_table(struct ip6t_table *table, | |||
1543 | struct ip6t_table_info *newinfo; | 1602 | struct ip6t_table_info *newinfo; |
1544 | static struct ip6t_table_info bootstrap | 1603 | static struct ip6t_table_info bootstrap |
1545 | = { 0, 0, 0, { 0 }, { 0 }, { } }; | 1604 | = { 0, 0, 0, { 0 }, { 0 }, { } }; |
1605 | void *loc_cpu_entry; | ||
1546 | 1606 | ||
1547 | newinfo = vmalloc(sizeof(struct ip6t_table_info) | 1607 | newinfo = alloc_table_info(repl->size); |
1548 | + SMP_ALIGN(repl->size) * | ||
1549 | (highest_possible_processor_id()+1)); | ||
1550 | if (!newinfo) | 1608 | if (!newinfo) |
1551 | return -ENOMEM; | 1609 | return -ENOMEM; |
1552 | 1610 | ||
1553 | memcpy(newinfo->entries, repl->entries, repl->size); | 1611 | /* choose the copy on our node/cpu */ |
1612 | loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; | ||
1613 | memcpy(loc_cpu_entry, repl->entries, repl->size); | ||
1554 | 1614 | ||
1555 | ret = translate_table(table->name, table->valid_hooks, | 1615 | ret = translate_table(table->name, table->valid_hooks, |
1556 | newinfo, repl->size, | 1616 | newinfo, loc_cpu_entry, repl->size, |
1557 | repl->num_entries, | 1617 | repl->num_entries, |
1558 | repl->hook_entry, | 1618 | repl->hook_entry, |
1559 | repl->underflow); | 1619 | repl->underflow); |
1560 | if (ret != 0) { | 1620 | if (ret != 0) { |
1561 | vfree(newinfo); | 1621 | free_table_info(newinfo); |
1562 | return ret; | 1622 | return ret; |
1563 | } | 1623 | } |
1564 | 1624 | ||
1565 | ret = down_interruptible(&ip6t_mutex); | 1625 | ret = down_interruptible(&ip6t_mutex); |
1566 | if (ret != 0) { | 1626 | if (ret != 0) { |
1567 | vfree(newinfo); | 1627 | free_table_info(newinfo); |
1568 | return ret; | 1628 | return ret; |
1569 | } | 1629 | } |
1570 | 1630 | ||
@@ -1593,20 +1653,23 @@ int ip6t_register_table(struct ip6t_table *table, | |||
1593 | return ret; | 1653 | return ret; |
1594 | 1654 | ||
1595 | free_unlock: | 1655 | free_unlock: |
1596 | vfree(newinfo); | 1656 | free_table_info(newinfo); |
1597 | goto unlock; | 1657 | goto unlock; |
1598 | } | 1658 | } |
1599 | 1659 | ||
1600 | void ip6t_unregister_table(struct ip6t_table *table) | 1660 | void ip6t_unregister_table(struct ip6t_table *table) |
1601 | { | 1661 | { |
1662 | void *loc_cpu_entry; | ||
1663 | |||
1602 | down(&ip6t_mutex); | 1664 | down(&ip6t_mutex); |
1603 | LIST_DELETE(&ip6t_tables, table); | 1665 | LIST_DELETE(&ip6t_tables, table); |
1604 | up(&ip6t_mutex); | 1666 | up(&ip6t_mutex); |
1605 | 1667 | ||
1606 | /* Decrease module usage counts and free resources */ | 1668 | /* Decrease module usage counts and free resources */ |
1607 | IP6T_ENTRY_ITERATE(table->private->entries, table->private->size, | 1669 | loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; |
1670 | IP6T_ENTRY_ITERATE(loc_cpu_entry, table->private->size, | ||
1608 | cleanup_entry, NULL); | 1671 | cleanup_entry, NULL); |
1609 | vfree(table->private); | 1672 | free_table_info(table->private); |
1610 | } | 1673 | } |
1611 | 1674 | ||
1612 | /* Returns 1 if the port is matched by the range, 0 otherwise */ | 1675 | /* Returns 1 if the port is matched by the range, 0 otherwise */ |
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c index 0cd1d1bd9033..ae4653bfd654 100644 --- a/net/ipv6/netfilter/ip6t_LOG.c +++ b/net/ipv6/netfilter/ip6t_LOG.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/moduleparam.h> | 14 | #include <linux/moduleparam.h> |
15 | #include <linux/skbuff.h> | 15 | #include <linux/skbuff.h> |
16 | #include <linux/if_arp.h> | ||
16 | #include <linux/ip.h> | 17 | #include <linux/ip.h> |
17 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
18 | #include <linux/icmpv6.h> | 19 | #include <linux/icmpv6.h> |
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c index dde37793d20b..268918d5deea 100644 --- a/net/ipv6/netfilter/ip6t_ah.c +++ b/net/ipv6/netfilter/ip6t_ah.c | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/skbuff.h> | 11 | #include <linux/skbuff.h> |
12 | #include <linux/ip.h> | ||
12 | #include <linux/ipv6.h> | 13 | #include <linux/ipv6.h> |
13 | #include <linux/types.h> | 14 | #include <linux/types.h> |
14 | #include <net/checksum.h> | 15 | #include <net/checksum.h> |
diff --git a/net/ipv6/netfilter/ip6t_esp.c b/net/ipv6/netfilter/ip6t_esp.c index 24bc0cde43a1..65937de1b58c 100644 --- a/net/ipv6/netfilter/ip6t_esp.c +++ b/net/ipv6/netfilter/ip6t_esp.c | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/skbuff.h> | 11 | #include <linux/skbuff.h> |
12 | #include <linux/ip.h> | ||
12 | #include <linux/ipv6.h> | 13 | #include <linux/ipv6.h> |
13 | #include <linux/types.h> | 14 | #include <linux/types.h> |
14 | #include <net/checksum.h> | 15 | #include <net/checksum.h> |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index c2c52af9e560..f3e5ffbd592f 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -98,7 +98,7 @@ struct nf_ct_frag6_queue | |||
98 | #define FRAG6Q_HASHSZ 64 | 98 | #define FRAG6Q_HASHSZ 64 |
99 | 99 | ||
100 | static struct nf_ct_frag6_queue *nf_ct_frag6_hash[FRAG6Q_HASHSZ]; | 100 | static struct nf_ct_frag6_queue *nf_ct_frag6_hash[FRAG6Q_HASHSZ]; |
101 | static rwlock_t nf_ct_frag6_lock = RW_LOCK_UNLOCKED; | 101 | static DEFINE_RWLOCK(nf_ct_frag6_lock); |
102 | static u32 nf_ct_frag6_hash_rnd; | 102 | static u32 nf_ct_frag6_hash_rnd; |
103 | static LIST_HEAD(nf_ct_frag6_lru_list); | 103 | static LIST_HEAD(nf_ct_frag6_lru_list); |
104 | int nf_ct_frag6_nqueues = 0; | 104 | int nf_ct_frag6_nqueues = 0; |
@@ -371,7 +371,7 @@ nf_ct_frag6_create(unsigned int hash, u32 id, struct in6_addr *src, struct | |||
371 | init_timer(&fq->timer); | 371 | init_timer(&fq->timer); |
372 | fq->timer.function = nf_ct_frag6_expire; | 372 | fq->timer.function = nf_ct_frag6_expire; |
373 | fq->timer.data = (long) fq; | 373 | fq->timer.data = (long) fq; |
374 | fq->lock = SPIN_LOCK_UNLOCKED; | 374 | spin_lock_init(&fq->lock); |
375 | atomic_set(&fq->refcnt, 1); | 375 | atomic_set(&fq->refcnt, 1); |
376 | 376 | ||
377 | return nf_ct_frag6_intern(hash, fq); | 377 | return nf_ct_frag6_intern(hash, fq); |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index a66900cda2af..66f1d12ea578 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/icmpv6.h> | 32 | #include <linux/icmpv6.h> |
33 | #include <linux/netfilter.h> | 33 | #include <linux/netfilter.h> |
34 | #include <linux/netfilter_ipv6.h> | 34 | #include <linux/netfilter_ipv6.h> |
35 | #include <linux/skbuff.h> | ||
35 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
36 | #include <asm/ioctls.h> | 37 | #include <asm/ioctls.h> |
37 | #include <asm/bug.h> | 38 | #include <asm/bug.h> |
@@ -433,25 +434,14 @@ out: | |||
433 | return err; | 434 | return err; |
434 | 435 | ||
435 | csum_copy_err: | 436 | csum_copy_err: |
436 | /* Clear queue. */ | 437 | skb_kill_datagram(sk, skb, flags); |
437 | if (flags&MSG_PEEK) { | ||
438 | int clear = 0; | ||
439 | spin_lock_bh(&sk->sk_receive_queue.lock); | ||
440 | if (skb == skb_peek(&sk->sk_receive_queue)) { | ||
441 | __skb_unlink(skb, &sk->sk_receive_queue); | ||
442 | clear = 1; | ||
443 | } | ||
444 | spin_unlock_bh(&sk->sk_receive_queue.lock); | ||
445 | if (clear) | ||
446 | kfree_skb(skb); | ||
447 | } | ||
448 | 438 | ||
449 | /* Error for blocking case is chosen to masquerade | 439 | /* Error for blocking case is chosen to masquerade |
450 | as some normal condition. | 440 | as some normal condition. |
451 | */ | 441 | */ |
452 | err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH; | 442 | err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH; |
453 | /* FIXME: increment a raw6 drops counter here */ | 443 | /* FIXME: increment a raw6 drops counter here */ |
454 | goto out_free; | 444 | goto out; |
455 | } | 445 | } |
456 | 446 | ||
457 | static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, | 447 | static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index a7a537b50595..66140f13d119 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -413,11 +413,14 @@ static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr, | |||
413 | rt = ip6_rt_copy(ort); | 413 | rt = ip6_rt_copy(ort); |
414 | 414 | ||
415 | if (rt) { | 415 | if (rt) { |
416 | ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); | 416 | if (!(rt->rt6i_flags&RTF_GATEWAY)) { |
417 | 417 | if (rt->rt6i_dst.plen != 128 && | |
418 | if (!(rt->rt6i_flags&RTF_GATEWAY)) | 418 | ipv6_addr_equal(&rt->rt6i_dst.addr, daddr)) |
419 | rt->rt6i_flags |= RTF_ANYCAST; | ||
419 | ipv6_addr_copy(&rt->rt6i_gateway, daddr); | 420 | ipv6_addr_copy(&rt->rt6i_gateway, daddr); |
421 | } | ||
420 | 422 | ||
423 | ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); | ||
421 | rt->rt6i_dst.plen = 128; | 424 | rt->rt6i_dst.plen = 128; |
422 | rt->rt6i_flags |= RTF_CACHE; | 425 | rt->rt6i_flags |= RTF_CACHE; |
423 | rt->u.dst.flags |= DST_HOST; | 426 | rt->u.dst.flags |= DST_HOST; |
@@ -829,7 +832,7 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, | |||
829 | } | 832 | } |
830 | 833 | ||
831 | rt->u.dst.obsolete = -1; | 834 | rt->u.dst.obsolete = -1; |
832 | rt->rt6i_expires = clock_t_to_jiffies(rtmsg->rtmsg_info); | 835 | rt->rt6i_expires = jiffies + clock_t_to_jiffies(rtmsg->rtmsg_info); |
833 | if (nlh && (r = NLMSG_DATA(nlh))) { | 836 | if (nlh && (r = NLMSG_DATA(nlh))) { |
834 | rt->rt6i_protocol = r->rtm_protocol; | 837 | rt->rt6i_protocol = r->rtm_protocol; |
835 | } else { | 838 | } else { |
@@ -1413,7 +1416,9 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
1413 | rt->u.dst.obsolete = -1; | 1416 | rt->u.dst.obsolete = -1; |
1414 | 1417 | ||
1415 | rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP; | 1418 | rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP; |
1416 | if (!anycast) | 1419 | if (anycast) |
1420 | rt->rt6i_flags |= RTF_ANYCAST; | ||
1421 | else | ||
1417 | rt->rt6i_flags |= RTF_LOCAL; | 1422 | rt->rt6i_flags |= RTF_LOCAL; |
1418 | rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway); | 1423 | rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway); |
1419 | if (rt->rt6i_nexthop == NULL) { | 1424 | if (rt->rt6i_nexthop == NULL) { |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 8827389abaf7..2947bc56d8a0 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <net/tcp.h> | 48 | #include <net/tcp.h> |
49 | #include <net/ndisc.h> | 49 | #include <net/ndisc.h> |
50 | #include <net/inet6_hashtables.h> | 50 | #include <net/inet6_hashtables.h> |
51 | #include <net/inet6_connection_sock.h> | ||
51 | #include <net/ipv6.h> | 52 | #include <net/ipv6.h> |
52 | #include <net/transp_v6.h> | 53 | #include <net/transp_v6.h> |
53 | #include <net/addrconf.h> | 54 | #include <net/addrconf.h> |
@@ -59,6 +60,7 @@ | |||
59 | #include <net/addrconf.h> | 60 | #include <net/addrconf.h> |
60 | #include <net/snmp.h> | 61 | #include <net/snmp.h> |
61 | #include <net/dsfield.h> | 62 | #include <net/dsfield.h> |
63 | #include <net/timewait_sock.h> | ||
62 | 64 | ||
63 | #include <asm/uaccess.h> | 65 | #include <asm/uaccess.h> |
64 | 66 | ||
@@ -67,224 +69,33 @@ | |||
67 | 69 | ||
68 | static void tcp_v6_send_reset(struct sk_buff *skb); | 70 | static void tcp_v6_send_reset(struct sk_buff *skb); |
69 | static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req); | 71 | static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req); |
70 | static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, | 72 | static void tcp_v6_send_check(struct sock *sk, int len, |
71 | struct sk_buff *skb); | 73 | struct sk_buff *skb); |
72 | 74 | ||
73 | static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); | 75 | static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); |
74 | static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok); | ||
75 | 76 | ||
76 | static struct tcp_func ipv6_mapped; | 77 | static struct inet_connection_sock_af_ops ipv6_mapped; |
77 | static struct tcp_func ipv6_specific; | 78 | static struct inet_connection_sock_af_ops ipv6_specific; |
78 | 79 | ||
79 | static inline int tcp_v6_bind_conflict(const struct sock *sk, | ||
80 | const struct inet_bind_bucket *tb) | ||
81 | { | ||
82 | const struct sock *sk2; | ||
83 | const struct hlist_node *node; | ||
84 | |||
85 | /* We must walk the whole port owner list in this case. -DaveM */ | ||
86 | sk_for_each_bound(sk2, node, &tb->owners) { | ||
87 | if (sk != sk2 && | ||
88 | (!sk->sk_bound_dev_if || | ||
89 | !sk2->sk_bound_dev_if || | ||
90 | sk->sk_bound_dev_if == sk2->sk_bound_dev_if) && | ||
91 | (!sk->sk_reuse || !sk2->sk_reuse || | ||
92 | sk2->sk_state == TCP_LISTEN) && | ||
93 | ipv6_rcv_saddr_equal(sk, sk2)) | ||
94 | break; | ||
95 | } | ||
96 | |||
97 | return node != NULL; | ||
98 | } | ||
99 | |||
100 | /* Grrr, addr_type already calculated by caller, but I don't want | ||
101 | * to add some silly "cookie" argument to this method just for that. | ||
102 | * But it doesn't matter, the recalculation is in the rarest path | ||
103 | * this function ever takes. | ||
104 | */ | ||
105 | static int tcp_v6_get_port(struct sock *sk, unsigned short snum) | 80 | static int tcp_v6_get_port(struct sock *sk, unsigned short snum) |
106 | { | 81 | { |
107 | struct inet_bind_hashbucket *head; | 82 | return inet_csk_get_port(&tcp_hashinfo, sk, snum, |
108 | struct inet_bind_bucket *tb; | 83 | inet6_csk_bind_conflict); |
109 | struct hlist_node *node; | ||
110 | int ret; | ||
111 | |||
112 | local_bh_disable(); | ||
113 | if (snum == 0) { | ||
114 | int low = sysctl_local_port_range[0]; | ||
115 | int high = sysctl_local_port_range[1]; | ||
116 | int remaining = (high - low) + 1; | ||
117 | int rover = net_random() % (high - low) + low; | ||
118 | |||
119 | do { | ||
120 | head = &tcp_hashinfo.bhash[inet_bhashfn(rover, tcp_hashinfo.bhash_size)]; | ||
121 | spin_lock(&head->lock); | ||
122 | inet_bind_bucket_for_each(tb, node, &head->chain) | ||
123 | if (tb->port == rover) | ||
124 | goto next; | ||
125 | break; | ||
126 | next: | ||
127 | spin_unlock(&head->lock); | ||
128 | if (++rover > high) | ||
129 | rover = low; | ||
130 | } while (--remaining > 0); | ||
131 | |||
132 | /* Exhausted local port range during search? It is not | ||
133 | * possible for us to be holding one of the bind hash | ||
134 | * locks if this test triggers, because if 'remaining' | ||
135 | * drops to zero, we broke out of the do/while loop at | ||
136 | * the top level, not from the 'break;' statement. | ||
137 | */ | ||
138 | ret = 1; | ||
139 | if (unlikely(remaining <= 0)) | ||
140 | goto fail; | ||
141 | |||
142 | /* OK, here is the one we will use. */ | ||
143 | snum = rover; | ||
144 | } else { | ||
145 | head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)]; | ||
146 | spin_lock(&head->lock); | ||
147 | inet_bind_bucket_for_each(tb, node, &head->chain) | ||
148 | if (tb->port == snum) | ||
149 | goto tb_found; | ||
150 | } | ||
151 | tb = NULL; | ||
152 | goto tb_not_found; | ||
153 | tb_found: | ||
154 | if (tb && !hlist_empty(&tb->owners)) { | ||
155 | if (tb->fastreuse > 0 && sk->sk_reuse && | ||
156 | sk->sk_state != TCP_LISTEN) { | ||
157 | goto success; | ||
158 | } else { | ||
159 | ret = 1; | ||
160 | if (tcp_v6_bind_conflict(sk, tb)) | ||
161 | goto fail_unlock; | ||
162 | } | ||
163 | } | ||
164 | tb_not_found: | ||
165 | ret = 1; | ||
166 | if (tb == NULL) { | ||
167 | tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, snum); | ||
168 | if (tb == NULL) | ||
169 | goto fail_unlock; | ||
170 | } | ||
171 | if (hlist_empty(&tb->owners)) { | ||
172 | if (sk->sk_reuse && sk->sk_state != TCP_LISTEN) | ||
173 | tb->fastreuse = 1; | ||
174 | else | ||
175 | tb->fastreuse = 0; | ||
176 | } else if (tb->fastreuse && | ||
177 | (!sk->sk_reuse || sk->sk_state == TCP_LISTEN)) | ||
178 | tb->fastreuse = 0; | ||
179 | |||
180 | success: | ||
181 | if (!inet_csk(sk)->icsk_bind_hash) | ||
182 | inet_bind_hash(sk, tb, snum); | ||
183 | BUG_TRAP(inet_csk(sk)->icsk_bind_hash == tb); | ||
184 | ret = 0; | ||
185 | |||
186 | fail_unlock: | ||
187 | spin_unlock(&head->lock); | ||
188 | fail: | ||
189 | local_bh_enable(); | ||
190 | return ret; | ||
191 | } | ||
192 | |||
193 | static __inline__ void __tcp_v6_hash(struct sock *sk) | ||
194 | { | ||
195 | struct hlist_head *list; | ||
196 | rwlock_t *lock; | ||
197 | |||
198 | BUG_TRAP(sk_unhashed(sk)); | ||
199 | |||
200 | if (sk->sk_state == TCP_LISTEN) { | ||
201 | list = &tcp_hashinfo.listening_hash[inet_sk_listen_hashfn(sk)]; | ||
202 | lock = &tcp_hashinfo.lhash_lock; | ||
203 | inet_listen_wlock(&tcp_hashinfo); | ||
204 | } else { | ||
205 | unsigned int hash; | ||
206 | sk->sk_hash = hash = inet6_sk_ehashfn(sk); | ||
207 | hash &= (tcp_hashinfo.ehash_size - 1); | ||
208 | list = &tcp_hashinfo.ehash[hash].chain; | ||
209 | lock = &tcp_hashinfo.ehash[hash].lock; | ||
210 | write_lock(lock); | ||
211 | } | ||
212 | |||
213 | __sk_add_node(sk, list); | ||
214 | sock_prot_inc_use(sk->sk_prot); | ||
215 | write_unlock(lock); | ||
216 | } | 84 | } |
217 | 85 | ||
218 | |||
219 | static void tcp_v6_hash(struct sock *sk) | 86 | static void tcp_v6_hash(struct sock *sk) |
220 | { | 87 | { |
221 | if (sk->sk_state != TCP_CLOSE) { | 88 | if (sk->sk_state != TCP_CLOSE) { |
222 | struct tcp_sock *tp = tcp_sk(sk); | 89 | if (inet_csk(sk)->icsk_af_ops == &ipv6_mapped) { |
223 | |||
224 | if (tp->af_specific == &ipv6_mapped) { | ||
225 | tcp_prot.hash(sk); | 90 | tcp_prot.hash(sk); |
226 | return; | 91 | return; |
227 | } | 92 | } |
228 | local_bh_disable(); | 93 | local_bh_disable(); |
229 | __tcp_v6_hash(sk); | 94 | __inet6_hash(&tcp_hashinfo, sk); |
230 | local_bh_enable(); | 95 | local_bh_enable(); |
231 | } | 96 | } |
232 | } | 97 | } |
233 | 98 | ||
234 | /* | ||
235 | * Open request hash tables. | ||
236 | */ | ||
237 | |||
238 | static u32 tcp_v6_synq_hash(const struct in6_addr *raddr, const u16 rport, const u32 rnd) | ||
239 | { | ||
240 | u32 a, b, c; | ||
241 | |||
242 | a = raddr->s6_addr32[0]; | ||
243 | b = raddr->s6_addr32[1]; | ||
244 | c = raddr->s6_addr32[2]; | ||
245 | |||
246 | a += JHASH_GOLDEN_RATIO; | ||
247 | b += JHASH_GOLDEN_RATIO; | ||
248 | c += rnd; | ||
249 | __jhash_mix(a, b, c); | ||
250 | |||
251 | a += raddr->s6_addr32[3]; | ||
252 | b += (u32) rport; | ||
253 | __jhash_mix(a, b, c); | ||
254 | |||
255 | return c & (TCP_SYNQ_HSIZE - 1); | ||
256 | } | ||
257 | |||
258 | static struct request_sock *tcp_v6_search_req(const struct sock *sk, | ||
259 | struct request_sock ***prevp, | ||
260 | __u16 rport, | ||
261 | struct in6_addr *raddr, | ||
262 | struct in6_addr *laddr, | ||
263 | int iif) | ||
264 | { | ||
265 | const struct inet_connection_sock *icsk = inet_csk(sk); | ||
266 | struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt; | ||
267 | struct request_sock *req, **prev; | ||
268 | |||
269 | for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport, lopt->hash_rnd)]; | ||
270 | (req = *prev) != NULL; | ||
271 | prev = &req->dl_next) { | ||
272 | const struct tcp6_request_sock *treq = tcp6_rsk(req); | ||
273 | |||
274 | if (inet_rsk(req)->rmt_port == rport && | ||
275 | req->rsk_ops->family == AF_INET6 && | ||
276 | ipv6_addr_equal(&treq->rmt_addr, raddr) && | ||
277 | ipv6_addr_equal(&treq->loc_addr, laddr) && | ||
278 | (!treq->iif || treq->iif == iif)) { | ||
279 | BUG_TRAP(req->sk == NULL); | ||
280 | *prevp = prev; | ||
281 | return req; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | return NULL; | ||
286 | } | ||
287 | |||
288 | static __inline__ u16 tcp_v6_check(struct tcphdr *th, int len, | 99 | static __inline__ u16 tcp_v6_check(struct tcphdr *th, int len, |
289 | struct in6_addr *saddr, | 100 | struct in6_addr *saddr, |
290 | struct in6_addr *daddr, | 101 | struct in6_addr *daddr, |
@@ -308,195 +119,12 @@ static __u32 tcp_v6_init_sequence(struct sock *sk, struct sk_buff *skb) | |||
308 | } | 119 | } |
309 | } | 120 | } |
310 | 121 | ||
311 | static int __tcp_v6_check_established(struct sock *sk, const __u16 lport, | ||
312 | struct inet_timewait_sock **twp) | ||
313 | { | ||
314 | struct inet_sock *inet = inet_sk(sk); | ||
315 | const struct ipv6_pinfo *np = inet6_sk(sk); | ||
316 | const struct in6_addr *daddr = &np->rcv_saddr; | ||
317 | const struct in6_addr *saddr = &np->daddr; | ||
318 | const int dif = sk->sk_bound_dev_if; | ||
319 | const u32 ports = INET_COMBINED_PORTS(inet->dport, lport); | ||
320 | unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr, inet->dport); | ||
321 | struct inet_ehash_bucket *head = inet_ehash_bucket(&tcp_hashinfo, hash); | ||
322 | struct sock *sk2; | ||
323 | const struct hlist_node *node; | ||
324 | struct inet_timewait_sock *tw; | ||
325 | |||
326 | prefetch(head->chain.first); | ||
327 | write_lock(&head->lock); | ||
328 | |||
329 | /* Check TIME-WAIT sockets first. */ | ||
330 | sk_for_each(sk2, node, &(head + tcp_hashinfo.ehash_size)->chain) { | ||
331 | const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk2); | ||
332 | |||
333 | tw = inet_twsk(sk2); | ||
334 | |||
335 | if(*((__u32 *)&(tw->tw_dport)) == ports && | ||
336 | sk2->sk_family == PF_INET6 && | ||
337 | ipv6_addr_equal(&tcp6tw->tw_v6_daddr, saddr) && | ||
338 | ipv6_addr_equal(&tcp6tw->tw_v6_rcv_saddr, daddr) && | ||
339 | sk2->sk_bound_dev_if == sk->sk_bound_dev_if) { | ||
340 | const struct tcp_timewait_sock *tcptw = tcp_twsk(sk2); | ||
341 | struct tcp_sock *tp = tcp_sk(sk); | ||
342 | |||
343 | if (tcptw->tw_ts_recent_stamp && | ||
344 | (!twp || | ||
345 | (sysctl_tcp_tw_reuse && | ||
346 | xtime.tv_sec - tcptw->tw_ts_recent_stamp > 1))) { | ||
347 | /* See comment in tcp_ipv4.c */ | ||
348 | tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2; | ||
349 | if (!tp->write_seq) | ||
350 | tp->write_seq = 1; | ||
351 | tp->rx_opt.ts_recent = tcptw->tw_ts_recent; | ||
352 | tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp; | ||
353 | sock_hold(sk2); | ||
354 | goto unique; | ||
355 | } else | ||
356 | goto not_unique; | ||
357 | } | ||
358 | } | ||
359 | tw = NULL; | ||
360 | |||
361 | /* And established part... */ | ||
362 | sk_for_each(sk2, node, &head->chain) { | ||
363 | if (INET6_MATCH(sk2, hash, saddr, daddr, ports, dif)) | ||
364 | goto not_unique; | ||
365 | } | ||
366 | |||
367 | unique: | ||
368 | BUG_TRAP(sk_unhashed(sk)); | ||
369 | __sk_add_node(sk, &head->chain); | ||
370 | sk->sk_hash = hash; | ||
371 | sock_prot_inc_use(sk->sk_prot); | ||
372 | write_unlock(&head->lock); | ||
373 | |||
374 | if (twp) { | ||
375 | *twp = tw; | ||
376 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); | ||
377 | } else if (tw) { | ||
378 | /* Silly. Should hash-dance instead... */ | ||
379 | inet_twsk_deschedule(tw, &tcp_death_row); | ||
380 | NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED); | ||
381 | |||
382 | inet_twsk_put(tw); | ||
383 | } | ||
384 | return 0; | ||
385 | |||
386 | not_unique: | ||
387 | write_unlock(&head->lock); | ||
388 | return -EADDRNOTAVAIL; | ||
389 | } | ||
390 | |||
391 | static inline u32 tcpv6_port_offset(const struct sock *sk) | ||
392 | { | ||
393 | const struct inet_sock *inet = inet_sk(sk); | ||
394 | const struct ipv6_pinfo *np = inet6_sk(sk); | ||
395 | |||
396 | return secure_tcpv6_port_ephemeral(np->rcv_saddr.s6_addr32, | ||
397 | np->daddr.s6_addr32, | ||
398 | inet->dport); | ||
399 | } | ||
400 | |||
401 | static int tcp_v6_hash_connect(struct sock *sk) | ||
402 | { | ||
403 | unsigned short snum = inet_sk(sk)->num; | ||
404 | struct inet_bind_hashbucket *head; | ||
405 | struct inet_bind_bucket *tb; | ||
406 | int ret; | ||
407 | |||
408 | if (!snum) { | ||
409 | int low = sysctl_local_port_range[0]; | ||
410 | int high = sysctl_local_port_range[1]; | ||
411 | int range = high - low; | ||
412 | int i; | ||
413 | int port; | ||
414 | static u32 hint; | ||
415 | u32 offset = hint + tcpv6_port_offset(sk); | ||
416 | struct hlist_node *node; | ||
417 | struct inet_timewait_sock *tw = NULL; | ||
418 | |||
419 | local_bh_disable(); | ||
420 | for (i = 1; i <= range; i++) { | ||
421 | port = low + (i + offset) % range; | ||
422 | head = &tcp_hashinfo.bhash[inet_bhashfn(port, tcp_hashinfo.bhash_size)]; | ||
423 | spin_lock(&head->lock); | ||
424 | |||
425 | /* Does not bother with rcv_saddr checks, | ||
426 | * because the established check is already | ||
427 | * unique enough. | ||
428 | */ | ||
429 | inet_bind_bucket_for_each(tb, node, &head->chain) { | ||
430 | if (tb->port == port) { | ||
431 | BUG_TRAP(!hlist_empty(&tb->owners)); | ||
432 | if (tb->fastreuse >= 0) | ||
433 | goto next_port; | ||
434 | if (!__tcp_v6_check_established(sk, | ||
435 | port, | ||
436 | &tw)) | ||
437 | goto ok; | ||
438 | goto next_port; | ||
439 | } | ||
440 | } | ||
441 | |||
442 | tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, port); | ||
443 | if (!tb) { | ||
444 | spin_unlock(&head->lock); | ||
445 | break; | ||
446 | } | ||
447 | tb->fastreuse = -1; | ||
448 | goto ok; | ||
449 | |||
450 | next_port: | ||
451 | spin_unlock(&head->lock); | ||
452 | } | ||
453 | local_bh_enable(); | ||
454 | |||
455 | return -EADDRNOTAVAIL; | ||
456 | |||
457 | ok: | ||
458 | hint += i; | ||
459 | |||
460 | /* Head lock still held and bh's disabled */ | ||
461 | inet_bind_hash(sk, tb, port); | ||
462 | if (sk_unhashed(sk)) { | ||
463 | inet_sk(sk)->sport = htons(port); | ||
464 | __tcp_v6_hash(sk); | ||
465 | } | ||
466 | spin_unlock(&head->lock); | ||
467 | |||
468 | if (tw) { | ||
469 | inet_twsk_deschedule(tw, &tcp_death_row); | ||
470 | inet_twsk_put(tw); | ||
471 | } | ||
472 | |||
473 | ret = 0; | ||
474 | goto out; | ||
475 | } | ||
476 | |||
477 | head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)]; | ||
478 | tb = inet_csk(sk)->icsk_bind_hash; | ||
479 | spin_lock_bh(&head->lock); | ||
480 | |||
481 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { | ||
482 | __tcp_v6_hash(sk); | ||
483 | spin_unlock_bh(&head->lock); | ||
484 | return 0; | ||
485 | } else { | ||
486 | spin_unlock(&head->lock); | ||
487 | /* No definite answer... Walk to established hash table */ | ||
488 | ret = __tcp_v6_check_established(sk, snum, NULL); | ||
489 | out: | ||
490 | local_bh_enable(); | ||
491 | return ret; | ||
492 | } | ||
493 | } | ||
494 | |||
495 | static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | 122 | static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, |
496 | int addr_len) | 123 | int addr_len) |
497 | { | 124 | { |
498 | struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; | 125 | struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; |
499 | struct inet_sock *inet = inet_sk(sk); | 126 | struct inet_sock *inet = inet_sk(sk); |
127 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
500 | struct ipv6_pinfo *np = inet6_sk(sk); | 128 | struct ipv6_pinfo *np = inet6_sk(sk); |
501 | struct tcp_sock *tp = tcp_sk(sk); | 129 | struct tcp_sock *tp = tcp_sk(sk); |
502 | struct in6_addr *saddr = NULL, *final_p = NULL, final; | 130 | struct in6_addr *saddr = NULL, *final_p = NULL, final; |
@@ -571,7 +199,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
571 | */ | 199 | */ |
572 | 200 | ||
573 | if (addr_type == IPV6_ADDR_MAPPED) { | 201 | if (addr_type == IPV6_ADDR_MAPPED) { |
574 | u32 exthdrlen = tp->ext_header_len; | 202 | u32 exthdrlen = icsk->icsk_ext_hdr_len; |
575 | struct sockaddr_in sin; | 203 | struct sockaddr_in sin; |
576 | 204 | ||
577 | SOCK_DEBUG(sk, "connect: ipv4 mapped\n"); | 205 | SOCK_DEBUG(sk, "connect: ipv4 mapped\n"); |
@@ -583,14 +211,14 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
583 | sin.sin_port = usin->sin6_port; | 211 | sin.sin_port = usin->sin6_port; |
584 | sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3]; | 212 | sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3]; |
585 | 213 | ||
586 | tp->af_specific = &ipv6_mapped; | 214 | icsk->icsk_af_ops = &ipv6_mapped; |
587 | sk->sk_backlog_rcv = tcp_v4_do_rcv; | 215 | sk->sk_backlog_rcv = tcp_v4_do_rcv; |
588 | 216 | ||
589 | err = tcp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin)); | 217 | err = tcp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin)); |
590 | 218 | ||
591 | if (err) { | 219 | if (err) { |
592 | tp->ext_header_len = exthdrlen; | 220 | icsk->icsk_ext_hdr_len = exthdrlen; |
593 | tp->af_specific = &ipv6_specific; | 221 | icsk->icsk_af_ops = &ipv6_specific; |
594 | sk->sk_backlog_rcv = tcp_v6_do_rcv; | 222 | sk->sk_backlog_rcv = tcp_v6_do_rcv; |
595 | goto failure; | 223 | goto failure; |
596 | } else { | 224 | } else { |
@@ -643,16 +271,17 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
643 | sk->sk_route_caps = dst->dev->features & | 271 | sk->sk_route_caps = dst->dev->features & |
644 | ~(NETIF_F_IP_CSUM | NETIF_F_TSO); | 272 | ~(NETIF_F_IP_CSUM | NETIF_F_TSO); |
645 | 273 | ||
646 | tp->ext_header_len = 0; | 274 | icsk->icsk_ext_hdr_len = 0; |
647 | if (np->opt) | 275 | if (np->opt) |
648 | tp->ext_header_len = np->opt->opt_flen + np->opt->opt_nflen; | 276 | icsk->icsk_ext_hdr_len = (np->opt->opt_flen + |
277 | np->opt->opt_nflen); | ||
649 | 278 | ||
650 | tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); | 279 | tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); |
651 | 280 | ||
652 | inet->dport = usin->sin6_port; | 281 | inet->dport = usin->sin6_port; |
653 | 282 | ||
654 | tcp_set_state(sk, TCP_SYN_SENT); | 283 | tcp_set_state(sk, TCP_SYN_SENT); |
655 | err = tcp_v6_hash_connect(sk); | 284 | err = inet6_hash_connect(&tcp_death_row, sk); |
656 | if (err) | 285 | if (err) |
657 | goto late_failure; | 286 | goto late_failure; |
658 | 287 | ||
@@ -758,7 +387,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
758 | } else | 387 | } else |
759 | dst_hold(dst); | 388 | dst_hold(dst); |
760 | 389 | ||
761 | if (tp->pmtu_cookie > dst_mtu(dst)) { | 390 | if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) { |
762 | tcp_sync_mss(sk, dst_mtu(dst)); | 391 | tcp_sync_mss(sk, dst_mtu(dst)); |
763 | tcp_simple_retransmit(sk); | 392 | tcp_simple_retransmit(sk); |
764 | } /* else let the usual retransmit timer handle it */ | 393 | } /* else let the usual retransmit timer handle it */ |
@@ -775,8 +404,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
775 | if (sock_owned_by_user(sk)) | 404 | if (sock_owned_by_user(sk)) |
776 | goto out; | 405 | goto out; |
777 | 406 | ||
778 | req = tcp_v6_search_req(sk, &prev, th->dest, &hdr->daddr, | 407 | req = inet6_csk_search_req(sk, &prev, th->dest, &hdr->daddr, |
779 | &hdr->saddr, inet6_iif(skb)); | 408 | &hdr->saddr, inet6_iif(skb)); |
780 | if (!req) | 409 | if (!req) |
781 | goto out; | 410 | goto out; |
782 | 411 | ||
@@ -822,7 +451,7 @@ out: | |||
822 | static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | 451 | static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, |
823 | struct dst_entry *dst) | 452 | struct dst_entry *dst) |
824 | { | 453 | { |
825 | struct tcp6_request_sock *treq = tcp6_rsk(req); | 454 | struct inet6_request_sock *treq = inet6_rsk(req); |
826 | struct ipv6_pinfo *np = inet6_sk(sk); | 455 | struct ipv6_pinfo *np = inet6_sk(sk); |
827 | struct sk_buff * skb; | 456 | struct sk_buff * skb; |
828 | struct ipv6_txoptions *opt = NULL; | 457 | struct ipv6_txoptions *opt = NULL; |
@@ -888,8 +517,8 @@ done: | |||
888 | 517 | ||
889 | static void tcp_v6_reqsk_destructor(struct request_sock *req) | 518 | static void tcp_v6_reqsk_destructor(struct request_sock *req) |
890 | { | 519 | { |
891 | if (tcp6_rsk(req)->pktopts) | 520 | if (inet6_rsk(req)->pktopts) |
892 | kfree_skb(tcp6_rsk(req)->pktopts); | 521 | kfree_skb(inet6_rsk(req)->pktopts); |
893 | } | 522 | } |
894 | 523 | ||
895 | static struct request_sock_ops tcp6_request_sock_ops = { | 524 | static struct request_sock_ops tcp6_request_sock_ops = { |
@@ -901,26 +530,15 @@ static struct request_sock_ops tcp6_request_sock_ops = { | |||
901 | .send_reset = tcp_v6_send_reset | 530 | .send_reset = tcp_v6_send_reset |
902 | }; | 531 | }; |
903 | 532 | ||
904 | static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb) | 533 | static struct timewait_sock_ops tcp6_timewait_sock_ops = { |
905 | { | 534 | .twsk_obj_size = sizeof(struct tcp6_timewait_sock), |
906 | struct ipv6_pinfo *np = inet6_sk(sk); | 535 | .twsk_unique = tcp_twsk_unique, |
907 | struct inet6_skb_parm *opt = IP6CB(skb); | 536 | }; |
908 | |||
909 | if (np->rxopt.all) { | ||
910 | if ((opt->hop && (np->rxopt.bits.hopopts || np->rxopt.bits.ohopopts)) || | ||
911 | ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) && np->rxopt.bits.rxflow) || | ||
912 | (opt->srcrt && (np->rxopt.bits.srcrt || np->rxopt.bits.osrcrt)) || | ||
913 | ((opt->dst1 || opt->dst0) && (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts))) | ||
914 | return 1; | ||
915 | } | ||
916 | return 0; | ||
917 | } | ||
918 | |||
919 | 537 | ||
920 | static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, | 538 | static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb) |
921 | struct sk_buff *skb) | ||
922 | { | 539 | { |
923 | struct ipv6_pinfo *np = inet6_sk(sk); | 540 | struct ipv6_pinfo *np = inet6_sk(sk); |
541 | struct tcphdr *th = skb->h.th; | ||
924 | 542 | ||
925 | if (skb->ip_summed == CHECKSUM_HW) { | 543 | if (skb->ip_summed == CHECKSUM_HW) { |
926 | th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 0); | 544 | th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 0); |
@@ -1091,8 +709,9 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) | |||
1091 | struct sock *nsk; | 709 | struct sock *nsk; |
1092 | 710 | ||
1093 | /* Find possible connection requests. */ | 711 | /* Find possible connection requests. */ |
1094 | req = tcp_v6_search_req(sk, &prev, th->source, &skb->nh.ipv6h->saddr, | 712 | req = inet6_csk_search_req(sk, &prev, th->source, |
1095 | &skb->nh.ipv6h->daddr, inet6_iif(skb)); | 713 | &skb->nh.ipv6h->saddr, |
714 | &skb->nh.ipv6h->daddr, inet6_iif(skb)); | ||
1096 | if (req) | 715 | if (req) |
1097 | return tcp_check_req(sk, skb, req, prev); | 716 | return tcp_check_req(sk, skb, req, prev); |
1098 | 717 | ||
@@ -1116,23 +735,12 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) | |||
1116 | return sk; | 735 | return sk; |
1117 | } | 736 | } |
1118 | 737 | ||
1119 | static void tcp_v6_synq_add(struct sock *sk, struct request_sock *req) | ||
1120 | { | ||
1121 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
1122 | struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt; | ||
1123 | const u32 h = tcp_v6_synq_hash(&tcp6_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd); | ||
1124 | |||
1125 | reqsk_queue_hash_req(&icsk->icsk_accept_queue, h, req, TCP_TIMEOUT_INIT); | ||
1126 | inet_csk_reqsk_queue_added(sk, TCP_TIMEOUT_INIT); | ||
1127 | } | ||
1128 | |||
1129 | |||
1130 | /* FIXME: this is substantially similar to the ipv4 code. | 738 | /* FIXME: this is substantially similar to the ipv4 code. |
1131 | * Can some kind of merge be done? -- erics | 739 | * Can some kind of merge be done? -- erics |
1132 | */ | 740 | */ |
1133 | static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | 741 | static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) |
1134 | { | 742 | { |
1135 | struct tcp6_request_sock *treq; | 743 | struct inet6_request_sock *treq; |
1136 | struct ipv6_pinfo *np = inet6_sk(sk); | 744 | struct ipv6_pinfo *np = inet6_sk(sk); |
1137 | struct tcp_options_received tmp_opt; | 745 | struct tcp_options_received tmp_opt; |
1138 | struct tcp_sock *tp = tcp_sk(sk); | 746 | struct tcp_sock *tp = tcp_sk(sk); |
@@ -1157,7 +765,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1157 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) | 765 | if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) |
1158 | goto drop; | 766 | goto drop; |
1159 | 767 | ||
1160 | req = reqsk_alloc(&tcp6_request_sock_ops); | 768 | req = inet6_reqsk_alloc(&tcp6_request_sock_ops); |
1161 | if (req == NULL) | 769 | if (req == NULL) |
1162 | goto drop; | 770 | goto drop; |
1163 | 771 | ||
@@ -1170,7 +778,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1170 | tmp_opt.tstamp_ok = tmp_opt.saw_tstamp; | 778 | tmp_opt.tstamp_ok = tmp_opt.saw_tstamp; |
1171 | tcp_openreq_init(req, &tmp_opt, skb); | 779 | tcp_openreq_init(req, &tmp_opt, skb); |
1172 | 780 | ||
1173 | treq = tcp6_rsk(req); | 781 | treq = inet6_rsk(req); |
1174 | ipv6_addr_copy(&treq->rmt_addr, &skb->nh.ipv6h->saddr); | 782 | ipv6_addr_copy(&treq->rmt_addr, &skb->nh.ipv6h->saddr); |
1175 | ipv6_addr_copy(&treq->loc_addr, &skb->nh.ipv6h->daddr); | 783 | ipv6_addr_copy(&treq->loc_addr, &skb->nh.ipv6h->daddr); |
1176 | TCP_ECN_create_request(req, skb->h.th); | 784 | TCP_ECN_create_request(req, skb->h.th); |
@@ -1196,8 +804,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1196 | if (tcp_v6_send_synack(sk, req, NULL)) | 804 | if (tcp_v6_send_synack(sk, req, NULL)) |
1197 | goto drop; | 805 | goto drop; |
1198 | 806 | ||
1199 | tcp_v6_synq_add(sk, req); | 807 | inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); |
1200 | |||
1201 | return 0; | 808 | return 0; |
1202 | 809 | ||
1203 | drop: | 810 | drop: |
@@ -1212,7 +819,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1212 | struct request_sock *req, | 819 | struct request_sock *req, |
1213 | struct dst_entry *dst) | 820 | struct dst_entry *dst) |
1214 | { | 821 | { |
1215 | struct tcp6_request_sock *treq = tcp6_rsk(req); | 822 | struct inet6_request_sock *treq = inet6_rsk(req); |
1216 | struct ipv6_pinfo *newnp, *np = inet6_sk(sk); | 823 | struct ipv6_pinfo *newnp, *np = inet6_sk(sk); |
1217 | struct tcp6_sock *newtcp6sk; | 824 | struct tcp6_sock *newtcp6sk; |
1218 | struct inet_sock *newinet; | 825 | struct inet_sock *newinet; |
@@ -1247,7 +854,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1247 | 854 | ||
1248 | ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr); | 855 | ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr); |
1249 | 856 | ||
1250 | newtp->af_specific = &ipv6_mapped; | 857 | inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; |
1251 | newsk->sk_backlog_rcv = tcp_v4_do_rcv; | 858 | newsk->sk_backlog_rcv = tcp_v4_do_rcv; |
1252 | newnp->pktoptions = NULL; | 859 | newnp->pktoptions = NULL; |
1253 | newnp->opt = NULL; | 860 | newnp->opt = NULL; |
@@ -1261,10 +868,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1261 | */ | 868 | */ |
1262 | 869 | ||
1263 | /* It is tricky place. Until this moment IPv4 tcp | 870 | /* It is tricky place. Until this moment IPv4 tcp |
1264 | worked with IPv6 af_tcp.af_specific. | 871 | worked with IPv6 icsk.icsk_af_ops. |
1265 | Sync it now. | 872 | Sync it now. |
1266 | */ | 873 | */ |
1267 | tcp_sync_mss(newsk, newtp->pmtu_cookie); | 874 | tcp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie); |
1268 | 875 | ||
1269 | return newsk; | 876 | return newsk; |
1270 | } | 877 | } |
@@ -1371,10 +978,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1371 | sock_kfree_s(sk, opt, opt->tot_len); | 978 | sock_kfree_s(sk, opt, opt->tot_len); |
1372 | } | 979 | } |
1373 | 980 | ||
1374 | newtp->ext_header_len = 0; | 981 | inet_csk(newsk)->icsk_ext_hdr_len = 0; |
1375 | if (newnp->opt) | 982 | if (newnp->opt) |
1376 | newtp->ext_header_len = newnp->opt->opt_nflen + | 983 | inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + |
1377 | newnp->opt->opt_flen; | 984 | newnp->opt->opt_flen); |
1378 | 985 | ||
1379 | tcp_sync_mss(newsk, dst_mtu(dst)); | 986 | tcp_sync_mss(newsk, dst_mtu(dst)); |
1380 | newtp->advmss = dst_metric(dst, RTAX_ADVMSS); | 987 | newtp->advmss = dst_metric(dst, RTAX_ADVMSS); |
@@ -1382,7 +989,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1382 | 989 | ||
1383 | newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6; | 990 | newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6; |
1384 | 991 | ||
1385 | __tcp_v6_hash(newsk); | 992 | __inet6_hash(&tcp_hashinfo, newsk); |
1386 | inet_inherit_port(&tcp_hashinfo, sk, newsk); | 993 | inet_inherit_port(&tcp_hashinfo, sk, newsk); |
1387 | 994 | ||
1388 | return newsk; | 995 | return newsk; |
@@ -1679,139 +1286,16 @@ do_time_wait: | |||
1679 | goto discard_it; | 1286 | goto discard_it; |
1680 | } | 1287 | } |
1681 | 1288 | ||
1682 | static int tcp_v6_rebuild_header(struct sock *sk) | ||
1683 | { | ||
1684 | int err; | ||
1685 | struct dst_entry *dst; | ||
1686 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
1687 | |||
1688 | dst = __sk_dst_check(sk, np->dst_cookie); | ||
1689 | |||
1690 | if (dst == NULL) { | ||
1691 | struct inet_sock *inet = inet_sk(sk); | ||
1692 | struct in6_addr *final_p = NULL, final; | ||
1693 | struct flowi fl; | ||
1694 | |||
1695 | memset(&fl, 0, sizeof(fl)); | ||
1696 | fl.proto = IPPROTO_TCP; | ||
1697 | ipv6_addr_copy(&fl.fl6_dst, &np->daddr); | ||
1698 | ipv6_addr_copy(&fl.fl6_src, &np->saddr); | ||
1699 | fl.fl6_flowlabel = np->flow_label; | ||
1700 | fl.oif = sk->sk_bound_dev_if; | ||
1701 | fl.fl_ip_dport = inet->dport; | ||
1702 | fl.fl_ip_sport = inet->sport; | ||
1703 | |||
1704 | if (np->opt && np->opt->srcrt) { | ||
1705 | struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; | ||
1706 | ipv6_addr_copy(&final, &fl.fl6_dst); | ||
1707 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); | ||
1708 | final_p = &final; | ||
1709 | } | ||
1710 | |||
1711 | err = ip6_dst_lookup(sk, &dst, &fl); | ||
1712 | if (err) { | ||
1713 | sk->sk_route_caps = 0; | ||
1714 | return err; | ||
1715 | } | ||
1716 | if (final_p) | ||
1717 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
1718 | |||
1719 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | ||
1720 | sk->sk_err_soft = -err; | ||
1721 | return err; | ||
1722 | } | ||
1723 | |||
1724 | ip6_dst_store(sk, dst, NULL); | ||
1725 | sk->sk_route_caps = dst->dev->features & | ||
1726 | ~(NETIF_F_IP_CSUM | NETIF_F_TSO); | ||
1727 | } | ||
1728 | |||
1729 | return 0; | ||
1730 | } | ||
1731 | |||
1732 | static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok) | ||
1733 | { | ||
1734 | struct sock *sk = skb->sk; | ||
1735 | struct inet_sock *inet = inet_sk(sk); | ||
1736 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
1737 | struct flowi fl; | ||
1738 | struct dst_entry *dst; | ||
1739 | struct in6_addr *final_p = NULL, final; | ||
1740 | |||
1741 | memset(&fl, 0, sizeof(fl)); | ||
1742 | fl.proto = IPPROTO_TCP; | ||
1743 | ipv6_addr_copy(&fl.fl6_dst, &np->daddr); | ||
1744 | ipv6_addr_copy(&fl.fl6_src, &np->saddr); | ||
1745 | fl.fl6_flowlabel = np->flow_label; | ||
1746 | IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel); | ||
1747 | fl.oif = sk->sk_bound_dev_if; | ||
1748 | fl.fl_ip_sport = inet->sport; | ||
1749 | fl.fl_ip_dport = inet->dport; | ||
1750 | |||
1751 | if (np->opt && np->opt->srcrt) { | ||
1752 | struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; | ||
1753 | ipv6_addr_copy(&final, &fl.fl6_dst); | ||
1754 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); | ||
1755 | final_p = &final; | ||
1756 | } | ||
1757 | |||
1758 | dst = __sk_dst_check(sk, np->dst_cookie); | ||
1759 | |||
1760 | if (dst == NULL) { | ||
1761 | int err = ip6_dst_lookup(sk, &dst, &fl); | ||
1762 | |||
1763 | if (err) { | ||
1764 | sk->sk_err_soft = -err; | ||
1765 | return err; | ||
1766 | } | ||
1767 | |||
1768 | if (final_p) | ||
1769 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
1770 | |||
1771 | if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) { | ||
1772 | sk->sk_route_caps = 0; | ||
1773 | return err; | ||
1774 | } | ||
1775 | |||
1776 | ip6_dst_store(sk, dst, NULL); | ||
1777 | sk->sk_route_caps = dst->dev->features & | ||
1778 | ~(NETIF_F_IP_CSUM | NETIF_F_TSO); | ||
1779 | } | ||
1780 | |||
1781 | skb->dst = dst_clone(dst); | ||
1782 | |||
1783 | /* Restore final destination back after routing done */ | ||
1784 | ipv6_addr_copy(&fl.fl6_dst, &np->daddr); | ||
1785 | |||
1786 | return ip6_xmit(sk, skb, &fl, np->opt, 0); | ||
1787 | } | ||
1788 | |||
1789 | static void v6_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr) | ||
1790 | { | ||
1791 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
1792 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr; | ||
1793 | |||
1794 | sin6->sin6_family = AF_INET6; | ||
1795 | ipv6_addr_copy(&sin6->sin6_addr, &np->daddr); | ||
1796 | sin6->sin6_port = inet_sk(sk)->dport; | ||
1797 | /* We do not store received flowlabel for TCP */ | ||
1798 | sin6->sin6_flowinfo = 0; | ||
1799 | sin6->sin6_scope_id = 0; | ||
1800 | if (sk->sk_bound_dev_if && | ||
1801 | ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) | ||
1802 | sin6->sin6_scope_id = sk->sk_bound_dev_if; | ||
1803 | } | ||
1804 | |||
1805 | static int tcp_v6_remember_stamp(struct sock *sk) | 1289 | static int tcp_v6_remember_stamp(struct sock *sk) |
1806 | { | 1290 | { |
1807 | /* Alas, not yet... */ | 1291 | /* Alas, not yet... */ |
1808 | return 0; | 1292 | return 0; |
1809 | } | 1293 | } |
1810 | 1294 | ||
1811 | static struct tcp_func ipv6_specific = { | 1295 | static struct inet_connection_sock_af_ops ipv6_specific = { |
1812 | .queue_xmit = tcp_v6_xmit, | 1296 | .queue_xmit = inet6_csk_xmit, |
1813 | .send_check = tcp_v6_send_check, | 1297 | .send_check = tcp_v6_send_check, |
1814 | .rebuild_header = tcp_v6_rebuild_header, | 1298 | .rebuild_header = inet6_sk_rebuild_header, |
1815 | .conn_request = tcp_v6_conn_request, | 1299 | .conn_request = tcp_v6_conn_request, |
1816 | .syn_recv_sock = tcp_v6_syn_recv_sock, | 1300 | .syn_recv_sock = tcp_v6_syn_recv_sock, |
1817 | .remember_stamp = tcp_v6_remember_stamp, | 1301 | .remember_stamp = tcp_v6_remember_stamp, |
@@ -1819,7 +1303,7 @@ static struct tcp_func ipv6_specific = { | |||
1819 | 1303 | ||
1820 | .setsockopt = ipv6_setsockopt, | 1304 | .setsockopt = ipv6_setsockopt, |
1821 | .getsockopt = ipv6_getsockopt, | 1305 | .getsockopt = ipv6_getsockopt, |
1822 | .addr2sockaddr = v6_addr2sockaddr, | 1306 | .addr2sockaddr = inet6_csk_addr2sockaddr, |
1823 | .sockaddr_len = sizeof(struct sockaddr_in6) | 1307 | .sockaddr_len = sizeof(struct sockaddr_in6) |
1824 | }; | 1308 | }; |
1825 | 1309 | ||
@@ -1827,7 +1311,7 @@ static struct tcp_func ipv6_specific = { | |||
1827 | * TCP over IPv4 via INET6 API | 1311 | * TCP over IPv4 via INET6 API |
1828 | */ | 1312 | */ |
1829 | 1313 | ||
1830 | static struct tcp_func ipv6_mapped = { | 1314 | static struct inet_connection_sock_af_ops ipv6_mapped = { |
1831 | .queue_xmit = ip_queue_xmit, | 1315 | .queue_xmit = ip_queue_xmit, |
1832 | .send_check = tcp_v4_send_check, | 1316 | .send_check = tcp_v4_send_check, |
1833 | .rebuild_header = inet_sk_rebuild_header, | 1317 | .rebuild_header = inet_sk_rebuild_header, |
@@ -1838,7 +1322,7 @@ static struct tcp_func ipv6_mapped = { | |||
1838 | 1322 | ||
1839 | .setsockopt = ipv6_setsockopt, | 1323 | .setsockopt = ipv6_setsockopt, |
1840 | .getsockopt = ipv6_getsockopt, | 1324 | .getsockopt = ipv6_getsockopt, |
1841 | .addr2sockaddr = v6_addr2sockaddr, | 1325 | .addr2sockaddr = inet6_csk_addr2sockaddr, |
1842 | .sockaddr_len = sizeof(struct sockaddr_in6) | 1326 | .sockaddr_len = sizeof(struct sockaddr_in6) |
1843 | }; | 1327 | }; |
1844 | 1328 | ||
@@ -1877,8 +1361,9 @@ static int tcp_v6_init_sock(struct sock *sk) | |||
1877 | 1361 | ||
1878 | sk->sk_state = TCP_CLOSE; | 1362 | sk->sk_state = TCP_CLOSE; |
1879 | 1363 | ||
1880 | tp->af_specific = &ipv6_specific; | 1364 | icsk->icsk_af_ops = &ipv6_specific; |
1881 | icsk->icsk_ca_ops = &tcp_init_congestion_ops; | 1365 | icsk->icsk_ca_ops = &tcp_init_congestion_ops; |
1366 | icsk->icsk_sync_mss = tcp_sync_mss; | ||
1882 | sk->sk_write_space = sk_stream_write_space; | 1367 | sk->sk_write_space = sk_stream_write_space; |
1883 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); | 1368 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); |
1884 | 1369 | ||
@@ -1900,14 +1385,13 @@ static int tcp_v6_destroy_sock(struct sock *sk) | |||
1900 | static void get_openreq6(struct seq_file *seq, | 1385 | static void get_openreq6(struct seq_file *seq, |
1901 | struct sock *sk, struct request_sock *req, int i, int uid) | 1386 | struct sock *sk, struct request_sock *req, int i, int uid) |
1902 | { | 1387 | { |
1903 | struct in6_addr *dest, *src; | ||
1904 | int ttd = req->expires - jiffies; | 1388 | int ttd = req->expires - jiffies; |
1389 | struct in6_addr *src = &inet6_rsk(req)->loc_addr; | ||
1390 | struct in6_addr *dest = &inet6_rsk(req)->rmt_addr; | ||
1905 | 1391 | ||
1906 | if (ttd < 0) | 1392 | if (ttd < 0) |
1907 | ttd = 0; | 1393 | ttd = 0; |
1908 | 1394 | ||
1909 | src = &tcp6_rsk(req)->loc_addr; | ||
1910 | dest = &tcp6_rsk(req)->rmt_addr; | ||
1911 | seq_printf(seq, | 1395 | seq_printf(seq, |
1912 | "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " | 1396 | "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " |
1913 | "%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p\n", | 1397 | "%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p\n", |
@@ -1988,14 +1472,14 @@ static void get_timewait6_sock(struct seq_file *seq, | |||
1988 | { | 1472 | { |
1989 | struct in6_addr *dest, *src; | 1473 | struct in6_addr *dest, *src; |
1990 | __u16 destp, srcp; | 1474 | __u16 destp, srcp; |
1991 | struct tcp6_timewait_sock *tcp6tw = tcp6_twsk((struct sock *)tw); | 1475 | struct inet6_timewait_sock *tw6 = inet6_twsk((struct sock *)tw); |
1992 | int ttd = tw->tw_ttd - jiffies; | 1476 | int ttd = tw->tw_ttd - jiffies; |
1993 | 1477 | ||
1994 | if (ttd < 0) | 1478 | if (ttd < 0) |
1995 | ttd = 0; | 1479 | ttd = 0; |
1996 | 1480 | ||
1997 | dest = &tcp6tw->tw_v6_daddr; | 1481 | dest = &tw6->tw_v6_daddr; |
1998 | src = &tcp6tw->tw_v6_rcv_saddr; | 1482 | src = &tw6->tw_v6_rcv_saddr; |
1999 | destp = ntohs(tw->tw_dport); | 1483 | destp = ntohs(tw->tw_dport); |
2000 | srcp = ntohs(tw->tw_sport); | 1484 | srcp = ntohs(tw->tw_sport); |
2001 | 1485 | ||
@@ -2093,7 +1577,7 @@ struct proto tcpv6_prot = { | |||
2093 | .sysctl_rmem = sysctl_tcp_rmem, | 1577 | .sysctl_rmem = sysctl_tcp_rmem, |
2094 | .max_header = MAX_TCP_HEADER, | 1578 | .max_header = MAX_TCP_HEADER, |
2095 | .obj_size = sizeof(struct tcp6_sock), | 1579 | .obj_size = sizeof(struct tcp6_sock), |
2096 | .twsk_obj_size = sizeof(struct tcp6_timewait_sock), | 1580 | .twsk_prot = &tcp6_timewait_sock_ops, |
2097 | .rsk_prot = &tcp6_request_sock_ops, | 1581 | .rsk_prot = &tcp6_request_sock_ops, |
2098 | }; | 1582 | }; |
2099 | 1583 | ||
@@ -2110,7 +1594,8 @@ static struct inet_protosw tcpv6_protosw = { | |||
2110 | .ops = &inet6_stream_ops, | 1594 | .ops = &inet6_stream_ops, |
2111 | .capability = -1, | 1595 | .capability = -1, |
2112 | .no_check = 0, | 1596 | .no_check = 0, |
2113 | .flags = INET_PROTOSW_PERMANENT, | 1597 | .flags = INET_PROTOSW_PERMANENT | |
1598 | INET_PROTOSW_ICSK, | ||
2114 | }; | 1599 | }; |
2115 | 1600 | ||
2116 | void __init tcpv6_init(void) | 1601 | void __init tcpv6_init(void) |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 5cc8731eb55b..d8538dcea813 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/ipv6.h> | 36 | #include <linux/ipv6.h> |
37 | #include <linux/icmpv6.h> | 37 | #include <linux/icmpv6.h> |
38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
39 | #include <linux/skbuff.h> | ||
39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
40 | 41 | ||
41 | #include <net/sock.h> | 42 | #include <net/sock.h> |
@@ -300,20 +301,7 @@ out: | |||
300 | return err; | 301 | return err; |
301 | 302 | ||
302 | csum_copy_err: | 303 | csum_copy_err: |
303 | /* Clear queue. */ | 304 | skb_kill_datagram(sk, skb, flags); |
304 | if (flags&MSG_PEEK) { | ||
305 | int clear = 0; | ||
306 | spin_lock_bh(&sk->sk_receive_queue.lock); | ||
307 | if (skb == skb_peek(&sk->sk_receive_queue)) { | ||
308 | __skb_unlink(skb, &sk->sk_receive_queue); | ||
309 | clear = 1; | ||
310 | } | ||
311 | spin_unlock_bh(&sk->sk_receive_queue.lock); | ||
312 | if (clear) | ||
313 | kfree_skb(skb); | ||
314 | } | ||
315 | |||
316 | skb_free_datagram(sk, skb); | ||
317 | 305 | ||
318 | if (flags & MSG_DONTWAIT) { | 306 | if (flags & MSG_DONTWAIT) { |
319 | UDP6_INC_STATS_USER(UDP_MIB_INERRORS); | 307 | UDP6_INC_STATS_USER(UDP_MIB_INERRORS); |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index cf1d91e74c82..69bd957380e7 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -214,6 +214,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl) | |||
214 | case IPPROTO_UDP: | 214 | case IPPROTO_UDP: |
215 | case IPPROTO_TCP: | 215 | case IPPROTO_TCP: |
216 | case IPPROTO_SCTP: | 216 | case IPPROTO_SCTP: |
217 | case IPPROTO_DCCP: | ||
217 | if (pskb_may_pull(skb, skb->nh.raw + offset + 4 - skb->data)) { | 218 | if (pskb_may_pull(skb, skb->nh.raw + offset + 4 - skb->data)) { |
218 | u16 *ports = (u16 *)exthdr; | 219 | u16 *ports = (u16 *)exthdr; |
219 | 220 | ||
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 34b3bb868409..0dc519b40404 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c | |||
@@ -75,7 +75,7 @@ static struct datalink_proto *pEII_datalink; | |||
75 | static struct datalink_proto *p8023_datalink; | 75 | static struct datalink_proto *p8023_datalink; |
76 | static struct datalink_proto *pSNAP_datalink; | 76 | static struct datalink_proto *pSNAP_datalink; |
77 | 77 | ||
78 | static struct proto_ops ipx_dgram_ops; | 78 | static const struct proto_ops ipx_dgram_ops; |
79 | 79 | ||
80 | LIST_HEAD(ipx_interfaces); | 80 | LIST_HEAD(ipx_interfaces); |
81 | DEFINE_SPINLOCK(ipx_interfaces_lock); | 81 | DEFINE_SPINLOCK(ipx_interfaces_lock); |
@@ -1884,7 +1884,7 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1884 | rc = -EINVAL; | 1884 | rc = -EINVAL; |
1885 | break; | 1885 | break; |
1886 | default: | 1886 | default: |
1887 | rc = dev_ioctl(cmd, argp); | 1887 | rc = -ENOIOCTLCMD; |
1888 | break; | 1888 | break; |
1889 | } | 1889 | } |
1890 | 1890 | ||
@@ -1901,7 +1901,7 @@ static struct net_proto_family ipx_family_ops = { | |||
1901 | .owner = THIS_MODULE, | 1901 | .owner = THIS_MODULE, |
1902 | }; | 1902 | }; |
1903 | 1903 | ||
1904 | static struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = { | 1904 | static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = { |
1905 | .family = PF_IPX, | 1905 | .family = PF_IPX, |
1906 | .owner = THIS_MODULE, | 1906 | .owner = THIS_MODULE, |
1907 | .release = ipx_release, | 1907 | .release = ipx_release, |
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 6f92f9c62990..fbfa96754417 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -62,12 +62,12 @@ | |||
62 | 62 | ||
63 | static int irda_create(struct socket *sock, int protocol); | 63 | static int irda_create(struct socket *sock, int protocol); |
64 | 64 | ||
65 | static struct proto_ops irda_stream_ops; | 65 | static const struct proto_ops irda_stream_ops; |
66 | static struct proto_ops irda_seqpacket_ops; | 66 | static const struct proto_ops irda_seqpacket_ops; |
67 | static struct proto_ops irda_dgram_ops; | 67 | static const struct proto_ops irda_dgram_ops; |
68 | 68 | ||
69 | #ifdef CONFIG_IRDA_ULTRA | 69 | #ifdef CONFIG_IRDA_ULTRA |
70 | static struct proto_ops irda_ultra_ops; | 70 | static const struct proto_ops irda_ultra_ops; |
71 | #define ULTRA_MAX_DATA 382 | 71 | #define ULTRA_MAX_DATA 382 |
72 | #endif /* CONFIG_IRDA_ULTRA */ | 72 | #endif /* CONFIG_IRDA_ULTRA */ |
73 | 73 | ||
@@ -1438,8 +1438,9 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, | |||
1438 | /* | 1438 | /* |
1439 | * POSIX 1003.1g mandates this order. | 1439 | * POSIX 1003.1g mandates this order. |
1440 | */ | 1440 | */ |
1441 | if (sk->sk_err) | 1441 | ret = sock_error(sk); |
1442 | ret = sock_error(sk); | 1442 | if (ret) |
1443 | break; | ||
1443 | else if (sk->sk_shutdown & RCV_SHUTDOWN) | 1444 | else if (sk->sk_shutdown & RCV_SHUTDOWN) |
1444 | ; | 1445 | ; |
1445 | else if (noblock) | 1446 | else if (noblock) |
@@ -1821,7 +1822,7 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1821 | return -EINVAL; | 1822 | return -EINVAL; |
1822 | default: | 1823 | default: |
1823 | IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __FUNCTION__); | 1824 | IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __FUNCTION__); |
1824 | return dev_ioctl(cmd, (void __user *) arg); | 1825 | return -ENOIOCTLCMD; |
1825 | } | 1826 | } |
1826 | 1827 | ||
1827 | /*NOTREACHED*/ | 1828 | /*NOTREACHED*/ |
@@ -2463,7 +2464,7 @@ static struct net_proto_family irda_family_ops = { | |||
2463 | .owner = THIS_MODULE, | 2464 | .owner = THIS_MODULE, |
2464 | }; | 2465 | }; |
2465 | 2466 | ||
2466 | static struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = { | 2467 | static const struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = { |
2467 | .family = PF_IRDA, | 2468 | .family = PF_IRDA, |
2468 | .owner = THIS_MODULE, | 2469 | .owner = THIS_MODULE, |
2469 | .release = irda_release, | 2470 | .release = irda_release, |
@@ -2484,7 +2485,7 @@ static struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = { | |||
2484 | .sendpage = sock_no_sendpage, | 2485 | .sendpage = sock_no_sendpage, |
2485 | }; | 2486 | }; |
2486 | 2487 | ||
2487 | static struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = { | 2488 | static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = { |
2488 | .family = PF_IRDA, | 2489 | .family = PF_IRDA, |
2489 | .owner = THIS_MODULE, | 2490 | .owner = THIS_MODULE, |
2490 | .release = irda_release, | 2491 | .release = irda_release, |
@@ -2505,7 +2506,7 @@ static struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = { | |||
2505 | .sendpage = sock_no_sendpage, | 2506 | .sendpage = sock_no_sendpage, |
2506 | }; | 2507 | }; |
2507 | 2508 | ||
2508 | static struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = { | 2509 | static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = { |
2509 | .family = PF_IRDA, | 2510 | .family = PF_IRDA, |
2510 | .owner = THIS_MODULE, | 2511 | .owner = THIS_MODULE, |
2511 | .release = irda_release, | 2512 | .release = irda_release, |
@@ -2527,7 +2528,7 @@ static struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = { | |||
2527 | }; | 2528 | }; |
2528 | 2529 | ||
2529 | #ifdef CONFIG_IRDA_ULTRA | 2530 | #ifdef CONFIG_IRDA_ULTRA |
2530 | static struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = { | 2531 | static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = { |
2531 | .family = PF_IRDA, | 2532 | .family = PF_IRDA, |
2532 | .owner = THIS_MODULE, | 2533 | .owner = THIS_MODULE, |
2533 | .release = irda_release, | 2534 | .release = irda_release, |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 39031684b65c..52efd04cbedb 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -113,7 +113,7 @@ static __inline__ void pfkey_unlock_table(void) | |||
113 | } | 113 | } |
114 | 114 | ||
115 | 115 | ||
116 | static struct proto_ops pfkey_ops; | 116 | static const struct proto_ops pfkey_ops; |
117 | 117 | ||
118 | static void pfkey_insert(struct sock *sk) | 118 | static void pfkey_insert(struct sock *sk) |
119 | { | 119 | { |
@@ -336,6 +336,7 @@ static u8 sadb_ext_min_len[] = { | |||
336 | [SADB_X_EXT_NAT_T_SPORT] = (u8) sizeof(struct sadb_x_nat_t_port), | 336 | [SADB_X_EXT_NAT_T_SPORT] = (u8) sizeof(struct sadb_x_nat_t_port), |
337 | [SADB_X_EXT_NAT_T_DPORT] = (u8) sizeof(struct sadb_x_nat_t_port), | 337 | [SADB_X_EXT_NAT_T_DPORT] = (u8) sizeof(struct sadb_x_nat_t_port), |
338 | [SADB_X_EXT_NAT_T_OA] = (u8) sizeof(struct sadb_address), | 338 | [SADB_X_EXT_NAT_T_OA] = (u8) sizeof(struct sadb_address), |
339 | [SADB_X_EXT_SEC_CTX] = (u8) sizeof(struct sadb_x_sec_ctx), | ||
339 | }; | 340 | }; |
340 | 341 | ||
341 | /* Verify sadb_address_{len,prefixlen} against sa_family. */ | 342 | /* Verify sadb_address_{len,prefixlen} against sa_family. */ |
@@ -383,6 +384,55 @@ static int verify_address_len(void *p) | |||
383 | return 0; | 384 | return 0; |
384 | } | 385 | } |
385 | 386 | ||
387 | static inline int pfkey_sec_ctx_len(struct sadb_x_sec_ctx *sec_ctx) | ||
388 | { | ||
389 | int len = 0; | ||
390 | |||
391 | len += sizeof(struct sadb_x_sec_ctx); | ||
392 | len += sec_ctx->sadb_x_ctx_len; | ||
393 | len += sizeof(uint64_t) - 1; | ||
394 | len /= sizeof(uint64_t); | ||
395 | |||
396 | return len; | ||
397 | } | ||
398 | |||
399 | static inline int verify_sec_ctx_len(void *p) | ||
400 | { | ||
401 | struct sadb_x_sec_ctx *sec_ctx = (struct sadb_x_sec_ctx *)p; | ||
402 | int len; | ||
403 | |||
404 | if (sec_ctx->sadb_x_ctx_len > PAGE_SIZE) | ||
405 | return -EINVAL; | ||
406 | |||
407 | len = pfkey_sec_ctx_len(sec_ctx); | ||
408 | |||
409 | if (sec_ctx->sadb_x_sec_len != len) | ||
410 | return -EINVAL; | ||
411 | |||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | static inline struct xfrm_user_sec_ctx *pfkey_sadb2xfrm_user_sec_ctx(struct sadb_x_sec_ctx *sec_ctx) | ||
416 | { | ||
417 | struct xfrm_user_sec_ctx *uctx = NULL; | ||
418 | int ctx_size = sec_ctx->sadb_x_ctx_len; | ||
419 | |||
420 | uctx = kmalloc((sizeof(*uctx)+ctx_size), GFP_KERNEL); | ||
421 | |||
422 | if (!uctx) | ||
423 | return NULL; | ||
424 | |||
425 | uctx->len = pfkey_sec_ctx_len(sec_ctx); | ||
426 | uctx->exttype = sec_ctx->sadb_x_sec_exttype; | ||
427 | uctx->ctx_doi = sec_ctx->sadb_x_ctx_doi; | ||
428 | uctx->ctx_alg = sec_ctx->sadb_x_ctx_alg; | ||
429 | uctx->ctx_len = sec_ctx->sadb_x_ctx_len; | ||
430 | memcpy(uctx + 1, sec_ctx + 1, | ||
431 | uctx->ctx_len); | ||
432 | |||
433 | return uctx; | ||
434 | } | ||
435 | |||
386 | static int present_and_same_family(struct sadb_address *src, | 436 | static int present_and_same_family(struct sadb_address *src, |
387 | struct sadb_address *dst) | 437 | struct sadb_address *dst) |
388 | { | 438 | { |
@@ -438,6 +488,10 @@ static int parse_exthdrs(struct sk_buff *skb, struct sadb_msg *hdr, void **ext_h | |||
438 | if (verify_address_len(p)) | 488 | if (verify_address_len(p)) |
439 | return -EINVAL; | 489 | return -EINVAL; |
440 | } | 490 | } |
491 | if (ext_type == SADB_X_EXT_SEC_CTX) { | ||
492 | if (verify_sec_ctx_len(p)) | ||
493 | return -EINVAL; | ||
494 | } | ||
441 | ext_hdrs[ext_type-1] = p; | 495 | ext_hdrs[ext_type-1] = p; |
442 | } | 496 | } |
443 | p += ext_len; | 497 | p += ext_len; |
@@ -586,6 +640,9 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, | |||
586 | struct sadb_key *key; | 640 | struct sadb_key *key; |
587 | struct sadb_x_sa2 *sa2; | 641 | struct sadb_x_sa2 *sa2; |
588 | struct sockaddr_in *sin; | 642 | struct sockaddr_in *sin; |
643 | struct sadb_x_sec_ctx *sec_ctx; | ||
644 | struct xfrm_sec_ctx *xfrm_ctx; | ||
645 | int ctx_size = 0; | ||
589 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 646 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
590 | struct sockaddr_in6 *sin6; | 647 | struct sockaddr_in6 *sin6; |
591 | #endif | 648 | #endif |
@@ -609,6 +666,12 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, | |||
609 | sizeof(struct sadb_address)*2 + | 666 | sizeof(struct sadb_address)*2 + |
610 | sockaddr_size*2 + | 667 | sockaddr_size*2 + |
611 | sizeof(struct sadb_x_sa2); | 668 | sizeof(struct sadb_x_sa2); |
669 | |||
670 | if ((xfrm_ctx = x->security)) { | ||
671 | ctx_size = PFKEY_ALIGN8(xfrm_ctx->ctx_len); | ||
672 | size += sizeof(struct sadb_x_sec_ctx) + ctx_size; | ||
673 | } | ||
674 | |||
612 | /* identity & sensitivity */ | 675 | /* identity & sensitivity */ |
613 | 676 | ||
614 | if ((x->props.family == AF_INET && | 677 | if ((x->props.family == AF_INET && |
@@ -899,6 +962,20 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, | |||
899 | n_port->sadb_x_nat_t_port_reserved = 0; | 962 | n_port->sadb_x_nat_t_port_reserved = 0; |
900 | } | 963 | } |
901 | 964 | ||
965 | /* security context */ | ||
966 | if (xfrm_ctx) { | ||
967 | sec_ctx = (struct sadb_x_sec_ctx *) skb_put(skb, | ||
968 | sizeof(struct sadb_x_sec_ctx) + ctx_size); | ||
969 | sec_ctx->sadb_x_sec_len = | ||
970 | (sizeof(struct sadb_x_sec_ctx) + ctx_size) / sizeof(uint64_t); | ||
971 | sec_ctx->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX; | ||
972 | sec_ctx->sadb_x_ctx_doi = xfrm_ctx->ctx_doi; | ||
973 | sec_ctx->sadb_x_ctx_alg = xfrm_ctx->ctx_alg; | ||
974 | sec_ctx->sadb_x_ctx_len = xfrm_ctx->ctx_len; | ||
975 | memcpy(sec_ctx + 1, xfrm_ctx->ctx_str, | ||
976 | xfrm_ctx->ctx_len); | ||
977 | } | ||
978 | |||
902 | return skb; | 979 | return skb; |
903 | } | 980 | } |
904 | 981 | ||
@@ -909,6 +986,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, | |||
909 | struct sadb_lifetime *lifetime; | 986 | struct sadb_lifetime *lifetime; |
910 | struct sadb_sa *sa; | 987 | struct sadb_sa *sa; |
911 | struct sadb_key *key; | 988 | struct sadb_key *key; |
989 | struct sadb_x_sec_ctx *sec_ctx; | ||
912 | uint16_t proto; | 990 | uint16_t proto; |
913 | int err; | 991 | int err; |
914 | 992 | ||
@@ -993,6 +1071,21 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, | |||
993 | x->lft.soft_add_expires_seconds = lifetime->sadb_lifetime_addtime; | 1071 | x->lft.soft_add_expires_seconds = lifetime->sadb_lifetime_addtime; |
994 | x->lft.soft_use_expires_seconds = lifetime->sadb_lifetime_usetime; | 1072 | x->lft.soft_use_expires_seconds = lifetime->sadb_lifetime_usetime; |
995 | } | 1073 | } |
1074 | |||
1075 | sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1]; | ||
1076 | if (sec_ctx != NULL) { | ||
1077 | struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx); | ||
1078 | |||
1079 | if (!uctx) | ||
1080 | goto out; | ||
1081 | |||
1082 | err = security_xfrm_state_alloc(x, uctx); | ||
1083 | kfree(uctx); | ||
1084 | |||
1085 | if (err) | ||
1086 | goto out; | ||
1087 | } | ||
1088 | |||
996 | key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_AUTH-1]; | 1089 | key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_AUTH-1]; |
997 | if (sa->sadb_sa_auth) { | 1090 | if (sa->sadb_sa_auth) { |
998 | int keysize = 0; | 1091 | int keysize = 0; |
@@ -1720,6 +1813,18 @@ parse_ipsecrequests(struct xfrm_policy *xp, struct sadb_x_policy *pol) | |||
1720 | return 0; | 1813 | return 0; |
1721 | } | 1814 | } |
1722 | 1815 | ||
1816 | static inline int pfkey_xfrm_policy2sec_ctx_size(struct xfrm_policy *xp) | ||
1817 | { | ||
1818 | struct xfrm_sec_ctx *xfrm_ctx = xp->security; | ||
1819 | |||
1820 | if (xfrm_ctx) { | ||
1821 | int len = sizeof(struct sadb_x_sec_ctx); | ||
1822 | len += xfrm_ctx->ctx_len; | ||
1823 | return PFKEY_ALIGN8(len); | ||
1824 | } | ||
1825 | return 0; | ||
1826 | } | ||
1827 | |||
1723 | static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp) | 1828 | static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp) |
1724 | { | 1829 | { |
1725 | int sockaddr_size = pfkey_sockaddr_size(xp->family); | 1830 | int sockaddr_size = pfkey_sockaddr_size(xp->family); |
@@ -1733,7 +1838,8 @@ static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp) | |||
1733 | (sockaddr_size * 2) + | 1838 | (sockaddr_size * 2) + |
1734 | sizeof(struct sadb_x_policy) + | 1839 | sizeof(struct sadb_x_policy) + |
1735 | (xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) + | 1840 | (xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) + |
1736 | (socklen * 2))); | 1841 | (socklen * 2))) + |
1842 | pfkey_xfrm_policy2sec_ctx_size(xp); | ||
1737 | } | 1843 | } |
1738 | 1844 | ||
1739 | static struct sk_buff * pfkey_xfrm_policy2msg_prep(struct xfrm_policy *xp) | 1845 | static struct sk_buff * pfkey_xfrm_policy2msg_prep(struct xfrm_policy *xp) |
@@ -1757,6 +1863,8 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i | |||
1757 | struct sadb_lifetime *lifetime; | 1863 | struct sadb_lifetime *lifetime; |
1758 | struct sadb_x_policy *pol; | 1864 | struct sadb_x_policy *pol; |
1759 | struct sockaddr_in *sin; | 1865 | struct sockaddr_in *sin; |
1866 | struct sadb_x_sec_ctx *sec_ctx; | ||
1867 | struct xfrm_sec_ctx *xfrm_ctx; | ||
1760 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 1868 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
1761 | struct sockaddr_in6 *sin6; | 1869 | struct sockaddr_in6 *sin6; |
1762 | #endif | 1870 | #endif |
@@ -1941,6 +2049,21 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i | |||
1941 | } | 2049 | } |
1942 | } | 2050 | } |
1943 | } | 2051 | } |
2052 | |||
2053 | /* security context */ | ||
2054 | if ((xfrm_ctx = xp->security)) { | ||
2055 | int ctx_size = pfkey_xfrm_policy2sec_ctx_size(xp); | ||
2056 | |||
2057 | sec_ctx = (struct sadb_x_sec_ctx *) skb_put(skb, ctx_size); | ||
2058 | sec_ctx->sadb_x_sec_len = ctx_size / sizeof(uint64_t); | ||
2059 | sec_ctx->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX; | ||
2060 | sec_ctx->sadb_x_ctx_doi = xfrm_ctx->ctx_doi; | ||
2061 | sec_ctx->sadb_x_ctx_alg = xfrm_ctx->ctx_alg; | ||
2062 | sec_ctx->sadb_x_ctx_len = xfrm_ctx->ctx_len; | ||
2063 | memcpy(sec_ctx + 1, xfrm_ctx->ctx_str, | ||
2064 | xfrm_ctx->ctx_len); | ||
2065 | } | ||
2066 | |||
1944 | hdr->sadb_msg_len = size / sizeof(uint64_t); | 2067 | hdr->sadb_msg_len = size / sizeof(uint64_t); |
1945 | hdr->sadb_msg_reserved = atomic_read(&xp->refcnt); | 2068 | hdr->sadb_msg_reserved = atomic_read(&xp->refcnt); |
1946 | } | 2069 | } |
@@ -1976,12 +2099,13 @@ out: | |||
1976 | 2099 | ||
1977 | static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) | 2100 | static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) |
1978 | { | 2101 | { |
1979 | int err; | 2102 | int err = 0; |
1980 | struct sadb_lifetime *lifetime; | 2103 | struct sadb_lifetime *lifetime; |
1981 | struct sadb_address *sa; | 2104 | struct sadb_address *sa; |
1982 | struct sadb_x_policy *pol; | 2105 | struct sadb_x_policy *pol; |
1983 | struct xfrm_policy *xp; | 2106 | struct xfrm_policy *xp; |
1984 | struct km_event c; | 2107 | struct km_event c; |
2108 | struct sadb_x_sec_ctx *sec_ctx; | ||
1985 | 2109 | ||
1986 | if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], | 2110 | if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], |
1987 | ext_hdrs[SADB_EXT_ADDRESS_DST-1]) || | 2111 | ext_hdrs[SADB_EXT_ADDRESS_DST-1]) || |
@@ -2028,6 +2152,22 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
2028 | if (xp->selector.dport) | 2152 | if (xp->selector.dport) |
2029 | xp->selector.dport_mask = ~0; | 2153 | xp->selector.dport_mask = ~0; |
2030 | 2154 | ||
2155 | sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1]; | ||
2156 | if (sec_ctx != NULL) { | ||
2157 | struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx); | ||
2158 | |||
2159 | if (!uctx) { | ||
2160 | err = -ENOBUFS; | ||
2161 | goto out; | ||
2162 | } | ||
2163 | |||
2164 | err = security_xfrm_policy_alloc(xp, uctx); | ||
2165 | kfree(uctx); | ||
2166 | |||
2167 | if (err) | ||
2168 | goto out; | ||
2169 | } | ||
2170 | |||
2031 | xp->lft.soft_byte_limit = XFRM_INF; | 2171 | xp->lft.soft_byte_limit = XFRM_INF; |
2032 | xp->lft.hard_byte_limit = XFRM_INF; | 2172 | xp->lft.hard_byte_limit = XFRM_INF; |
2033 | xp->lft.soft_packet_limit = XFRM_INF; | 2173 | xp->lft.soft_packet_limit = XFRM_INF; |
@@ -2051,10 +2191,9 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
2051 | 2191 | ||
2052 | err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp, | 2192 | err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp, |
2053 | hdr->sadb_msg_type != SADB_X_SPDUPDATE); | 2193 | hdr->sadb_msg_type != SADB_X_SPDUPDATE); |
2054 | if (err) { | 2194 | |
2055 | kfree(xp); | 2195 | if (err) |
2056 | return err; | 2196 | goto out; |
2057 | } | ||
2058 | 2197 | ||
2059 | if (hdr->sadb_msg_type == SADB_X_SPDUPDATE) | 2198 | if (hdr->sadb_msg_type == SADB_X_SPDUPDATE) |
2060 | c.event = XFRM_MSG_UPDPOLICY; | 2199 | c.event = XFRM_MSG_UPDPOLICY; |
@@ -2069,6 +2208,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
2069 | return 0; | 2208 | return 0; |
2070 | 2209 | ||
2071 | out: | 2210 | out: |
2211 | security_xfrm_policy_free(xp); | ||
2072 | kfree(xp); | 2212 | kfree(xp); |
2073 | return err; | 2213 | return err; |
2074 | } | 2214 | } |
@@ -2078,9 +2218,10 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2078 | int err; | 2218 | int err; |
2079 | struct sadb_address *sa; | 2219 | struct sadb_address *sa; |
2080 | struct sadb_x_policy *pol; | 2220 | struct sadb_x_policy *pol; |
2081 | struct xfrm_policy *xp; | 2221 | struct xfrm_policy *xp, tmp; |
2082 | struct xfrm_selector sel; | 2222 | struct xfrm_selector sel; |
2083 | struct km_event c; | 2223 | struct km_event c; |
2224 | struct sadb_x_sec_ctx *sec_ctx; | ||
2084 | 2225 | ||
2085 | if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], | 2226 | if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], |
2086 | ext_hdrs[SADB_EXT_ADDRESS_DST-1]) || | 2227 | ext_hdrs[SADB_EXT_ADDRESS_DST-1]) || |
@@ -2109,7 +2250,24 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2109 | if (sel.dport) | 2250 | if (sel.dport) |
2110 | sel.dport_mask = ~0; | 2251 | sel.dport_mask = ~0; |
2111 | 2252 | ||
2112 | xp = xfrm_policy_bysel(pol->sadb_x_policy_dir-1, &sel, 1); | 2253 | sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1]; |
2254 | memset(&tmp, 0, sizeof(struct xfrm_policy)); | ||
2255 | |||
2256 | if (sec_ctx != NULL) { | ||
2257 | struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx); | ||
2258 | |||
2259 | if (!uctx) | ||
2260 | return -ENOMEM; | ||
2261 | |||
2262 | err = security_xfrm_policy_alloc(&tmp, uctx); | ||
2263 | kfree(uctx); | ||
2264 | |||
2265 | if (err) | ||
2266 | return err; | ||
2267 | } | ||
2268 | |||
2269 | xp = xfrm_policy_bysel_ctx(pol->sadb_x_policy_dir-1, &sel, tmp.security, 1); | ||
2270 | security_xfrm_policy_free(&tmp); | ||
2113 | if (xp == NULL) | 2271 | if (xp == NULL) |
2114 | return -ENOENT; | 2272 | return -ENOENT; |
2115 | 2273 | ||
@@ -2660,6 +2818,7 @@ static struct xfrm_policy *pfkey_compile_policy(u16 family, int opt, | |||
2660 | { | 2818 | { |
2661 | struct xfrm_policy *xp; | 2819 | struct xfrm_policy *xp; |
2662 | struct sadb_x_policy *pol = (struct sadb_x_policy*)data; | 2820 | struct sadb_x_policy *pol = (struct sadb_x_policy*)data; |
2821 | struct sadb_x_sec_ctx *sec_ctx; | ||
2663 | 2822 | ||
2664 | switch (family) { | 2823 | switch (family) { |
2665 | case AF_INET: | 2824 | case AF_INET: |
@@ -2709,10 +2868,32 @@ static struct xfrm_policy *pfkey_compile_policy(u16 family, int opt, | |||
2709 | (*dir = parse_ipsecrequests(xp, pol)) < 0) | 2868 | (*dir = parse_ipsecrequests(xp, pol)) < 0) |
2710 | goto out; | 2869 | goto out; |
2711 | 2870 | ||
2871 | /* security context too */ | ||
2872 | if (len >= (pol->sadb_x_policy_len*8 + | ||
2873 | sizeof(struct sadb_x_sec_ctx))) { | ||
2874 | char *p = (char *)pol; | ||
2875 | struct xfrm_user_sec_ctx *uctx; | ||
2876 | |||
2877 | p += pol->sadb_x_policy_len*8; | ||
2878 | sec_ctx = (struct sadb_x_sec_ctx *)p; | ||
2879 | if (len < pol->sadb_x_policy_len*8 + | ||
2880 | sec_ctx->sadb_x_sec_len) | ||
2881 | goto out; | ||
2882 | if ((*dir = verify_sec_ctx_len(p))) | ||
2883 | goto out; | ||
2884 | uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx); | ||
2885 | *dir = security_xfrm_policy_alloc(xp, uctx); | ||
2886 | kfree(uctx); | ||
2887 | |||
2888 | if (*dir) | ||
2889 | goto out; | ||
2890 | } | ||
2891 | |||
2712 | *dir = pol->sadb_x_policy_dir-1; | 2892 | *dir = pol->sadb_x_policy_dir-1; |
2713 | return xp; | 2893 | return xp; |
2714 | 2894 | ||
2715 | out: | 2895 | out: |
2896 | security_xfrm_policy_free(xp); | ||
2716 | kfree(xp); | 2897 | kfree(xp); |
2717 | return NULL; | 2898 | return NULL; |
2718 | } | 2899 | } |
@@ -2946,7 +3127,7 @@ out: | |||
2946 | return err; | 3127 | return err; |
2947 | } | 3128 | } |
2948 | 3129 | ||
2949 | static struct proto_ops pfkey_ops = { | 3130 | static const struct proto_ops pfkey_ops = { |
2950 | .family = PF_KEY, | 3131 | .family = PF_KEY, |
2951 | .owner = THIS_MODULE, | 3132 | .owner = THIS_MODULE, |
2952 | /* Operations that make no sense on pfkey sockets. */ | 3133 | /* Operations that make no sense on pfkey sockets. */ |
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index c3f0b0783453..8171c53bc0ed 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
@@ -36,7 +36,7 @@ | |||
36 | static u16 llc_ui_sap_last_autoport = LLC_SAP_DYN_START; | 36 | static u16 llc_ui_sap_last_autoport = LLC_SAP_DYN_START; |
37 | static u16 llc_ui_sap_link_no_max[256]; | 37 | static u16 llc_ui_sap_link_no_max[256]; |
38 | static struct sockaddr_llc llc_ui_addrnull; | 38 | static struct sockaddr_llc llc_ui_addrnull; |
39 | static struct proto_ops llc_ui_ops; | 39 | static const struct proto_ops llc_ui_ops; |
40 | 40 | ||
41 | static int llc_ui_wait_for_conn(struct sock *sk, long timeout); | 41 | static int llc_ui_wait_for_conn(struct sock *sk, long timeout); |
42 | static int llc_ui_wait_for_disc(struct sock *sk, long timeout); | 42 | static int llc_ui_wait_for_disc(struct sock *sk, long timeout); |
@@ -566,10 +566,9 @@ static int llc_wait_data(struct sock *sk, long timeo) | |||
566 | /* | 566 | /* |
567 | * POSIX 1003.1g mandates this order. | 567 | * POSIX 1003.1g mandates this order. |
568 | */ | 568 | */ |
569 | if (sk->sk_err) { | 569 | rc = sock_error(sk); |
570 | rc = sock_error(sk); | 570 | if (rc) |
571 | break; | 571 | break; |
572 | } | ||
573 | rc = 0; | 572 | rc = 0; |
574 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 573 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
575 | break; | 574 | break; |
@@ -960,7 +959,7 @@ out: | |||
960 | static int llc_ui_ioctl(struct socket *sock, unsigned int cmd, | 959 | static int llc_ui_ioctl(struct socket *sock, unsigned int cmd, |
961 | unsigned long arg) | 960 | unsigned long arg) |
962 | { | 961 | { |
963 | return dev_ioctl(cmd, (void __user *)arg); | 962 | return -ENOIOCTLCMD; |
964 | } | 963 | } |
965 | 964 | ||
966 | /** | 965 | /** |
@@ -1099,7 +1098,7 @@ static struct net_proto_family llc_ui_family_ops = { | |||
1099 | .owner = THIS_MODULE, | 1098 | .owner = THIS_MODULE, |
1100 | }; | 1099 | }; |
1101 | 1100 | ||
1102 | static struct proto_ops llc_ui_ops = { | 1101 | static const struct proto_ops llc_ui_ops = { |
1103 | .family = PF_LLC, | 1102 | .family = PF_LLC, |
1104 | .owner = THIS_MODULE, | 1103 | .owner = THIS_MODULE, |
1105 | .release = llc_ui_release, | 1104 | .release = llc_ui_release, |
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index cba63729313d..e10512e229b6 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -151,7 +151,7 @@ instance_create(u_int16_t group_num, int pid) | |||
151 | goto out_unlock; | 151 | goto out_unlock; |
152 | 152 | ||
153 | INIT_HLIST_NODE(&inst->hlist); | 153 | INIT_HLIST_NODE(&inst->hlist); |
154 | inst->lock = SPIN_LOCK_UNLOCKED; | 154 | spin_lock_init(&inst->lock); |
155 | /* needs to be two, since we _put() after creation */ | 155 | /* needs to be two, since we _put() after creation */ |
156 | atomic_set(&inst->use, 2); | 156 | atomic_set(&inst->use, 2); |
157 | 157 | ||
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index f28460b61e47..55afdda3d940 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -148,7 +148,7 @@ instance_create(u_int16_t queue_num, int pid) | |||
148 | atomic_set(&inst->id_sequence, 0); | 148 | atomic_set(&inst->id_sequence, 0); |
149 | /* needs to be two, since we _put() after creation */ | 149 | /* needs to be two, since we _put() after creation */ |
150 | atomic_set(&inst->use, 2); | 150 | atomic_set(&inst->use, 2); |
151 | inst->lock = SPIN_LOCK_UNLOCKED; | 151 | spin_lock_init(&inst->lock); |
152 | INIT_LIST_HEAD(&inst->queue_list); | 152 | INIT_LIST_HEAD(&inst->queue_list); |
153 | 153 | ||
154 | if (!try_module_get(THIS_MODULE)) | 154 | if (!try_module_get(THIS_MODULE)) |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 96020d7087e8..7849cac14d3a 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -293,7 +293,7 @@ static inline int nl_pid_hash_dilute(struct nl_pid_hash *hash, int len) | |||
293 | return 0; | 293 | return 0; |
294 | } | 294 | } |
295 | 295 | ||
296 | static struct proto_ops netlink_ops; | 296 | static const struct proto_ops netlink_ops; |
297 | 297 | ||
298 | static int netlink_insert(struct sock *sk, u32 pid) | 298 | static int netlink_insert(struct sock *sk, u32 pid) |
299 | { | 299 | { |
@@ -1656,7 +1656,7 @@ int netlink_unregister_notifier(struct notifier_block *nb) | |||
1656 | return notifier_chain_unregister(&netlink_chain, nb); | 1656 | return notifier_chain_unregister(&netlink_chain, nb); |
1657 | } | 1657 | } |
1658 | 1658 | ||
1659 | static struct proto_ops netlink_ops = { | 1659 | static const struct proto_ops netlink_ops = { |
1660 | .family = PF_NETLINK, | 1660 | .family = PF_NETLINK, |
1661 | .owner = THIS_MODULE, | 1661 | .owner = THIS_MODULE, |
1662 | .release = netlink_release, | 1662 | .release = netlink_release, |
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 287cfcc56951..3b1378498d50 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -441,7 +441,7 @@ errout: | |||
441 | } | 441 | } |
442 | 442 | ||
443 | static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid, | 443 | static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid, |
444 | int seq, int cmd) | 444 | int seq, u8 cmd) |
445 | { | 445 | { |
446 | struct sk_buff *skb; | 446 | struct sk_buff *skb; |
447 | int err; | 447 | int err; |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index e5d82d711cae..63b0e4afeb33 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -63,7 +63,7 @@ static unsigned short circuit = 0x101; | |||
63 | static HLIST_HEAD(nr_list); | 63 | static HLIST_HEAD(nr_list); |
64 | static DEFINE_SPINLOCK(nr_list_lock); | 64 | static DEFINE_SPINLOCK(nr_list_lock); |
65 | 65 | ||
66 | static struct proto_ops nr_proto_ops; | 66 | static const struct proto_ops nr_proto_ops; |
67 | 67 | ||
68 | /* | 68 | /* |
69 | * Socket removal during an interrupt is now safe. | 69 | * Socket removal during an interrupt is now safe. |
@@ -1166,10 +1166,11 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1166 | void __user *argp = (void __user *)arg; | 1166 | void __user *argp = (void __user *)arg; |
1167 | int ret; | 1167 | int ret; |
1168 | 1168 | ||
1169 | lock_sock(sk); | ||
1170 | switch (cmd) { | 1169 | switch (cmd) { |
1171 | case TIOCOUTQ: { | 1170 | case TIOCOUTQ: { |
1172 | long amount; | 1171 | long amount; |
1172 | |||
1173 | lock_sock(sk); | ||
1173 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 1174 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); |
1174 | if (amount < 0) | 1175 | if (amount < 0) |
1175 | amount = 0; | 1176 | amount = 0; |
@@ -1180,6 +1181,8 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1180 | case TIOCINQ: { | 1181 | case TIOCINQ: { |
1181 | struct sk_buff *skb; | 1182 | struct sk_buff *skb; |
1182 | long amount = 0L; | 1183 | long amount = 0L; |
1184 | |||
1185 | lock_sock(sk); | ||
1183 | /* These two are safe on a single CPU system as only user tasks fiddle here */ | 1186 | /* These two are safe on a single CPU system as only user tasks fiddle here */ |
1184 | if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) | 1187 | if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) |
1185 | amount = skb->len; | 1188 | amount = skb->len; |
@@ -1188,6 +1191,7 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1188 | } | 1191 | } |
1189 | 1192 | ||
1190 | case SIOCGSTAMP: | 1193 | case SIOCGSTAMP: |
1194 | lock_sock(sk); | ||
1191 | ret = sock_get_timestamp(sk, argp); | 1195 | ret = sock_get_timestamp(sk, argp); |
1192 | release_sock(sk); | 1196 | release_sock(sk); |
1193 | return ret; | 1197 | return ret; |
@@ -1202,21 +1206,17 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1202 | case SIOCSIFNETMASK: | 1206 | case SIOCSIFNETMASK: |
1203 | case SIOCGIFMETRIC: | 1207 | case SIOCGIFMETRIC: |
1204 | case SIOCSIFMETRIC: | 1208 | case SIOCSIFMETRIC: |
1205 | release_sock(sk); | ||
1206 | return -EINVAL; | 1209 | return -EINVAL; |
1207 | 1210 | ||
1208 | case SIOCADDRT: | 1211 | case SIOCADDRT: |
1209 | case SIOCDELRT: | 1212 | case SIOCDELRT: |
1210 | case SIOCNRDECOBS: | 1213 | case SIOCNRDECOBS: |
1211 | release_sock(sk); | ||
1212 | if (!capable(CAP_NET_ADMIN)) return -EPERM; | 1214 | if (!capable(CAP_NET_ADMIN)) return -EPERM; |
1213 | return nr_rt_ioctl(cmd, argp); | 1215 | return nr_rt_ioctl(cmd, argp); |
1214 | 1216 | ||
1215 | default: | 1217 | default: |
1216 | release_sock(sk); | 1218 | return -ENOIOCTLCMD; |
1217 | return dev_ioctl(cmd, argp); | ||
1218 | } | 1219 | } |
1219 | release_sock(sk); | ||
1220 | 1220 | ||
1221 | return 0; | 1221 | return 0; |
1222 | } | 1222 | } |
@@ -1337,7 +1337,7 @@ static struct net_proto_family nr_family_ops = { | |||
1337 | .owner = THIS_MODULE, | 1337 | .owner = THIS_MODULE, |
1338 | }; | 1338 | }; |
1339 | 1339 | ||
1340 | static struct proto_ops nr_proto_ops = { | 1340 | static const struct proto_ops nr_proto_ops = { |
1341 | .family = PF_NETROM, | 1341 | .family = PF_NETROM, |
1342 | .owner = THIS_MODULE, | 1342 | .owner = THIS_MODULE, |
1343 | .release = nr_release, | 1343 | .release = nr_release, |
diff --git a/net/netrom/nr_in.c b/net/netrom/nr_in.c index 004e8599b8fe..a7d88b5ad756 100644 --- a/net/netrom/nr_in.c +++ b/net/netrom/nr_in.c | |||
@@ -99,7 +99,7 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb, | |||
99 | break; | 99 | break; |
100 | 100 | ||
101 | case NR_RESET: | 101 | case NR_RESET: |
102 | if (sysctl_netrom_reset_circuit); | 102 | if (sysctl_netrom_reset_circuit) |
103 | nr_disconnect(sk, ECONNRESET); | 103 | nr_disconnect(sk, ECONNRESET); |
104 | break; | 104 | break; |
105 | 105 | ||
@@ -130,7 +130,7 @@ static int nr_state2_machine(struct sock *sk, struct sk_buff *skb, | |||
130 | break; | 130 | break; |
131 | 131 | ||
132 | case NR_RESET: | 132 | case NR_RESET: |
133 | if (sysctl_netrom_reset_circuit); | 133 | if (sysctl_netrom_reset_circuit) |
134 | nr_disconnect(sk, ECONNRESET); | 134 | nr_disconnect(sk, ECONNRESET); |
135 | break; | 135 | break; |
136 | 136 | ||
@@ -265,7 +265,7 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype | |||
265 | break; | 265 | break; |
266 | 266 | ||
267 | case NR_RESET: | 267 | case NR_RESET: |
268 | if (sysctl_netrom_reset_circuit); | 268 | if (sysctl_netrom_reset_circuit) |
269 | nr_disconnect(sk, ECONNRESET); | 269 | nr_disconnect(sk, ECONNRESET); |
270 | break; | 270 | break; |
271 | 271 | ||
diff --git a/net/nonet.c b/net/nonet.c index e5241dceaa57..1230f0ae832e 100644 --- a/net/nonet.c +++ b/net/nonet.c | |||
@@ -14,11 +14,6 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | 16 | ||
17 | void __init sock_init(void) | ||
18 | { | ||
19 | printk(KERN_INFO "Linux NoNET1.0 for Linux 2.6\n"); | ||
20 | } | ||
21 | |||
22 | static int sock_no_open(struct inode *irrelevant, struct file *dontcare) | 17 | static int sock_no_open(struct inode *irrelevant, struct file *dontcare) |
23 | { | 18 | { |
24 | return -ENXIO; | 19 | return -ENXIO; |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 3e2462760413..f69e5ed9bd06 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -251,10 +251,10 @@ static void packet_sock_destruct(struct sock *sk) | |||
251 | } | 251 | } |
252 | 252 | ||
253 | 253 | ||
254 | static struct proto_ops packet_ops; | 254 | static const struct proto_ops packet_ops; |
255 | 255 | ||
256 | #ifdef CONFIG_SOCK_PACKET | 256 | #ifdef CONFIG_SOCK_PACKET |
257 | static struct proto_ops packet_ops_spkt; | 257 | static const struct proto_ops packet_ops_spkt; |
258 | 258 | ||
259 | static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) | 259 | static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) |
260 | { | 260 | { |
@@ -1521,7 +1521,7 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd, | |||
1521 | #endif | 1521 | #endif |
1522 | 1522 | ||
1523 | default: | 1523 | default: |
1524 | return dev_ioctl(cmd, (void __user *)arg); | 1524 | return -ENOIOCTLCMD; |
1525 | } | 1525 | } |
1526 | return 0; | 1526 | return 0; |
1527 | } | 1527 | } |
@@ -1784,7 +1784,7 @@ out: | |||
1784 | 1784 | ||
1785 | 1785 | ||
1786 | #ifdef CONFIG_SOCK_PACKET | 1786 | #ifdef CONFIG_SOCK_PACKET |
1787 | static struct proto_ops packet_ops_spkt = { | 1787 | static const struct proto_ops packet_ops_spkt = { |
1788 | .family = PF_PACKET, | 1788 | .family = PF_PACKET, |
1789 | .owner = THIS_MODULE, | 1789 | .owner = THIS_MODULE, |
1790 | .release = packet_release, | 1790 | .release = packet_release, |
@@ -1806,7 +1806,7 @@ static struct proto_ops packet_ops_spkt = { | |||
1806 | }; | 1806 | }; |
1807 | #endif | 1807 | #endif |
1808 | 1808 | ||
1809 | static struct proto_ops packet_ops = { | 1809 | static const struct proto_ops packet_ops = { |
1810 | .family = PF_PACKET, | 1810 | .family = PF_PACKET, |
1811 | .owner = THIS_MODULE, | 1811 | .owner = THIS_MODULE, |
1812 | .release = packet_release, | 1812 | .release = packet_release, |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 829fdbc4400b..63090be2315a 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -1320,7 +1320,7 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1320 | return 0; | 1320 | return 0; |
1321 | 1321 | ||
1322 | default: | 1322 | default: |
1323 | return dev_ioctl(cmd, argp); | 1323 | return -ENOIOCTLCMD; |
1324 | } | 1324 | } |
1325 | 1325 | ||
1326 | return 0; | 1326 | return 0; |
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 82fb07aa06a5..ba5283204837 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | #include <net/pkt_sched.h> | 26 | #include <net/pkt_sched.h> |
27 | 27 | ||
28 | #define VERSION "1.1" | 28 | #define VERSION "1.2" |
29 | 29 | ||
30 | /* Network Emulation Queuing algorithm. | 30 | /* Network Emulation Queuing algorithm. |
31 | ==================================== | 31 | ==================================== |
@@ -65,11 +65,12 @@ struct netem_sched_data { | |||
65 | u32 jitter; | 65 | u32 jitter; |
66 | u32 duplicate; | 66 | u32 duplicate; |
67 | u32 reorder; | 67 | u32 reorder; |
68 | u32 corrupt; | ||
68 | 69 | ||
69 | struct crndstate { | 70 | struct crndstate { |
70 | unsigned long last; | 71 | unsigned long last; |
71 | unsigned long rho; | 72 | unsigned long rho; |
72 | } delay_cor, loss_cor, dup_cor, reorder_cor; | 73 | } delay_cor, loss_cor, dup_cor, reorder_cor, corrupt_cor; |
73 | 74 | ||
74 | struct disttable { | 75 | struct disttable { |
75 | u32 size; | 76 | u32 size; |
@@ -183,6 +184,23 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
183 | q->duplicate = dupsave; | 184 | q->duplicate = dupsave; |
184 | } | 185 | } |
185 | 186 | ||
187 | /* | ||
188 | * Randomized packet corruption. | ||
189 | * Make copy if needed since we are modifying | ||
190 | * If packet is going to be hardware checksummed, then | ||
191 | * do it now in software before we mangle it. | ||
192 | */ | ||
193 | if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) { | ||
194 | if (!(skb = skb_unshare(skb, GFP_ATOMIC)) | ||
195 | || (skb->ip_summed == CHECKSUM_HW | ||
196 | && skb_checksum_help(skb, 0))) { | ||
197 | sch->qstats.drops++; | ||
198 | return NET_XMIT_DROP; | ||
199 | } | ||
200 | |||
201 | skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8); | ||
202 | } | ||
203 | |||
186 | if (q->gap == 0 /* not doing reordering */ | 204 | if (q->gap == 0 /* not doing reordering */ |
187 | || q->counter < q->gap /* inside last reordering gap */ | 205 | || q->counter < q->gap /* inside last reordering gap */ |
188 | || q->reorder < get_crandom(&q->reorder_cor)) { | 206 | || q->reorder < get_crandom(&q->reorder_cor)) { |
@@ -382,6 +400,20 @@ static int get_reorder(struct Qdisc *sch, const struct rtattr *attr) | |||
382 | return 0; | 400 | return 0; |
383 | } | 401 | } |
384 | 402 | ||
403 | static int get_corrupt(struct Qdisc *sch, const struct rtattr *attr) | ||
404 | { | ||
405 | struct netem_sched_data *q = qdisc_priv(sch); | ||
406 | const struct tc_netem_corrupt *r = RTA_DATA(attr); | ||
407 | |||
408 | if (RTA_PAYLOAD(attr) != sizeof(*r)) | ||
409 | return -EINVAL; | ||
410 | |||
411 | q->corrupt = r->probability; | ||
412 | init_crandom(&q->corrupt_cor, r->correlation); | ||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | /* Parse netlink message to set options */ | ||
385 | static int netem_change(struct Qdisc *sch, struct rtattr *opt) | 417 | static int netem_change(struct Qdisc *sch, struct rtattr *opt) |
386 | { | 418 | { |
387 | struct netem_sched_data *q = qdisc_priv(sch); | 419 | struct netem_sched_data *q = qdisc_priv(sch); |
@@ -432,13 +464,19 @@ static int netem_change(struct Qdisc *sch, struct rtattr *opt) | |||
432 | if (ret) | 464 | if (ret) |
433 | return ret; | 465 | return ret; |
434 | } | 466 | } |
467 | |||
435 | if (tb[TCA_NETEM_REORDER-1]) { | 468 | if (tb[TCA_NETEM_REORDER-1]) { |
436 | ret = get_reorder(sch, tb[TCA_NETEM_REORDER-1]); | 469 | ret = get_reorder(sch, tb[TCA_NETEM_REORDER-1]); |
437 | if (ret) | 470 | if (ret) |
438 | return ret; | 471 | return ret; |
439 | } | 472 | } |
440 | } | ||
441 | 473 | ||
474 | if (tb[TCA_NETEM_CORRUPT-1]) { | ||
475 | ret = get_corrupt(sch, tb[TCA_NETEM_CORRUPT-1]); | ||
476 | if (ret) | ||
477 | return ret; | ||
478 | } | ||
479 | } | ||
442 | 480 | ||
443 | return 0; | 481 | return 0; |
444 | } | 482 | } |
@@ -564,6 +602,7 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
564 | struct tc_netem_qopt qopt; | 602 | struct tc_netem_qopt qopt; |
565 | struct tc_netem_corr cor; | 603 | struct tc_netem_corr cor; |
566 | struct tc_netem_reorder reorder; | 604 | struct tc_netem_reorder reorder; |
605 | struct tc_netem_corrupt corrupt; | ||
567 | 606 | ||
568 | qopt.latency = q->latency; | 607 | qopt.latency = q->latency; |
569 | qopt.jitter = q->jitter; | 608 | qopt.jitter = q->jitter; |
@@ -582,6 +621,10 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
582 | reorder.correlation = q->reorder_cor.rho; | 621 | reorder.correlation = q->reorder_cor.rho; |
583 | RTA_PUT(skb, TCA_NETEM_REORDER, sizeof(reorder), &reorder); | 622 | RTA_PUT(skb, TCA_NETEM_REORDER, sizeof(reorder), &reorder); |
584 | 623 | ||
624 | corrupt.probability = q->corrupt; | ||
625 | corrupt.correlation = q->corrupt_cor.rho; | ||
626 | RTA_PUT(skb, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt); | ||
627 | |||
585 | rta->rta_len = skb->tail - b; | 628 | rta->rta_len = skb->tail - b; |
586 | 629 | ||
587 | return skb->len; | 630 | return skb->len; |
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 6cf0342706b5..c4a2a8c4c339 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/in.h> | 22 | #include <linux/in.h> |
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/if_arp.h> | ||
25 | #include <linux/if_ether.h> | 26 | #include <linux/if_ether.h> |
26 | #include <linux/inet.h> | 27 | #include <linux/inet.h> |
27 | #include <linux/netdevice.h> | 28 | #include <linux/netdevice.h> |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index dec68a604773..9d05e13e92f6 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -110,7 +110,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
110 | asoc->cookie_life.tv_sec = sp->assocparams.sasoc_cookie_life / 1000; | 110 | asoc->cookie_life.tv_sec = sp->assocparams.sasoc_cookie_life / 1000; |
111 | asoc->cookie_life.tv_usec = (sp->assocparams.sasoc_cookie_life % 1000) | 111 | asoc->cookie_life.tv_usec = (sp->assocparams.sasoc_cookie_life % 1000) |
112 | * 1000; | 112 | * 1000; |
113 | asoc->pmtu = 0; | ||
114 | asoc->frag_point = 0; | 113 | asoc->frag_point = 0; |
115 | 114 | ||
116 | /* Set the association max_retrans and RTO values from the | 115 | /* Set the association max_retrans and RTO values from the |
@@ -123,6 +122,25 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
123 | 122 | ||
124 | asoc->overall_error_count = 0; | 123 | asoc->overall_error_count = 0; |
125 | 124 | ||
125 | /* Initialize the association's heartbeat interval based on the | ||
126 | * sock configured value. | ||
127 | */ | ||
128 | asoc->hbinterval = msecs_to_jiffies(sp->hbinterval); | ||
129 | |||
130 | /* Initialize path max retrans value. */ | ||
131 | asoc->pathmaxrxt = sp->pathmaxrxt; | ||
132 | |||
133 | /* Initialize default path MTU. */ | ||
134 | asoc->pathmtu = sp->pathmtu; | ||
135 | |||
136 | /* Set association default SACK delay */ | ||
137 | asoc->sackdelay = msecs_to_jiffies(sp->sackdelay); | ||
138 | |||
139 | /* Set the association default flags controlling | ||
140 | * Heartbeat, SACK delay, and Path MTU Discovery. | ||
141 | */ | ||
142 | asoc->param_flags = sp->param_flags; | ||
143 | |||
126 | /* Initialize the maximum mumber of new data packets that can be sent | 144 | /* Initialize the maximum mumber of new data packets that can be sent |
127 | * in a burst. | 145 | * in a burst. |
128 | */ | 146 | */ |
@@ -144,8 +162,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
144 | = 5 * asoc->rto_max; | 162 | = 5 * asoc->rto_max; |
145 | 163 | ||
146 | asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; | 164 | asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; |
147 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = | 165 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; |
148 | SCTP_DEFAULT_TIMEOUT_SACK; | ||
149 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = | 166 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = |
150 | sp->autoclose * HZ; | 167 | sp->autoclose * HZ; |
151 | 168 | ||
@@ -540,23 +557,46 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, | |||
540 | 557 | ||
541 | sctp_transport_set_owner(peer, asoc); | 558 | sctp_transport_set_owner(peer, asoc); |
542 | 559 | ||
560 | /* Initialize the peer's heartbeat interval based on the | ||
561 | * association configured value. | ||
562 | */ | ||
563 | peer->hbinterval = asoc->hbinterval; | ||
564 | |||
565 | /* Set the path max_retrans. */ | ||
566 | peer->pathmaxrxt = asoc->pathmaxrxt; | ||
567 | |||
568 | /* Initialize the peer's SACK delay timeout based on the | ||
569 | * association configured value. | ||
570 | */ | ||
571 | peer->sackdelay = asoc->sackdelay; | ||
572 | |||
573 | /* Enable/disable heartbeat, SACK delay, and path MTU discovery | ||
574 | * based on association setting. | ||
575 | */ | ||
576 | peer->param_flags = asoc->param_flags; | ||
577 | |||
543 | /* Initialize the pmtu of the transport. */ | 578 | /* Initialize the pmtu of the transport. */ |
544 | sctp_transport_pmtu(peer); | 579 | if (peer->param_flags & SPP_PMTUD_ENABLE) |
580 | sctp_transport_pmtu(peer); | ||
581 | else if (asoc->pathmtu) | ||
582 | peer->pathmtu = asoc->pathmtu; | ||
583 | else | ||
584 | peer->pathmtu = SCTP_DEFAULT_MAXSEGMENT; | ||
545 | 585 | ||
546 | /* If this is the first transport addr on this association, | 586 | /* If this is the first transport addr on this association, |
547 | * initialize the association PMTU to the peer's PMTU. | 587 | * initialize the association PMTU to the peer's PMTU. |
548 | * If not and the current association PMTU is higher than the new | 588 | * If not and the current association PMTU is higher than the new |
549 | * peer's PMTU, reset the association PMTU to the new peer's PMTU. | 589 | * peer's PMTU, reset the association PMTU to the new peer's PMTU. |
550 | */ | 590 | */ |
551 | if (asoc->pmtu) | 591 | if (asoc->pathmtu) |
552 | asoc->pmtu = min_t(int, peer->pmtu, asoc->pmtu); | 592 | asoc->pathmtu = min_t(int, peer->pathmtu, asoc->pathmtu); |
553 | else | 593 | else |
554 | asoc->pmtu = peer->pmtu; | 594 | asoc->pathmtu = peer->pathmtu; |
555 | 595 | ||
556 | SCTP_DEBUG_PRINTK("sctp_assoc_add_peer:association %p PMTU set to " | 596 | SCTP_DEBUG_PRINTK("sctp_assoc_add_peer:association %p PMTU set to " |
557 | "%d\n", asoc, asoc->pmtu); | 597 | "%d\n", asoc, asoc->pathmtu); |
558 | 598 | ||
559 | asoc->frag_point = sctp_frag_point(sp, asoc->pmtu); | 599 | asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu); |
560 | 600 | ||
561 | /* The asoc->peer.port might not be meaningful yet, but | 601 | /* The asoc->peer.port might not be meaningful yet, but |
562 | * initialize the packet structure anyway. | 602 | * initialize the packet structure anyway. |
@@ -574,7 +614,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, | |||
574 | * (for example, implementations MAY use the size of the | 614 | * (for example, implementations MAY use the size of the |
575 | * receiver advertised window). | 615 | * receiver advertised window). |
576 | */ | 616 | */ |
577 | peer->cwnd = min(4*asoc->pmtu, max_t(__u32, 2*asoc->pmtu, 4380)); | 617 | peer->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); |
578 | 618 | ||
579 | /* At this point, we may not have the receiver's advertised window, | 619 | /* At this point, we may not have the receiver's advertised window, |
580 | * so initialize ssthresh to the default value and it will be set | 620 | * so initialize ssthresh to the default value and it will be set |
@@ -585,17 +625,6 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, | |||
585 | peer->partial_bytes_acked = 0; | 625 | peer->partial_bytes_acked = 0; |
586 | peer->flight_size = 0; | 626 | peer->flight_size = 0; |
587 | 627 | ||
588 | /* By default, enable heartbeat for peer address. */ | ||
589 | peer->hb_allowed = 1; | ||
590 | |||
591 | /* Initialize the peer's heartbeat interval based on the | ||
592 | * sock configured value. | ||
593 | */ | ||
594 | peer->hb_interval = msecs_to_jiffies(sp->paddrparam.spp_hbinterval); | ||
595 | |||
596 | /* Set the path max_retrans. */ | ||
597 | peer->max_retrans = sp->paddrparam.spp_pathmaxrxt; | ||
598 | |||
599 | /* Set the transport's RTO.initial value */ | 628 | /* Set the transport's RTO.initial value */ |
600 | peer->rto = asoc->rto_initial; | 629 | peer->rto = asoc->rto_initial; |
601 | 630 | ||
@@ -1155,18 +1184,18 @@ void sctp_assoc_sync_pmtu(struct sctp_association *asoc) | |||
1155 | /* Get the lowest pmtu of all the transports. */ | 1184 | /* Get the lowest pmtu of all the transports. */ |
1156 | list_for_each(pos, &asoc->peer.transport_addr_list) { | 1185 | list_for_each(pos, &asoc->peer.transport_addr_list) { |
1157 | t = list_entry(pos, struct sctp_transport, transports); | 1186 | t = list_entry(pos, struct sctp_transport, transports); |
1158 | if (!pmtu || (t->pmtu < pmtu)) | 1187 | if (!pmtu || (t->pathmtu < pmtu)) |
1159 | pmtu = t->pmtu; | 1188 | pmtu = t->pathmtu; |
1160 | } | 1189 | } |
1161 | 1190 | ||
1162 | if (pmtu) { | 1191 | if (pmtu) { |
1163 | struct sctp_sock *sp = sctp_sk(asoc->base.sk); | 1192 | struct sctp_sock *sp = sctp_sk(asoc->base.sk); |
1164 | asoc->pmtu = pmtu; | 1193 | asoc->pathmtu = pmtu; |
1165 | asoc->frag_point = sctp_frag_point(sp, pmtu); | 1194 | asoc->frag_point = sctp_frag_point(sp, pmtu); |
1166 | } | 1195 | } |
1167 | 1196 | ||
1168 | SCTP_DEBUG_PRINTK("%s: asoc:%p, pmtu:%d, frag_point:%d\n", | 1197 | SCTP_DEBUG_PRINTK("%s: asoc:%p, pmtu:%d, frag_point:%d\n", |
1169 | __FUNCTION__, asoc, asoc->pmtu, asoc->frag_point); | 1198 | __FUNCTION__, asoc, asoc->pathmtu, asoc->frag_point); |
1170 | } | 1199 | } |
1171 | 1200 | ||
1172 | /* Should we send a SACK to update our peer? */ | 1201 | /* Should we send a SACK to update our peer? */ |
@@ -1179,7 +1208,7 @@ static inline int sctp_peer_needs_update(struct sctp_association *asoc) | |||
1179 | case SCTP_STATE_SHUTDOWN_SENT: | 1208 | case SCTP_STATE_SHUTDOWN_SENT: |
1180 | if ((asoc->rwnd > asoc->a_rwnd) && | 1209 | if ((asoc->rwnd > asoc->a_rwnd) && |
1181 | ((asoc->rwnd - asoc->a_rwnd) >= | 1210 | ((asoc->rwnd - asoc->a_rwnd) >= |
1182 | min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pmtu))) | 1211 | min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pathmtu))) |
1183 | return 1; | 1212 | return 1; |
1184 | break; | 1213 | break; |
1185 | default: | 1214 | default: |
diff --git a/net/sctp/input.c b/net/sctp/input.c index b24ff2c1aef5..238f1bffa684 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -305,18 +305,36 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) | |||
305 | void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, | 305 | void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, |
306 | struct sctp_transport *t, __u32 pmtu) | 306 | struct sctp_transport *t, __u32 pmtu) |
307 | { | 307 | { |
308 | if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) { | 308 | if (sock_owned_by_user(sk) || !t || (t->pathmtu == pmtu)) |
309 | printk(KERN_WARNING "%s: Reported pmtu %d too low, " | 309 | return; |
310 | "using default minimum of %d\n", __FUNCTION__, pmtu, | ||
311 | SCTP_DEFAULT_MINSEGMENT); | ||
312 | pmtu = SCTP_DEFAULT_MINSEGMENT; | ||
313 | } | ||
314 | 310 | ||
315 | if (!sock_owned_by_user(sk) && t && (t->pmtu != pmtu)) { | 311 | if (t->param_flags & SPP_PMTUD_ENABLE) { |
316 | t->pmtu = pmtu; | 312 | if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) { |
313 | printk(KERN_WARNING "%s: Reported pmtu %d too low, " | ||
314 | "using default minimum of %d\n", | ||
315 | __FUNCTION__, pmtu, | ||
316 | SCTP_DEFAULT_MINSEGMENT); | ||
317 | /* Use default minimum segment size and disable | ||
318 | * pmtu discovery on this transport. | ||
319 | */ | ||
320 | t->pathmtu = SCTP_DEFAULT_MINSEGMENT; | ||
321 | t->param_flags = (t->param_flags & ~SPP_HB) | | ||
322 | SPP_PMTUD_DISABLE; | ||
323 | } else { | ||
324 | t->pathmtu = pmtu; | ||
325 | } | ||
326 | |||
327 | /* Update association pmtu. */ | ||
317 | sctp_assoc_sync_pmtu(asoc); | 328 | sctp_assoc_sync_pmtu(asoc); |
318 | sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD); | ||
319 | } | 329 | } |
330 | |||
331 | /* Retransmit with the new pmtu setting. | ||
332 | * Normally, if PMTU discovery is disabled, an ICMP Fragmentation | ||
333 | * Needed will never be sent, but if a message was sent before | ||
334 | * PMTU discovery was disabled that was larger than the PMTU, it | ||
335 | * would not be fragmented, so it must be re-transmitted fragmented. | ||
336 | */ | ||
337 | sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD); | ||
320 | } | 338 | } |
321 | 339 | ||
322 | /* | 340 | /* |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index fa3be2b8fb5f..15c05165c905 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -866,7 +866,7 @@ static int sctp_inet6_supported_addrs(const struct sctp_sock *opt, | |||
866 | return 2; | 866 | return 2; |
867 | } | 867 | } |
868 | 868 | ||
869 | static struct proto_ops inet6_seqpacket_ops = { | 869 | static const struct proto_ops inet6_seqpacket_ops = { |
870 | .family = PF_INET6, | 870 | .family = PF_INET6, |
871 | .owner = THIS_MODULE, | 871 | .owner = THIS_MODULE, |
872 | .release = inet6_release, | 872 | .release = inet6_release, |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 931371633464..a40991ef72c9 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -234,8 +234,8 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet, | |||
234 | goto finish; | 234 | goto finish; |
235 | 235 | ||
236 | pmtu = ((packet->transport->asoc) ? | 236 | pmtu = ((packet->transport->asoc) ? |
237 | (packet->transport->asoc->pmtu) : | 237 | (packet->transport->asoc->pathmtu) : |
238 | (packet->transport->pmtu)); | 238 | (packet->transport->pathmtu)); |
239 | 239 | ||
240 | too_big = (psize + chunk_len > pmtu); | 240 | too_big = (psize + chunk_len > pmtu); |
241 | 241 | ||
@@ -482,7 +482,9 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
482 | if (!dst || (dst->obsolete > 1)) { | 482 | if (!dst || (dst->obsolete > 1)) { |
483 | dst_release(dst); | 483 | dst_release(dst); |
484 | sctp_transport_route(tp, NULL, sctp_sk(sk)); | 484 | sctp_transport_route(tp, NULL, sctp_sk(sk)); |
485 | sctp_assoc_sync_pmtu(asoc); | 485 | if (asoc->param_flags & SPP_PMTUD_ENABLE) { |
486 | sctp_assoc_sync_pmtu(asoc); | ||
487 | } | ||
486 | } | 488 | } |
487 | 489 | ||
488 | nskb->dst = dst_clone(tp->dst); | 490 | nskb->dst = dst_clone(tp->dst); |
@@ -492,7 +494,10 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
492 | SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n", | 494 | SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n", |
493 | nskb->len); | 495 | nskb->len); |
494 | 496 | ||
495 | (*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok); | 497 | if (tp->param_flags & SPP_PMTUD_ENABLE) |
498 | (*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok); | ||
499 | else | ||
500 | (*tp->af_specific->sctp_xmit)(nskb, tp, 1); | ||
496 | 501 | ||
497 | out: | 502 | out: |
498 | packet->size = packet->overhead; | 503 | packet->size = packet->overhead; |
@@ -577,7 +582,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, | |||
577 | * if ((flightsize + Max.Burst * MTU) < cwnd) | 582 | * if ((flightsize + Max.Burst * MTU) < cwnd) |
578 | * cwnd = flightsize + Max.Burst * MTU | 583 | * cwnd = flightsize + Max.Burst * MTU |
579 | */ | 584 | */ |
580 | max_burst_bytes = asoc->max_burst * asoc->pmtu; | 585 | max_burst_bytes = asoc->max_burst * asoc->pathmtu; |
581 | if ((transport->flight_size + max_burst_bytes) < transport->cwnd) { | 586 | if ((transport->flight_size + max_burst_bytes) < transport->cwnd) { |
582 | transport->cwnd = transport->flight_size + max_burst_bytes; | 587 | transport->cwnd = transport->flight_size + max_burst_bytes; |
583 | SCTP_DEBUG_PRINTK("%s: cwnd limited by max_burst: " | 588 | SCTP_DEBUG_PRINTK("%s: cwnd limited by max_burst: " |
@@ -622,7 +627,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, | |||
622 | * data will fit or delay in hopes of bundling a full | 627 | * data will fit or delay in hopes of bundling a full |
623 | * sized packet. | 628 | * sized packet. |
624 | */ | 629 | */ |
625 | if (len < asoc->pmtu - packet->overhead) { | 630 | if (len < asoc->pathmtu - packet->overhead) { |
626 | retval = SCTP_XMIT_NAGLE_DELAY; | 631 | retval = SCTP_XMIT_NAGLE_DELAY; |
627 | goto finish; | 632 | goto finish; |
628 | } | 633 | } |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index f775d78aa59d..de693b43c8ea 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <net/protocol.h> | 54 | #include <net/protocol.h> |
55 | #include <net/ip.h> | 55 | #include <net/ip.h> |
56 | #include <net/ipv6.h> | 56 | #include <net/ipv6.h> |
57 | #include <net/route.h> | ||
57 | #include <net/sctp/sctp.h> | 58 | #include <net/sctp/sctp.h> |
58 | #include <net/addrconf.h> | 59 | #include <net/addrconf.h> |
59 | #include <net/inet_common.h> | 60 | #include <net/inet_common.h> |
@@ -829,7 +830,7 @@ static struct notifier_block sctp_inetaddr_notifier = { | |||
829 | }; | 830 | }; |
830 | 831 | ||
831 | /* Socket operations. */ | 832 | /* Socket operations. */ |
832 | static struct proto_ops inet_seqpacket_ops = { | 833 | static const struct proto_ops inet_seqpacket_ops = { |
833 | .family = PF_INET, | 834 | .family = PF_INET, |
834 | .owner = THIS_MODULE, | 835 | .owner = THIS_MODULE, |
835 | .release = inet_release, /* Needs to be wrapped... */ | 836 | .release = inet_release, /* Needs to be wrapped... */ |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 823947170a33..2d7d8a5db2ac 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -157,9 +157,12 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force, | |||
157 | { | 157 | { |
158 | __u32 ctsn, max_tsn_seen; | 158 | __u32 ctsn, max_tsn_seen; |
159 | struct sctp_chunk *sack; | 159 | struct sctp_chunk *sack; |
160 | struct sctp_transport *trans = asoc->peer.last_data_from; | ||
160 | int error = 0; | 161 | int error = 0; |
161 | 162 | ||
162 | if (force) | 163 | if (force || |
164 | (!trans && (asoc->param_flags & SPP_SACKDELAY_DISABLE)) || | ||
165 | (trans && (trans->param_flags & SPP_SACKDELAY_DISABLE))) | ||
163 | asoc->peer.sack_needed = 1; | 166 | asoc->peer.sack_needed = 1; |
164 | 167 | ||
165 | ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map); | 168 | ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map); |
@@ -189,7 +192,22 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force, | |||
189 | if (!asoc->peer.sack_needed) { | 192 | if (!asoc->peer.sack_needed) { |
190 | /* We will need a SACK for the next packet. */ | 193 | /* We will need a SACK for the next packet. */ |
191 | asoc->peer.sack_needed = 1; | 194 | asoc->peer.sack_needed = 1; |
192 | goto out; | 195 | |
196 | /* Set the SACK delay timeout based on the | ||
197 | * SACK delay for the last transport | ||
198 | * data was received from, or the default | ||
199 | * for the association. | ||
200 | */ | ||
201 | if (trans) | ||
202 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = | ||
203 | trans->sackdelay; | ||
204 | else | ||
205 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = | ||
206 | asoc->sackdelay; | ||
207 | |||
208 | /* Restart the SACK timer. */ | ||
209 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | ||
210 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); | ||
193 | } else { | 211 | } else { |
194 | if (asoc->a_rwnd > asoc->rwnd) | 212 | if (asoc->a_rwnd > asoc->rwnd) |
195 | asoc->a_rwnd = asoc->rwnd; | 213 | asoc->a_rwnd = asoc->rwnd; |
@@ -205,7 +223,7 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force, | |||
205 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 223 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
206 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); | 224 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); |
207 | } | 225 | } |
208 | out: | 226 | |
209 | return error; | 227 | return error; |
210 | nomem: | 228 | nomem: |
211 | error = -ENOMEM; | 229 | error = -ENOMEM; |
@@ -415,7 +433,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, | |||
415 | asoc->overall_error_count++; | 433 | asoc->overall_error_count++; |
416 | 434 | ||
417 | if (transport->state != SCTP_INACTIVE && | 435 | if (transport->state != SCTP_INACTIVE && |
418 | (transport->error_count++ >= transport->max_retrans)) { | 436 | (transport->error_count++ >= transport->pathmaxrxt)) { |
419 | SCTP_DEBUG_PRINTK_IPADDR("transport_strike:association %p", | 437 | SCTP_DEBUG_PRINTK_IPADDR("transport_strike:association %p", |
420 | " transport IP: port:%d failed.\n", | 438 | " transport IP: port:%d failed.\n", |
421 | asoc, | 439 | asoc, |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 475bfb4972d9..557a7d90b92a 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -900,7 +900,7 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep, | |||
900 | * HEARTBEAT is sent (see Section 8.3). | 900 | * HEARTBEAT is sent (see Section 8.3). |
901 | */ | 901 | */ |
902 | 902 | ||
903 | if (transport->hb_allowed) { | 903 | if (transport->param_flags & SPP_HB_ENABLE) { |
904 | if (SCTP_DISPOSITION_NOMEM == | 904 | if (SCTP_DISPOSITION_NOMEM == |
905 | sctp_sf_heartbeat(ep, asoc, type, arg, | 905 | sctp_sf_heartbeat(ep, asoc, type, arg, |
906 | commands)) | 906 | commands)) |
@@ -1051,7 +1051,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep, | |||
1051 | return SCTP_DISPOSITION_DISCARD; | 1051 | return SCTP_DISPOSITION_DISCARD; |
1052 | } | 1052 | } |
1053 | 1053 | ||
1054 | max_interval = link->hb_interval + link->rto; | 1054 | max_interval = link->hbinterval + link->rto; |
1055 | 1055 | ||
1056 | /* Check if the timestamp looks valid. */ | 1056 | /* Check if the timestamp looks valid. */ |
1057 | if (time_after(hbinfo->sent_at, jiffies) || | 1057 | if (time_after(hbinfo->sent_at, jiffies) || |
@@ -2691,14 +2691,9 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep, | |||
2691 | * document allow. However, an SCTP transmitter MUST NOT be | 2691 | * document allow. However, an SCTP transmitter MUST NOT be |
2692 | * more aggressive than the following algorithms allow. | 2692 | * more aggressive than the following algorithms allow. |
2693 | */ | 2693 | */ |
2694 | if (chunk->end_of_packet) { | 2694 | if (chunk->end_of_packet) |
2695 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); | 2695 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); |
2696 | 2696 | ||
2697 | /* Start the SACK timer. */ | ||
2698 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | ||
2699 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); | ||
2700 | } | ||
2701 | |||
2702 | return SCTP_DISPOSITION_CONSUME; | 2697 | return SCTP_DISPOSITION_CONSUME; |
2703 | 2698 | ||
2704 | discard_force: | 2699 | discard_force: |
@@ -2721,13 +2716,9 @@ discard_force: | |||
2721 | return SCTP_DISPOSITION_DISCARD; | 2716 | return SCTP_DISPOSITION_DISCARD; |
2722 | 2717 | ||
2723 | discard_noforce: | 2718 | discard_noforce: |
2724 | if (chunk->end_of_packet) { | 2719 | if (chunk->end_of_packet) |
2725 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); | 2720 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); |
2726 | 2721 | ||
2727 | /* Start the SACK timer. */ | ||
2728 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | ||
2729 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); | ||
2730 | } | ||
2731 | return SCTP_DISPOSITION_DISCARD; | 2722 | return SCTP_DISPOSITION_DISCARD; |
2732 | consume: | 2723 | consume: |
2733 | return SCTP_DISPOSITION_CONSUME; | 2724 | return SCTP_DISPOSITION_CONSUME; |
@@ -3442,9 +3433,6 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep, | |||
3442 | * send another. | 3433 | * send another. |
3443 | */ | 3434 | */ |
3444 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); | 3435 | sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE()); |
3445 | /* Start the SACK timer. */ | ||
3446 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | ||
3447 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); | ||
3448 | 3436 | ||
3449 | return SCTP_DISPOSITION_CONSUME; | 3437 | return SCTP_DISPOSITION_CONSUME; |
3450 | 3438 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 1f7f244806b7..fc04d185fa33 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -156,10 +156,6 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk) | |||
156 | sizeof(struct sk_buff) + | 156 | sizeof(struct sk_buff) + |
157 | sizeof(struct sctp_chunk); | 157 | sizeof(struct sctp_chunk); |
158 | 158 | ||
159 | sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk) + | ||
160 | sizeof(struct sk_buff) + | ||
161 | sizeof(struct sctp_chunk); | ||
162 | |||
163 | atomic_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc); | 159 | atomic_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc); |
164 | } | 160 | } |
165 | 161 | ||
@@ -1945,107 +1941,379 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | |||
1945 | * address's parameters: | 1941 | * address's parameters: |
1946 | * | 1942 | * |
1947 | * struct sctp_paddrparams { | 1943 | * struct sctp_paddrparams { |
1948 | * sctp_assoc_t spp_assoc_id; | 1944 | * sctp_assoc_t spp_assoc_id; |
1949 | * struct sockaddr_storage spp_address; | 1945 | * struct sockaddr_storage spp_address; |
1950 | * uint32_t spp_hbinterval; | 1946 | * uint32_t spp_hbinterval; |
1951 | * uint16_t spp_pathmaxrxt; | 1947 | * uint16_t spp_pathmaxrxt; |
1952 | * }; | 1948 | * uint32_t spp_pathmtu; |
1953 | * | 1949 | * uint32_t spp_sackdelay; |
1954 | * spp_assoc_id - (UDP style socket) This is filled in the application, | 1950 | * uint32_t spp_flags; |
1955 | * and identifies the association for this query. | 1951 | * }; |
1952 | * | ||
1953 | * spp_assoc_id - (one-to-many style socket) This is filled in the | ||
1954 | * application, and identifies the association for | ||
1955 | * this query. | ||
1956 | * spp_address - This specifies which address is of interest. | 1956 | * spp_address - This specifies which address is of interest. |
1957 | * spp_hbinterval - This contains the value of the heartbeat interval, | 1957 | * spp_hbinterval - This contains the value of the heartbeat interval, |
1958 | * in milliseconds. A value of 0, when modifying the | 1958 | * in milliseconds. If a value of zero |
1959 | * parameter, specifies that the heartbeat on this | 1959 | * is present in this field then no changes are to |
1960 | * address should be disabled. A value of UINT32_MAX | 1960 | * be made to this parameter. |
1961 | * (4294967295), when modifying the parameter, | ||
1962 | * specifies that a heartbeat should be sent | ||
1963 | * immediately to the peer address, and the current | ||
1964 | * interval should remain unchanged. | ||
1965 | * spp_pathmaxrxt - This contains the maximum number of | 1961 | * spp_pathmaxrxt - This contains the maximum number of |
1966 | * retransmissions before this address shall be | 1962 | * retransmissions before this address shall be |
1967 | * considered unreachable. | 1963 | * considered unreachable. If a value of zero |
1964 | * is present in this field then no changes are to | ||
1965 | * be made to this parameter. | ||
1966 | * spp_pathmtu - When Path MTU discovery is disabled the value | ||
1967 | * specified here will be the "fixed" path mtu. | ||
1968 | * Note that if the spp_address field is empty | ||
1969 | * then all associations on this address will | ||
1970 | * have this fixed path mtu set upon them. | ||
1971 | * | ||
1972 | * spp_sackdelay - When delayed sack is enabled, this value specifies | ||
1973 | * the number of milliseconds that sacks will be delayed | ||
1974 | * for. This value will apply to all addresses of an | ||
1975 | * association if the spp_address field is empty. Note | ||
1976 | * also, that if delayed sack is enabled and this | ||
1977 | * value is set to 0, no change is made to the last | ||
1978 | * recorded delayed sack timer value. | ||
1979 | * | ||
1980 | * spp_flags - These flags are used to control various features | ||
1981 | * on an association. The flag field may contain | ||
1982 | * zero or more of the following options. | ||
1983 | * | ||
1984 | * SPP_HB_ENABLE - Enable heartbeats on the | ||
1985 | * specified address. Note that if the address | ||
1986 | * field is empty all addresses for the association | ||
1987 | * have heartbeats enabled upon them. | ||
1988 | * | ||
1989 | * SPP_HB_DISABLE - Disable heartbeats on the | ||
1990 | * speicifed address. Note that if the address | ||
1991 | * field is empty all addresses for the association | ||
1992 | * will have their heartbeats disabled. Note also | ||
1993 | * that SPP_HB_ENABLE and SPP_HB_DISABLE are | ||
1994 | * mutually exclusive, only one of these two should | ||
1995 | * be specified. Enabling both fields will have | ||
1996 | * undetermined results. | ||
1997 | * | ||
1998 | * SPP_HB_DEMAND - Request a user initiated heartbeat | ||
1999 | * to be made immediately. | ||
2000 | * | ||
2001 | * SPP_PMTUD_ENABLE - This field will enable PMTU | ||
2002 | * discovery upon the specified address. Note that | ||
2003 | * if the address feild is empty then all addresses | ||
2004 | * on the association are effected. | ||
2005 | * | ||
2006 | * SPP_PMTUD_DISABLE - This field will disable PMTU | ||
2007 | * discovery upon the specified address. Note that | ||
2008 | * if the address feild is empty then all addresses | ||
2009 | * on the association are effected. Not also that | ||
2010 | * SPP_PMTUD_ENABLE and SPP_PMTUD_DISABLE are mutually | ||
2011 | * exclusive. Enabling both will have undetermined | ||
2012 | * results. | ||
2013 | * | ||
2014 | * SPP_SACKDELAY_ENABLE - Setting this flag turns | ||
2015 | * on delayed sack. The time specified in spp_sackdelay | ||
2016 | * is used to specify the sack delay for this address. Note | ||
2017 | * that if spp_address is empty then all addresses will | ||
2018 | * enable delayed sack and take on the sack delay | ||
2019 | * value specified in spp_sackdelay. | ||
2020 | * SPP_SACKDELAY_DISABLE - Setting this flag turns | ||
2021 | * off delayed sack. If the spp_address field is blank then | ||
2022 | * delayed sack is disabled for the entire association. Note | ||
2023 | * also that this field is mutually exclusive to | ||
2024 | * SPP_SACKDELAY_ENABLE, setting both will have undefined | ||
2025 | * results. | ||
1968 | */ | 2026 | */ |
2027 | int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | ||
2028 | struct sctp_transport *trans, | ||
2029 | struct sctp_association *asoc, | ||
2030 | struct sctp_sock *sp, | ||
2031 | int hb_change, | ||
2032 | int pmtud_change, | ||
2033 | int sackdelay_change) | ||
2034 | { | ||
2035 | int error; | ||
2036 | |||
2037 | if (params->spp_flags & SPP_HB_DEMAND && trans) { | ||
2038 | error = sctp_primitive_REQUESTHEARTBEAT (trans->asoc, trans); | ||
2039 | if (error) | ||
2040 | return error; | ||
2041 | } | ||
2042 | |||
2043 | if (params->spp_hbinterval) { | ||
2044 | if (trans) { | ||
2045 | trans->hbinterval = msecs_to_jiffies(params->spp_hbinterval); | ||
2046 | } else if (asoc) { | ||
2047 | asoc->hbinterval = msecs_to_jiffies(params->spp_hbinterval); | ||
2048 | } else { | ||
2049 | sp->hbinterval = params->spp_hbinterval; | ||
2050 | } | ||
2051 | } | ||
2052 | |||
2053 | if (hb_change) { | ||
2054 | if (trans) { | ||
2055 | trans->param_flags = | ||
2056 | (trans->param_flags & ~SPP_HB) | hb_change; | ||
2057 | } else if (asoc) { | ||
2058 | asoc->param_flags = | ||
2059 | (asoc->param_flags & ~SPP_HB) | hb_change; | ||
2060 | } else { | ||
2061 | sp->param_flags = | ||
2062 | (sp->param_flags & ~SPP_HB) | hb_change; | ||
2063 | } | ||
2064 | } | ||
2065 | |||
2066 | if (params->spp_pathmtu) { | ||
2067 | if (trans) { | ||
2068 | trans->pathmtu = params->spp_pathmtu; | ||
2069 | sctp_assoc_sync_pmtu(asoc); | ||
2070 | } else if (asoc) { | ||
2071 | asoc->pathmtu = params->spp_pathmtu; | ||
2072 | sctp_frag_point(sp, params->spp_pathmtu); | ||
2073 | } else { | ||
2074 | sp->pathmtu = params->spp_pathmtu; | ||
2075 | } | ||
2076 | } | ||
2077 | |||
2078 | if (pmtud_change) { | ||
2079 | if (trans) { | ||
2080 | int update = (trans->param_flags & SPP_PMTUD_DISABLE) && | ||
2081 | (params->spp_flags & SPP_PMTUD_ENABLE); | ||
2082 | trans->param_flags = | ||
2083 | (trans->param_flags & ~SPP_PMTUD) | pmtud_change; | ||
2084 | if (update) { | ||
2085 | sctp_transport_pmtu(trans); | ||
2086 | sctp_assoc_sync_pmtu(asoc); | ||
2087 | } | ||
2088 | } else if (asoc) { | ||
2089 | asoc->param_flags = | ||
2090 | (asoc->param_flags & ~SPP_PMTUD) | pmtud_change; | ||
2091 | } else { | ||
2092 | sp->param_flags = | ||
2093 | (sp->param_flags & ~SPP_PMTUD) | pmtud_change; | ||
2094 | } | ||
2095 | } | ||
2096 | |||
2097 | if (params->spp_sackdelay) { | ||
2098 | if (trans) { | ||
2099 | trans->sackdelay = | ||
2100 | msecs_to_jiffies(params->spp_sackdelay); | ||
2101 | } else if (asoc) { | ||
2102 | asoc->sackdelay = | ||
2103 | msecs_to_jiffies(params->spp_sackdelay); | ||
2104 | } else { | ||
2105 | sp->sackdelay = params->spp_sackdelay; | ||
2106 | } | ||
2107 | } | ||
2108 | |||
2109 | if (sackdelay_change) { | ||
2110 | if (trans) { | ||
2111 | trans->param_flags = | ||
2112 | (trans->param_flags & ~SPP_SACKDELAY) | | ||
2113 | sackdelay_change; | ||
2114 | } else if (asoc) { | ||
2115 | asoc->param_flags = | ||
2116 | (asoc->param_flags & ~SPP_SACKDELAY) | | ||
2117 | sackdelay_change; | ||
2118 | } else { | ||
2119 | sp->param_flags = | ||
2120 | (sp->param_flags & ~SPP_SACKDELAY) | | ||
2121 | sackdelay_change; | ||
2122 | } | ||
2123 | } | ||
2124 | |||
2125 | if (params->spp_pathmaxrxt) { | ||
2126 | if (trans) { | ||
2127 | trans->pathmaxrxt = params->spp_pathmaxrxt; | ||
2128 | } else if (asoc) { | ||
2129 | asoc->pathmaxrxt = params->spp_pathmaxrxt; | ||
2130 | } else { | ||
2131 | sp->pathmaxrxt = params->spp_pathmaxrxt; | ||
2132 | } | ||
2133 | } | ||
2134 | |||
2135 | return 0; | ||
2136 | } | ||
2137 | |||
1969 | static int sctp_setsockopt_peer_addr_params(struct sock *sk, | 2138 | static int sctp_setsockopt_peer_addr_params(struct sock *sk, |
1970 | char __user *optval, int optlen) | 2139 | char __user *optval, int optlen) |
1971 | { | 2140 | { |
1972 | struct sctp_paddrparams params; | 2141 | struct sctp_paddrparams params; |
1973 | struct sctp_transport *trans; | 2142 | struct sctp_transport *trans = NULL; |
2143 | struct sctp_association *asoc = NULL; | ||
2144 | struct sctp_sock *sp = sctp_sk(sk); | ||
1974 | int error; | 2145 | int error; |
2146 | int hb_change, pmtud_change, sackdelay_change; | ||
1975 | 2147 | ||
1976 | if (optlen != sizeof(struct sctp_paddrparams)) | 2148 | if (optlen != sizeof(struct sctp_paddrparams)) |
1977 | return -EINVAL; | 2149 | return - EINVAL; |
2150 | |||
1978 | if (copy_from_user(¶ms, optval, optlen)) | 2151 | if (copy_from_user(¶ms, optval, optlen)) |
1979 | return -EFAULT; | 2152 | return -EFAULT; |
1980 | 2153 | ||
1981 | /* | 2154 | /* Validate flags and value parameters. */ |
1982 | * API 7. Socket Options (setting the default value for the endpoint) | 2155 | hb_change = params.spp_flags & SPP_HB; |
1983 | * All options that support specific settings on an association by | 2156 | pmtud_change = params.spp_flags & SPP_PMTUD; |
1984 | * filling in either an association id variable or a sockaddr_storage | 2157 | sackdelay_change = params.spp_flags & SPP_SACKDELAY; |
1985 | * SHOULD also support setting of the same value for the entire endpoint | 2158 | |
1986 | * (i.e. future associations). To accomplish this the following logic is | 2159 | if (hb_change == SPP_HB || |
1987 | * used when setting one of these options: | 2160 | pmtud_change == SPP_PMTUD || |
1988 | 2161 | sackdelay_change == SPP_SACKDELAY || | |
1989 | * c) If neither the sockaddr_storage or association identification is | 2162 | params.spp_sackdelay > 500 || |
1990 | * set i.e. the sockaddr_storage is set to all 0's (INADDR_ANY) and | 2163 | (params.spp_pathmtu |
1991 | * the association identification is 0, the settings are a default | 2164 | && params.spp_pathmtu < SCTP_DEFAULT_MINSEGMENT)) |
1992 | * and to be applied to the endpoint (all future associations). | 2165 | return -EINVAL; |
1993 | */ | ||
1994 | 2166 | ||
1995 | /* update default value for endpoint (all future associations) */ | 2167 | /* If an address other than INADDR_ANY is specified, and |
1996 | if (!params.spp_assoc_id && | 2168 | * no transport is found, then the request is invalid. |
1997 | sctp_is_any(( union sctp_addr *)¶ms.spp_address)) { | 2169 | */ |
1998 | /* Manual heartbeat on an endpoint is invalid. */ | 2170 | if (!sctp_is_any(( union sctp_addr *)¶ms.spp_address)) { |
1999 | if (0xffffffff == params.spp_hbinterval) | 2171 | trans = sctp_addr_id2transport(sk, ¶ms.spp_address, |
2172 | params.spp_assoc_id); | ||
2173 | if (!trans) | ||
2000 | return -EINVAL; | 2174 | return -EINVAL; |
2001 | else if (params.spp_hbinterval) | ||
2002 | sctp_sk(sk)->paddrparam.spp_hbinterval = | ||
2003 | params.spp_hbinterval; | ||
2004 | if (params.spp_pathmaxrxt) | ||
2005 | sctp_sk(sk)->paddrparam.spp_pathmaxrxt = | ||
2006 | params.spp_pathmaxrxt; | ||
2007 | return 0; | ||
2008 | } | 2175 | } |
2009 | 2176 | ||
2010 | trans = sctp_addr_id2transport(sk, ¶ms.spp_address, | 2177 | /* Get association, if assoc_id != 0 and the socket is a one |
2011 | params.spp_assoc_id); | 2178 | * to many style socket, and an association was not found, then |
2012 | if (!trans) | 2179 | * the id was invalid. |
2180 | */ | ||
2181 | asoc = sctp_id2assoc(sk, params.spp_assoc_id); | ||
2182 | if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP)) | ||
2013 | return -EINVAL; | 2183 | return -EINVAL; |
2014 | 2184 | ||
2015 | /* Applications can enable or disable heartbeats for any peer address | 2185 | /* Heartbeat demand can only be sent on a transport or |
2016 | * of an association, modify an address's heartbeat interval, force a | 2186 | * association, but not a socket. |
2017 | * heartbeat to be sent immediately, and adjust the address's maximum | ||
2018 | * number of retransmissions sent before an address is considered | ||
2019 | * unreachable. | ||
2020 | * | ||
2021 | * The value of the heartbeat interval, in milliseconds. A value of | ||
2022 | * UINT32_MAX (4294967295), when modifying the parameter, specifies | ||
2023 | * that a heartbeat should be sent immediately to the peer address, | ||
2024 | * and the current interval should remain unchanged. | ||
2025 | */ | 2187 | */ |
2026 | if (0xffffffff == params.spp_hbinterval) { | 2188 | if (params.spp_flags & SPP_HB_DEMAND && !trans && !asoc) |
2027 | error = sctp_primitive_REQUESTHEARTBEAT (trans->asoc, trans); | 2189 | return -EINVAL; |
2028 | if (error) | 2190 | |
2029 | return error; | 2191 | /* Process parameters. */ |
2030 | } else { | 2192 | error = sctp_apply_peer_addr_params(¶ms, trans, asoc, sp, |
2031 | /* The value of the heartbeat interval, in milliseconds. A value of 0, | 2193 | hb_change, pmtud_change, |
2032 | * when modifying the parameter, specifies that the heartbeat on this | 2194 | sackdelay_change); |
2033 | * address should be disabled. | 2195 | |
2196 | if (error) | ||
2197 | return error; | ||
2198 | |||
2199 | /* If changes are for association, also apply parameters to each | ||
2200 | * transport. | ||
2034 | */ | 2201 | */ |
2035 | if (params.spp_hbinterval) { | 2202 | if (!trans && asoc) { |
2036 | trans->hb_allowed = 1; | 2203 | struct list_head *pos; |
2037 | trans->hb_interval = | 2204 | |
2038 | msecs_to_jiffies(params.spp_hbinterval); | 2205 | list_for_each(pos, &asoc->peer.transport_addr_list) { |
2039 | } else | 2206 | trans = list_entry(pos, struct sctp_transport, |
2040 | trans->hb_allowed = 0; | 2207 | transports); |
2208 | sctp_apply_peer_addr_params(¶ms, trans, asoc, sp, | ||
2209 | hb_change, pmtud_change, | ||
2210 | sackdelay_change); | ||
2211 | } | ||
2041 | } | 2212 | } |
2042 | 2213 | ||
2043 | /* spp_pathmaxrxt contains the maximum number of retransmissions | 2214 | return 0; |
2044 | * before this address shall be considered unreachable. | 2215 | } |
2045 | */ | 2216 | |
2046 | if (params.spp_pathmaxrxt) | 2217 | /* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) |
2047 | trans->max_retrans = params.spp_pathmaxrxt; | 2218 | * |
2219 | * This options will get or set the delayed ack timer. The time is set | ||
2220 | * in milliseconds. If the assoc_id is 0, then this sets or gets the | ||
2221 | * endpoints default delayed ack timer value. If the assoc_id field is | ||
2222 | * non-zero, then the set or get effects the specified association. | ||
2223 | * | ||
2224 | * struct sctp_assoc_value { | ||
2225 | * sctp_assoc_t assoc_id; | ||
2226 | * uint32_t assoc_value; | ||
2227 | * }; | ||
2228 | * | ||
2229 | * assoc_id - This parameter, indicates which association the | ||
2230 | * user is preforming an action upon. Note that if | ||
2231 | * this field's value is zero then the endpoints | ||
2232 | * default value is changed (effecting future | ||
2233 | * associations only). | ||
2234 | * | ||
2235 | * assoc_value - This parameter contains the number of milliseconds | ||
2236 | * that the user is requesting the delayed ACK timer | ||
2237 | * be set to. Note that this value is defined in | ||
2238 | * the standard to be between 200 and 500 milliseconds. | ||
2239 | * | ||
2240 | * Note: a value of zero will leave the value alone, | ||
2241 | * but disable SACK delay. A non-zero value will also | ||
2242 | * enable SACK delay. | ||
2243 | */ | ||
2048 | 2244 | ||
2245 | static int sctp_setsockopt_delayed_ack_time(struct sock *sk, | ||
2246 | char __user *optval, int optlen) | ||
2247 | { | ||
2248 | struct sctp_assoc_value params; | ||
2249 | struct sctp_transport *trans = NULL; | ||
2250 | struct sctp_association *asoc = NULL; | ||
2251 | struct sctp_sock *sp = sctp_sk(sk); | ||
2252 | |||
2253 | if (optlen != sizeof(struct sctp_assoc_value)) | ||
2254 | return - EINVAL; | ||
2255 | |||
2256 | if (copy_from_user(¶ms, optval, optlen)) | ||
2257 | return -EFAULT; | ||
2258 | |||
2259 | /* Validate value parameter. */ | ||
2260 | if (params.assoc_value > 500) | ||
2261 | return -EINVAL; | ||
2262 | |||
2263 | /* Get association, if assoc_id != 0 and the socket is a one | ||
2264 | * to many style socket, and an association was not found, then | ||
2265 | * the id was invalid. | ||
2266 | */ | ||
2267 | asoc = sctp_id2assoc(sk, params.assoc_id); | ||
2268 | if (!asoc && params.assoc_id && sctp_style(sk, UDP)) | ||
2269 | return -EINVAL; | ||
2270 | |||
2271 | if (params.assoc_value) { | ||
2272 | if (asoc) { | ||
2273 | asoc->sackdelay = | ||
2274 | msecs_to_jiffies(params.assoc_value); | ||
2275 | asoc->param_flags = | ||
2276 | (asoc->param_flags & ~SPP_SACKDELAY) | | ||
2277 | SPP_SACKDELAY_ENABLE; | ||
2278 | } else { | ||
2279 | sp->sackdelay = params.assoc_value; | ||
2280 | sp->param_flags = | ||
2281 | (sp->param_flags & ~SPP_SACKDELAY) | | ||
2282 | SPP_SACKDELAY_ENABLE; | ||
2283 | } | ||
2284 | } else { | ||
2285 | if (asoc) { | ||
2286 | asoc->param_flags = | ||
2287 | (asoc->param_flags & ~SPP_SACKDELAY) | | ||
2288 | SPP_SACKDELAY_DISABLE; | ||
2289 | } else { | ||
2290 | sp->param_flags = | ||
2291 | (sp->param_flags & ~SPP_SACKDELAY) | | ||
2292 | SPP_SACKDELAY_DISABLE; | ||
2293 | } | ||
2294 | } | ||
2295 | |||
2296 | /* If change is for association, also apply to each transport. */ | ||
2297 | if (asoc) { | ||
2298 | struct list_head *pos; | ||
2299 | |||
2300 | list_for_each(pos, &asoc->peer.transport_addr_list) { | ||
2301 | trans = list_entry(pos, struct sctp_transport, | ||
2302 | transports); | ||
2303 | if (params.assoc_value) { | ||
2304 | trans->sackdelay = | ||
2305 | msecs_to_jiffies(params.assoc_value); | ||
2306 | trans->param_flags = | ||
2307 | (trans->param_flags & ~SPP_SACKDELAY) | | ||
2308 | SPP_SACKDELAY_ENABLE; | ||
2309 | } else { | ||
2310 | trans->param_flags = | ||
2311 | (trans->param_flags & ~SPP_SACKDELAY) | | ||
2312 | SPP_SACKDELAY_DISABLE; | ||
2313 | } | ||
2314 | } | ||
2315 | } | ||
2316 | |||
2049 | return 0; | 2317 | return 0; |
2050 | } | 2318 | } |
2051 | 2319 | ||
@@ -2338,7 +2606,7 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optl | |||
2338 | /* Update the frag_point of the existing associations. */ | 2606 | /* Update the frag_point of the existing associations. */ |
2339 | list_for_each(pos, &(sp->ep->asocs)) { | 2607 | list_for_each(pos, &(sp->ep->asocs)) { |
2340 | asoc = list_entry(pos, struct sctp_association, asocs); | 2608 | asoc = list_entry(pos, struct sctp_association, asocs); |
2341 | asoc->frag_point = sctp_frag_point(sp, asoc->pmtu); | 2609 | asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu); |
2342 | } | 2610 | } |
2343 | 2611 | ||
2344 | return 0; | 2612 | return 0; |
@@ -2495,6 +2763,10 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
2495 | retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen); | 2763 | retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen); |
2496 | break; | 2764 | break; |
2497 | 2765 | ||
2766 | case SCTP_DELAYED_ACK_TIME: | ||
2767 | retval = sctp_setsockopt_delayed_ack_time(sk, optval, optlen); | ||
2768 | break; | ||
2769 | |||
2498 | case SCTP_INITMSG: | 2770 | case SCTP_INITMSG: |
2499 | retval = sctp_setsockopt_initmsg(sk, optval, optlen); | 2771 | retval = sctp_setsockopt_initmsg(sk, optval, optlen); |
2500 | break; | 2772 | break; |
@@ -2719,8 +2991,13 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
2719 | /* Default Peer Address Parameters. These defaults can | 2991 | /* Default Peer Address Parameters. These defaults can |
2720 | * be modified via SCTP_PEER_ADDR_PARAMS | 2992 | * be modified via SCTP_PEER_ADDR_PARAMS |
2721 | */ | 2993 | */ |
2722 | sp->paddrparam.spp_hbinterval = jiffies_to_msecs(sctp_hb_interval); | 2994 | sp->hbinterval = jiffies_to_msecs(sctp_hb_interval); |
2723 | sp->paddrparam.spp_pathmaxrxt = sctp_max_retrans_path; | 2995 | sp->pathmaxrxt = sctp_max_retrans_path; |
2996 | sp->pathmtu = 0; // allow default discovery | ||
2997 | sp->sackdelay = sctp_sack_timeout; | ||
2998 | sp->param_flags = SPP_HB_ENABLE | | ||
2999 | SPP_PMTUD_ENABLE | | ||
3000 | SPP_SACKDELAY_ENABLE; | ||
2724 | 3001 | ||
2725 | /* If enabled no SCTP message fragmentation will be performed. | 3002 | /* If enabled no SCTP message fragmentation will be performed. |
2726 | * Configure through SCTP_DISABLE_FRAGMENTS socket option. | 3003 | * Configure through SCTP_DISABLE_FRAGMENTS socket option. |
@@ -2869,7 +3146,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, | |||
2869 | status.sstat_primary.spinfo_cwnd = transport->cwnd; | 3146 | status.sstat_primary.spinfo_cwnd = transport->cwnd; |
2870 | status.sstat_primary.spinfo_srtt = transport->srtt; | 3147 | status.sstat_primary.spinfo_srtt = transport->srtt; |
2871 | status.sstat_primary.spinfo_rto = jiffies_to_msecs(transport->rto); | 3148 | status.sstat_primary.spinfo_rto = jiffies_to_msecs(transport->rto); |
2872 | status.sstat_primary.spinfo_mtu = transport->pmtu; | 3149 | status.sstat_primary.spinfo_mtu = transport->pathmtu; |
2873 | 3150 | ||
2874 | if (status.sstat_primary.spinfo_state == SCTP_UNKNOWN) | 3151 | if (status.sstat_primary.spinfo_state == SCTP_UNKNOWN) |
2875 | status.sstat_primary.spinfo_state = SCTP_ACTIVE; | 3152 | status.sstat_primary.spinfo_state = SCTP_ACTIVE; |
@@ -2928,7 +3205,7 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len, | |||
2928 | pinfo.spinfo_cwnd = transport->cwnd; | 3205 | pinfo.spinfo_cwnd = transport->cwnd; |
2929 | pinfo.spinfo_srtt = transport->srtt; | 3206 | pinfo.spinfo_srtt = transport->srtt; |
2930 | pinfo.spinfo_rto = jiffies_to_msecs(transport->rto); | 3207 | pinfo.spinfo_rto = jiffies_to_msecs(transport->rto); |
2931 | pinfo.spinfo_mtu = transport->pmtu; | 3208 | pinfo.spinfo_mtu = transport->pathmtu; |
2932 | 3209 | ||
2933 | if (pinfo.spinfo_state == SCTP_UNKNOWN) | 3210 | if (pinfo.spinfo_state == SCTP_UNKNOWN) |
2934 | pinfo.spinfo_state = SCTP_ACTIVE; | 3211 | pinfo.spinfo_state = SCTP_ACTIVE; |
@@ -3090,69 +3367,227 @@ out: | |||
3090 | * address's parameters: | 3367 | * address's parameters: |
3091 | * | 3368 | * |
3092 | * struct sctp_paddrparams { | 3369 | * struct sctp_paddrparams { |
3093 | * sctp_assoc_t spp_assoc_id; | 3370 | * sctp_assoc_t spp_assoc_id; |
3094 | * struct sockaddr_storage spp_address; | 3371 | * struct sockaddr_storage spp_address; |
3095 | * uint32_t spp_hbinterval; | 3372 | * uint32_t spp_hbinterval; |
3096 | * uint16_t spp_pathmaxrxt; | 3373 | * uint16_t spp_pathmaxrxt; |
3097 | * }; | 3374 | * uint32_t spp_pathmtu; |
3098 | * | 3375 | * uint32_t spp_sackdelay; |
3099 | * spp_assoc_id - (UDP style socket) This is filled in the application, | 3376 | * uint32_t spp_flags; |
3100 | * and identifies the association for this query. | 3377 | * }; |
3378 | * | ||
3379 | * spp_assoc_id - (one-to-many style socket) This is filled in the | ||
3380 | * application, and identifies the association for | ||
3381 | * this query. | ||
3101 | * spp_address - This specifies which address is of interest. | 3382 | * spp_address - This specifies which address is of interest. |
3102 | * spp_hbinterval - This contains the value of the heartbeat interval, | 3383 | * spp_hbinterval - This contains the value of the heartbeat interval, |
3103 | * in milliseconds. A value of 0, when modifying the | 3384 | * in milliseconds. If a value of zero |
3104 | * parameter, specifies that the heartbeat on this | 3385 | * is present in this field then no changes are to |
3105 | * address should be disabled. A value of UINT32_MAX | 3386 | * be made to this parameter. |
3106 | * (4294967295), when modifying the parameter, | ||
3107 | * specifies that a heartbeat should be sent | ||
3108 | * immediately to the peer address, and the current | ||
3109 | * interval should remain unchanged. | ||
3110 | * spp_pathmaxrxt - This contains the maximum number of | 3387 | * spp_pathmaxrxt - This contains the maximum number of |
3111 | * retransmissions before this address shall be | 3388 | * retransmissions before this address shall be |
3112 | * considered unreachable. | 3389 | * considered unreachable. If a value of zero |
3390 | * is present in this field then no changes are to | ||
3391 | * be made to this parameter. | ||
3392 | * spp_pathmtu - When Path MTU discovery is disabled the value | ||
3393 | * specified here will be the "fixed" path mtu. | ||
3394 | * Note that if the spp_address field is empty | ||
3395 | * then all associations on this address will | ||
3396 | * have this fixed path mtu set upon them. | ||
3397 | * | ||
3398 | * spp_sackdelay - When delayed sack is enabled, this value specifies | ||
3399 | * the number of milliseconds that sacks will be delayed | ||
3400 | * for. This value will apply to all addresses of an | ||
3401 | * association if the spp_address field is empty. Note | ||
3402 | * also, that if delayed sack is enabled and this | ||
3403 | * value is set to 0, no change is made to the last | ||
3404 | * recorded delayed sack timer value. | ||
3405 | * | ||
3406 | * spp_flags - These flags are used to control various features | ||
3407 | * on an association. The flag field may contain | ||
3408 | * zero or more of the following options. | ||
3409 | * | ||
3410 | * SPP_HB_ENABLE - Enable heartbeats on the | ||
3411 | * specified address. Note that if the address | ||
3412 | * field is empty all addresses for the association | ||
3413 | * have heartbeats enabled upon them. | ||
3414 | * | ||
3415 | * SPP_HB_DISABLE - Disable heartbeats on the | ||
3416 | * speicifed address. Note that if the address | ||
3417 | * field is empty all addresses for the association | ||
3418 | * will have their heartbeats disabled. Note also | ||
3419 | * that SPP_HB_ENABLE and SPP_HB_DISABLE are | ||
3420 | * mutually exclusive, only one of these two should | ||
3421 | * be specified. Enabling both fields will have | ||
3422 | * undetermined results. | ||
3423 | * | ||
3424 | * SPP_HB_DEMAND - Request a user initiated heartbeat | ||
3425 | * to be made immediately. | ||
3426 | * | ||
3427 | * SPP_PMTUD_ENABLE - This field will enable PMTU | ||
3428 | * discovery upon the specified address. Note that | ||
3429 | * if the address feild is empty then all addresses | ||
3430 | * on the association are effected. | ||
3431 | * | ||
3432 | * SPP_PMTUD_DISABLE - This field will disable PMTU | ||
3433 | * discovery upon the specified address. Note that | ||
3434 | * if the address feild is empty then all addresses | ||
3435 | * on the association are effected. Not also that | ||
3436 | * SPP_PMTUD_ENABLE and SPP_PMTUD_DISABLE are mutually | ||
3437 | * exclusive. Enabling both will have undetermined | ||
3438 | * results. | ||
3439 | * | ||
3440 | * SPP_SACKDELAY_ENABLE - Setting this flag turns | ||
3441 | * on delayed sack. The time specified in spp_sackdelay | ||
3442 | * is used to specify the sack delay for this address. Note | ||
3443 | * that if spp_address is empty then all addresses will | ||
3444 | * enable delayed sack and take on the sack delay | ||
3445 | * value specified in spp_sackdelay. | ||
3446 | * SPP_SACKDELAY_DISABLE - Setting this flag turns | ||
3447 | * off delayed sack. If the spp_address field is blank then | ||
3448 | * delayed sack is disabled for the entire association. Note | ||
3449 | * also that this field is mutually exclusive to | ||
3450 | * SPP_SACKDELAY_ENABLE, setting both will have undefined | ||
3451 | * results. | ||
3113 | */ | 3452 | */ |
3114 | static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, | 3453 | static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, |
3115 | char __user *optval, int __user *optlen) | 3454 | char __user *optval, int __user *optlen) |
3116 | { | 3455 | { |
3117 | struct sctp_paddrparams params; | 3456 | struct sctp_paddrparams params; |
3118 | struct sctp_transport *trans; | 3457 | struct sctp_transport *trans = NULL; |
3458 | struct sctp_association *asoc = NULL; | ||
3459 | struct sctp_sock *sp = sctp_sk(sk); | ||
3119 | 3460 | ||
3120 | if (len != sizeof(struct sctp_paddrparams)) | 3461 | if (len != sizeof(struct sctp_paddrparams)) |
3121 | return -EINVAL; | 3462 | return -EINVAL; |
3463 | |||
3122 | if (copy_from_user(¶ms, optval, len)) | 3464 | if (copy_from_user(¶ms, optval, len)) |
3123 | return -EFAULT; | 3465 | return -EFAULT; |
3124 | 3466 | ||
3125 | /* If no association id is specified retrieve the default value | 3467 | /* If an address other than INADDR_ANY is specified, and |
3126 | * for the endpoint that will be used for all future associations | 3468 | * no transport is found, then the request is invalid. |
3127 | */ | 3469 | */ |
3128 | if (!params.spp_assoc_id && | 3470 | if (!sctp_is_any(( union sctp_addr *)¶ms.spp_address)) { |
3129 | sctp_is_any(( union sctp_addr *)¶ms.spp_address)) { | 3471 | trans = sctp_addr_id2transport(sk, ¶ms.spp_address, |
3130 | params.spp_hbinterval = sctp_sk(sk)->paddrparam.spp_hbinterval; | 3472 | params.spp_assoc_id); |
3131 | params.spp_pathmaxrxt = sctp_sk(sk)->paddrparam.spp_pathmaxrxt; | 3473 | if (!trans) { |
3132 | 3474 | SCTP_DEBUG_PRINTK("Failed no transport\n"); | |
3133 | goto done; | 3475 | return -EINVAL; |
3476 | } | ||
3134 | } | 3477 | } |
3135 | 3478 | ||
3136 | trans = sctp_addr_id2transport(sk, ¶ms.spp_address, | 3479 | /* Get association, if assoc_id != 0 and the socket is a one |
3137 | params.spp_assoc_id); | 3480 | * to many style socket, and an association was not found, then |
3138 | if (!trans) | 3481 | * the id was invalid. |
3482 | */ | ||
3483 | asoc = sctp_id2assoc(sk, params.spp_assoc_id); | ||
3484 | if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP)) { | ||
3485 | SCTP_DEBUG_PRINTK("Failed no association\n"); | ||
3139 | return -EINVAL; | 3486 | return -EINVAL; |
3487 | } | ||
3140 | 3488 | ||
3141 | /* The value of the heartbeat interval, in milliseconds. A value of 0, | 3489 | if (trans) { |
3142 | * when modifying the parameter, specifies that the heartbeat on this | 3490 | /* Fetch transport values. */ |
3143 | * address should be disabled. | 3491 | params.spp_hbinterval = jiffies_to_msecs(trans->hbinterval); |
3144 | */ | 3492 | params.spp_pathmtu = trans->pathmtu; |
3145 | if (!trans->hb_allowed) | 3493 | params.spp_pathmaxrxt = trans->pathmaxrxt; |
3146 | params.spp_hbinterval = 0; | 3494 | params.spp_sackdelay = jiffies_to_msecs(trans->sackdelay); |
3147 | else | 3495 | |
3148 | params.spp_hbinterval = jiffies_to_msecs(trans->hb_interval); | 3496 | /*draft-11 doesn't say what to return in spp_flags*/ |
3497 | params.spp_flags = trans->param_flags; | ||
3498 | } else if (asoc) { | ||
3499 | /* Fetch association values. */ | ||
3500 | params.spp_hbinterval = jiffies_to_msecs(asoc->hbinterval); | ||
3501 | params.spp_pathmtu = asoc->pathmtu; | ||
3502 | params.spp_pathmaxrxt = asoc->pathmaxrxt; | ||
3503 | params.spp_sackdelay = jiffies_to_msecs(asoc->sackdelay); | ||
3504 | |||
3505 | /*draft-11 doesn't say what to return in spp_flags*/ | ||
3506 | params.spp_flags = asoc->param_flags; | ||
3507 | } else { | ||
3508 | /* Fetch socket values. */ | ||
3509 | params.spp_hbinterval = sp->hbinterval; | ||
3510 | params.spp_pathmtu = sp->pathmtu; | ||
3511 | params.spp_sackdelay = sp->sackdelay; | ||
3512 | params.spp_pathmaxrxt = sp->pathmaxrxt; | ||
3513 | |||
3514 | /*draft-11 doesn't say what to return in spp_flags*/ | ||
3515 | params.spp_flags = sp->param_flags; | ||
3516 | } | ||
3149 | 3517 | ||
3150 | /* spp_pathmaxrxt contains the maximum number of retransmissions | 3518 | if (copy_to_user(optval, ¶ms, len)) |
3151 | * before this address shall be considered unreachable. | 3519 | return -EFAULT; |
3152 | */ | 3520 | |
3153 | params.spp_pathmaxrxt = trans->max_retrans; | 3521 | if (put_user(len, optlen)) |
3522 | return -EFAULT; | ||
3523 | |||
3524 | return 0; | ||
3525 | } | ||
3526 | |||
3527 | /* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) | ||
3528 | * | ||
3529 | * This options will get or set the delayed ack timer. The time is set | ||
3530 | * in milliseconds. If the assoc_id is 0, then this sets or gets the | ||
3531 | * endpoints default delayed ack timer value. If the assoc_id field is | ||
3532 | * non-zero, then the set or get effects the specified association. | ||
3533 | * | ||
3534 | * struct sctp_assoc_value { | ||
3535 | * sctp_assoc_t assoc_id; | ||
3536 | * uint32_t assoc_value; | ||
3537 | * }; | ||
3538 | * | ||
3539 | * assoc_id - This parameter, indicates which association the | ||
3540 | * user is preforming an action upon. Note that if | ||
3541 | * this field's value is zero then the endpoints | ||
3542 | * default value is changed (effecting future | ||
3543 | * associations only). | ||
3544 | * | ||
3545 | * assoc_value - This parameter contains the number of milliseconds | ||
3546 | * that the user is requesting the delayed ACK timer | ||
3547 | * be set to. Note that this value is defined in | ||
3548 | * the standard to be between 200 and 500 milliseconds. | ||
3549 | * | ||
3550 | * Note: a value of zero will leave the value alone, | ||
3551 | * but disable SACK delay. A non-zero value will also | ||
3552 | * enable SACK delay. | ||
3553 | */ | ||
3554 | static int sctp_getsockopt_delayed_ack_time(struct sock *sk, int len, | ||
3555 | char __user *optval, | ||
3556 | int __user *optlen) | ||
3557 | { | ||
3558 | struct sctp_assoc_value params; | ||
3559 | struct sctp_association *asoc = NULL; | ||
3560 | struct sctp_sock *sp = sctp_sk(sk); | ||
3561 | |||
3562 | if (len != sizeof(struct sctp_assoc_value)) | ||
3563 | return - EINVAL; | ||
3564 | |||
3565 | if (copy_from_user(¶ms, optval, len)) | ||
3566 | return -EFAULT; | ||
3567 | |||
3568 | /* Get association, if assoc_id != 0 and the socket is a one | ||
3569 | * to many style socket, and an association was not found, then | ||
3570 | * the id was invalid. | ||
3571 | */ | ||
3572 | asoc = sctp_id2assoc(sk, params.assoc_id); | ||
3573 | if (!asoc && params.assoc_id && sctp_style(sk, UDP)) | ||
3574 | return -EINVAL; | ||
3575 | |||
3576 | if (asoc) { | ||
3577 | /* Fetch association values. */ | ||
3578 | if (asoc->param_flags & SPP_SACKDELAY_ENABLE) | ||
3579 | params.assoc_value = jiffies_to_msecs( | ||
3580 | asoc->sackdelay); | ||
3581 | else | ||
3582 | params.assoc_value = 0; | ||
3583 | } else { | ||
3584 | /* Fetch socket values. */ | ||
3585 | if (sp->param_flags & SPP_SACKDELAY_ENABLE) | ||
3586 | params.assoc_value = sp->sackdelay; | ||
3587 | else | ||
3588 | params.assoc_value = 0; | ||
3589 | } | ||
3154 | 3590 | ||
3155 | done: | ||
3156 | if (copy_to_user(optval, ¶ms, len)) | 3591 | if (copy_to_user(optval, ¶ms, len)) |
3157 | return -EFAULT; | 3592 | return -EFAULT; |
3158 | 3593 | ||
@@ -4019,6 +4454,10 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
4019 | retval = sctp_getsockopt_peer_addr_params(sk, len, optval, | 4454 | retval = sctp_getsockopt_peer_addr_params(sk, len, optval, |
4020 | optlen); | 4455 | optlen); |
4021 | break; | 4456 | break; |
4457 | case SCTP_DELAYED_ACK_TIME: | ||
4458 | retval = sctp_getsockopt_delayed_ack_time(sk, len, optval, | ||
4459 | optlen); | ||
4460 | break; | ||
4022 | case SCTP_INITMSG: | 4461 | case SCTP_INITMSG: |
4023 | retval = sctp_getsockopt_initmsg(sk, len, optval, optlen); | 4462 | retval = sctp_getsockopt_initmsg(sk, len, optval, optlen); |
4024 | break; | 4463 | break; |
@@ -4426,7 +4865,7 @@ cleanup: | |||
4426 | * tcp_poll(). Note that, based on these implementations, we don't | 4865 | * tcp_poll(). Note that, based on these implementations, we don't |
4427 | * lock the socket in this function, even though it seems that, | 4866 | * lock the socket in this function, even though it seems that, |
4428 | * ideally, locking or some other mechanisms can be used to ensure | 4867 | * ideally, locking or some other mechanisms can be used to ensure |
4429 | * the integrity of the counters (sndbuf and wmem_queued) used | 4868 | * the integrity of the counters (sndbuf and wmem_alloc) used |
4430 | * in this place. We assume that we don't need locks either until proven | 4869 | * in this place. We assume that we don't need locks either until proven |
4431 | * otherwise. | 4870 | * otherwise. |
4432 | * | 4871 | * |
@@ -4833,10 +5272,6 @@ static void sctp_wfree(struct sk_buff *skb) | |||
4833 | sizeof(struct sk_buff) + | 5272 | sizeof(struct sk_buff) + |
4834 | sizeof(struct sctp_chunk); | 5273 | sizeof(struct sctp_chunk); |
4835 | 5274 | ||
4836 | sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk) + | ||
4837 | sizeof(struct sk_buff) + | ||
4838 | sizeof(struct sctp_chunk); | ||
4839 | |||
4840 | atomic_sub(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc); | 5275 | atomic_sub(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc); |
4841 | 5276 | ||
4842 | sock_wfree(skb); | 5277 | sock_wfree(skb); |
@@ -4920,7 +5355,7 @@ void sctp_write_space(struct sock *sk) | |||
4920 | 5355 | ||
4921 | /* Is there any sndbuf space available on the socket? | 5356 | /* Is there any sndbuf space available on the socket? |
4922 | * | 5357 | * |
4923 | * Note that wmem_queued is the sum of the send buffers on all of the | 5358 | * Note that sk_wmem_alloc is the sum of the send buffers on all of the |
4924 | * associations on the same socket. For a UDP-style socket with | 5359 | * associations on the same socket. For a UDP-style socket with |
4925 | * multiple associations, it is possible for it to be "unwriteable" | 5360 | * multiple associations, it is possible for it to be "unwriteable" |
4926 | * prematurely. I assume that this is acceptable because | 5361 | * prematurely. I assume that this is acceptable because |
@@ -4933,7 +5368,7 @@ static int sctp_writeable(struct sock *sk) | |||
4933 | { | 5368 | { |
4934 | int amt = 0; | 5369 | int amt = 0; |
4935 | 5370 | ||
4936 | amt = sk->sk_sndbuf - sk->sk_wmem_queued; | 5371 | amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); |
4937 | if (amt < 0) | 5372 | if (amt < 0) |
4938 | amt = 0; | 5373 | amt = 0; |
4939 | return amt; | 5374 | return amt; |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 268ddaf2dc0f..68d73e2dd155 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -86,10 +86,13 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
86 | peer->init_sent_count = 0; | 86 | peer->init_sent_count = 0; |
87 | 87 | ||
88 | peer->state = SCTP_ACTIVE; | 88 | peer->state = SCTP_ACTIVE; |
89 | peer->hb_allowed = 0; | 89 | peer->param_flags = SPP_HB_DISABLE | |
90 | SPP_PMTUD_ENABLE | | ||
91 | SPP_SACKDELAY_ENABLE; | ||
92 | peer->hbinterval = 0; | ||
90 | 93 | ||
91 | /* Initialize the default path max_retrans. */ | 94 | /* Initialize the default path max_retrans. */ |
92 | peer->max_retrans = sctp_max_retrans_path; | 95 | peer->pathmaxrxt = sctp_max_retrans_path; |
93 | peer->error_count = 0; | 96 | peer->error_count = 0; |
94 | 97 | ||
95 | INIT_LIST_HEAD(&peer->transmitted); | 98 | INIT_LIST_HEAD(&peer->transmitted); |
@@ -229,10 +232,10 @@ void sctp_transport_pmtu(struct sctp_transport *transport) | |||
229 | dst = transport->af_specific->get_dst(NULL, &transport->ipaddr, NULL); | 232 | dst = transport->af_specific->get_dst(NULL, &transport->ipaddr, NULL); |
230 | 233 | ||
231 | if (dst) { | 234 | if (dst) { |
232 | transport->pmtu = dst_mtu(dst); | 235 | transport->pathmtu = dst_mtu(dst); |
233 | dst_release(dst); | 236 | dst_release(dst); |
234 | } else | 237 | } else |
235 | transport->pmtu = SCTP_DEFAULT_MAXSEGMENT; | 238 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; |
236 | } | 239 | } |
237 | 240 | ||
238 | /* Caches the dst entry and source address for a transport's destination | 241 | /* Caches the dst entry and source address for a transport's destination |
@@ -254,8 +257,11 @@ void sctp_transport_route(struct sctp_transport *transport, | |||
254 | af->get_saddr(asoc, dst, daddr, &transport->saddr); | 257 | af->get_saddr(asoc, dst, daddr, &transport->saddr); |
255 | 258 | ||
256 | transport->dst = dst; | 259 | transport->dst = dst; |
260 | if ((transport->param_flags & SPP_PMTUD_DISABLE) && transport->pathmtu) { | ||
261 | return; | ||
262 | } | ||
257 | if (dst) { | 263 | if (dst) { |
258 | transport->pmtu = dst_mtu(dst); | 264 | transport->pathmtu = dst_mtu(dst); |
259 | 265 | ||
260 | /* Initialize sk->sk_rcv_saddr, if the transport is the | 266 | /* Initialize sk->sk_rcv_saddr, if the transport is the |
261 | * association's active path for getsockname(). | 267 | * association's active path for getsockname(). |
@@ -264,7 +270,7 @@ void sctp_transport_route(struct sctp_transport *transport, | |||
264 | opt->pf->af->to_sk_saddr(&transport->saddr, | 270 | opt->pf->af->to_sk_saddr(&transport->saddr, |
265 | asoc->base.sk); | 271 | asoc->base.sk); |
266 | } else | 272 | } else |
267 | transport->pmtu = SCTP_DEFAULT_MAXSEGMENT; | 273 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; |
268 | } | 274 | } |
269 | 275 | ||
270 | /* Hold a reference to a transport. */ | 276 | /* Hold a reference to a transport. */ |
@@ -369,7 +375,7 @@ void sctp_transport_raise_cwnd(struct sctp_transport *transport, | |||
369 | 375 | ||
370 | ssthresh = transport->ssthresh; | 376 | ssthresh = transport->ssthresh; |
371 | pba = transport->partial_bytes_acked; | 377 | pba = transport->partial_bytes_acked; |
372 | pmtu = transport->asoc->pmtu; | 378 | pmtu = transport->asoc->pathmtu; |
373 | 379 | ||
374 | if (cwnd <= ssthresh) { | 380 | if (cwnd <= ssthresh) { |
375 | /* RFC 2960 7.2.1, sctpimpguide-05 2.14.2 When cwnd is less | 381 | /* RFC 2960 7.2.1, sctpimpguide-05 2.14.2 When cwnd is less |
@@ -441,8 +447,8 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
441 | * partial_bytes_acked = 0 | 447 | * partial_bytes_acked = 0 |
442 | */ | 448 | */ |
443 | transport->ssthresh = max(transport->cwnd/2, | 449 | transport->ssthresh = max(transport->cwnd/2, |
444 | 4*transport->asoc->pmtu); | 450 | 4*transport->asoc->pathmtu); |
445 | transport->cwnd = transport->asoc->pmtu; | 451 | transport->cwnd = transport->asoc->pathmtu; |
446 | break; | 452 | break; |
447 | 453 | ||
448 | case SCTP_LOWER_CWND_FAST_RTX: | 454 | case SCTP_LOWER_CWND_FAST_RTX: |
@@ -459,7 +465,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
459 | * partial_bytes_acked = 0 | 465 | * partial_bytes_acked = 0 |
460 | */ | 466 | */ |
461 | transport->ssthresh = max(transport->cwnd/2, | 467 | transport->ssthresh = max(transport->cwnd/2, |
462 | 4*transport->asoc->pmtu); | 468 | 4*transport->asoc->pathmtu); |
463 | transport->cwnd = transport->ssthresh; | 469 | transport->cwnd = transport->ssthresh; |
464 | break; | 470 | break; |
465 | 471 | ||
@@ -479,7 +485,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
479 | if ((jiffies - transport->last_time_ecne_reduced) > | 485 | if ((jiffies - transport->last_time_ecne_reduced) > |
480 | transport->rtt) { | 486 | transport->rtt) { |
481 | transport->ssthresh = max(transport->cwnd/2, | 487 | transport->ssthresh = max(transport->cwnd/2, |
482 | 4*transport->asoc->pmtu); | 488 | 4*transport->asoc->pathmtu); |
483 | transport->cwnd = transport->ssthresh; | 489 | transport->cwnd = transport->ssthresh; |
484 | transport->last_time_ecne_reduced = jiffies; | 490 | transport->last_time_ecne_reduced = jiffies; |
485 | } | 491 | } |
@@ -496,7 +502,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
496 | */ | 502 | */ |
497 | if ((jiffies - transport->last_time_used) > transport->rto) | 503 | if ((jiffies - transport->last_time_used) > transport->rto) |
498 | transport->cwnd = max(transport->cwnd/2, | 504 | transport->cwnd = max(transport->cwnd/2, |
499 | 4*transport->asoc->pmtu); | 505 | 4*transport->asoc->pathmtu); |
500 | break; | 506 | break; |
501 | }; | 507 | }; |
502 | 508 | ||
@@ -511,7 +517,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, | |||
511 | unsigned long sctp_transport_timeout(struct sctp_transport *t) | 517 | unsigned long sctp_transport_timeout(struct sctp_transport *t) |
512 | { | 518 | { |
513 | unsigned long timeout; | 519 | unsigned long timeout; |
514 | timeout = t->hb_interval + t->rto + sctp_jitter(t->rto); | 520 | timeout = t->hbinterval + t->rto + sctp_jitter(t->rto); |
515 | timeout += jiffies; | 521 | timeout += jiffies; |
516 | return timeout; | 522 | return timeout; |
517 | } | 523 | } |
diff --git a/net/socket.c b/net/socket.c index 3145103cdf54..06fa217f58a9 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -640,154 +640,150 @@ static void sock_aio_dtor(struct kiocb *iocb) | |||
640 | kfree(iocb->private); | 640 | kfree(iocb->private); |
641 | } | 641 | } |
642 | 642 | ||
643 | /* | 643 | static ssize_t sock_sendpage(struct file *file, struct page *page, |
644 | * Read data from a socket. ubuf is a user mode pointer. We make sure the user | 644 | int offset, size_t size, loff_t *ppos, int more) |
645 | * area ubuf...ubuf+size-1 is writable before asking the protocol. | ||
646 | */ | ||
647 | |||
648 | static ssize_t sock_aio_read(struct kiocb *iocb, char __user *ubuf, | ||
649 | size_t size, loff_t pos) | ||
650 | { | 645 | { |
651 | struct sock_iocb *x, siocb; | ||
652 | struct socket *sock; | 646 | struct socket *sock; |
653 | int flags; | 647 | int flags; |
654 | 648 | ||
655 | if (pos != 0) | 649 | sock = file->private_data; |
656 | return -ESPIPE; | ||
657 | if (size==0) /* Match SYS5 behaviour */ | ||
658 | return 0; | ||
659 | 650 | ||
660 | if (is_sync_kiocb(iocb)) | 651 | flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT; |
661 | x = &siocb; | 652 | if (more) |
662 | else { | 653 | flags |= MSG_MORE; |
663 | x = kmalloc(sizeof(struct sock_iocb), GFP_KERNEL); | 654 | |
664 | if (!x) | 655 | return sock->ops->sendpage(sock, page, offset, size, flags); |
665 | return -ENOMEM; | 656 | } |
657 | |||
658 | static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb, | ||
659 | char __user *ubuf, size_t size, struct sock_iocb *siocb) | ||
660 | { | ||
661 | if (!is_sync_kiocb(iocb)) { | ||
662 | siocb = kmalloc(sizeof(*siocb), GFP_KERNEL); | ||
663 | if (!siocb) | ||
664 | return NULL; | ||
666 | iocb->ki_dtor = sock_aio_dtor; | 665 | iocb->ki_dtor = sock_aio_dtor; |
667 | } | 666 | } |
668 | iocb->private = x; | ||
669 | x->kiocb = iocb; | ||
670 | sock = iocb->ki_filp->private_data; | ||
671 | 667 | ||
672 | x->async_msg.msg_name = NULL; | 668 | siocb->kiocb = iocb; |
673 | x->async_msg.msg_namelen = 0; | 669 | siocb->async_iov.iov_base = ubuf; |
674 | x->async_msg.msg_iov = &x->async_iov; | 670 | siocb->async_iov.iov_len = size; |
675 | x->async_msg.msg_iovlen = 1; | ||
676 | x->async_msg.msg_control = NULL; | ||
677 | x->async_msg.msg_controllen = 0; | ||
678 | x->async_iov.iov_base = ubuf; | ||
679 | x->async_iov.iov_len = size; | ||
680 | flags = !(iocb->ki_filp->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT; | ||
681 | 671 | ||
682 | return __sock_recvmsg(iocb, sock, &x->async_msg, size, flags); | 672 | iocb->private = siocb; |
673 | return siocb; | ||
683 | } | 674 | } |
684 | 675 | ||
676 | static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb, | ||
677 | struct file *file, struct iovec *iov, unsigned long nr_segs) | ||
678 | { | ||
679 | struct socket *sock = file->private_data; | ||
680 | size_t size = 0; | ||
681 | int i; | ||
685 | 682 | ||
686 | /* | 683 | for (i = 0 ; i < nr_segs ; i++) |
687 | * Write data to a socket. We verify that the user area ubuf..ubuf+size-1 | 684 | size += iov[i].iov_len; |
688 | * is readable by the user process. | ||
689 | */ | ||
690 | 685 | ||
691 | static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf, | 686 | msg->msg_name = NULL; |
692 | size_t size, loff_t pos) | 687 | msg->msg_namelen = 0; |
688 | msg->msg_control = NULL; | ||
689 | msg->msg_controllen = 0; | ||
690 | msg->msg_iov = (struct iovec *) iov; | ||
691 | msg->msg_iovlen = nr_segs; | ||
692 | msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; | ||
693 | |||
694 | return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags); | ||
695 | } | ||
696 | |||
697 | static ssize_t sock_readv(struct file *file, const struct iovec *iov, | ||
698 | unsigned long nr_segs, loff_t *ppos) | ||
693 | { | 699 | { |
694 | struct sock_iocb *x, siocb; | 700 | struct kiocb iocb; |
695 | struct socket *sock; | 701 | struct sock_iocb siocb; |
696 | 702 | struct msghdr msg; | |
703 | int ret; | ||
704 | |||
705 | init_sync_kiocb(&iocb, NULL); | ||
706 | iocb.private = &siocb; | ||
707 | |||
708 | ret = do_sock_read(&msg, &iocb, file, (struct iovec *)iov, nr_segs); | ||
709 | if (-EIOCBQUEUED == ret) | ||
710 | ret = wait_on_sync_kiocb(&iocb); | ||
711 | return ret; | ||
712 | } | ||
713 | |||
714 | static ssize_t sock_aio_read(struct kiocb *iocb, char __user *ubuf, | ||
715 | size_t count, loff_t pos) | ||
716 | { | ||
717 | struct sock_iocb siocb, *x; | ||
718 | |||
697 | if (pos != 0) | 719 | if (pos != 0) |
698 | return -ESPIPE; | 720 | return -ESPIPE; |
699 | if(size==0) /* Match SYS5 behaviour */ | 721 | if (count == 0) /* Match SYS5 behaviour */ |
700 | return 0; | 722 | return 0; |
701 | 723 | ||
702 | if (is_sync_kiocb(iocb)) | 724 | x = alloc_sock_iocb(iocb, ubuf, count, &siocb); |
703 | x = &siocb; | 725 | if (!x) |
704 | else { | 726 | return -ENOMEM; |
705 | x = kmalloc(sizeof(struct sock_iocb), GFP_KERNEL); | 727 | return do_sock_read(&x->async_msg, iocb, iocb->ki_filp, |
706 | if (!x) | 728 | &x->async_iov, 1); |
707 | return -ENOMEM; | ||
708 | iocb->ki_dtor = sock_aio_dtor; | ||
709 | } | ||
710 | iocb->private = x; | ||
711 | x->kiocb = iocb; | ||
712 | sock = iocb->ki_filp->private_data; | ||
713 | |||
714 | x->async_msg.msg_name = NULL; | ||
715 | x->async_msg.msg_namelen = 0; | ||
716 | x->async_msg.msg_iov = &x->async_iov; | ||
717 | x->async_msg.msg_iovlen = 1; | ||
718 | x->async_msg.msg_control = NULL; | ||
719 | x->async_msg.msg_controllen = 0; | ||
720 | x->async_msg.msg_flags = !(iocb->ki_filp->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT; | ||
721 | if (sock->type == SOCK_SEQPACKET) | ||
722 | x->async_msg.msg_flags |= MSG_EOR; | ||
723 | x->async_iov.iov_base = (void __user *)ubuf; | ||
724 | x->async_iov.iov_len = size; | ||
725 | |||
726 | return __sock_sendmsg(iocb, sock, &x->async_msg, size); | ||
727 | } | 729 | } |
728 | 730 | ||
729 | static ssize_t sock_sendpage(struct file *file, struct page *page, | 731 | static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb, |
730 | int offset, size_t size, loff_t *ppos, int more) | 732 | struct file *file, struct iovec *iov, unsigned long nr_segs) |
731 | { | 733 | { |
732 | struct socket *sock; | 734 | struct socket *sock = file->private_data; |
733 | int flags; | 735 | size_t size = 0; |
736 | int i; | ||
734 | 737 | ||
735 | sock = file->private_data; | 738 | for (i = 0 ; i < nr_segs ; i++) |
739 | size += iov[i].iov_len; | ||
736 | 740 | ||
737 | flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT; | 741 | msg->msg_name = NULL; |
738 | if (more) | 742 | msg->msg_namelen = 0; |
739 | flags |= MSG_MORE; | 743 | msg->msg_control = NULL; |
744 | msg->msg_controllen = 0; | ||
745 | msg->msg_iov = (struct iovec *) iov; | ||
746 | msg->msg_iovlen = nr_segs; | ||
747 | msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; | ||
748 | if (sock->type == SOCK_SEQPACKET) | ||
749 | msg->msg_flags |= MSG_EOR; | ||
740 | 750 | ||
741 | return sock->ops->sendpage(sock, page, offset, size, flags); | 751 | return __sock_sendmsg(iocb, sock, msg, size); |
742 | } | 752 | } |
743 | 753 | ||
744 | static int sock_readv_writev(int type, | 754 | static ssize_t sock_writev(struct file *file, const struct iovec *iov, |
745 | struct file * file, const struct iovec * iov, | 755 | unsigned long nr_segs, loff_t *ppos) |
746 | long count, size_t size) | ||
747 | { | 756 | { |
748 | struct msghdr msg; | 757 | struct msghdr msg; |
749 | struct socket *sock; | 758 | struct kiocb iocb; |
759 | struct sock_iocb siocb; | ||
760 | int ret; | ||
750 | 761 | ||
751 | sock = file->private_data; | 762 | init_sync_kiocb(&iocb, NULL); |
763 | iocb.private = &siocb; | ||
752 | 764 | ||
753 | msg.msg_name = NULL; | 765 | ret = do_sock_write(&msg, &iocb, file, (struct iovec *)iov, nr_segs); |
754 | msg.msg_namelen = 0; | 766 | if (-EIOCBQUEUED == ret) |
755 | msg.msg_control = NULL; | 767 | ret = wait_on_sync_kiocb(&iocb); |
756 | msg.msg_controllen = 0; | 768 | return ret; |
757 | msg.msg_iov = (struct iovec *) iov; | 769 | } |
758 | msg.msg_iovlen = count; | ||
759 | msg.msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; | ||
760 | 770 | ||
761 | /* read() does a VERIFY_WRITE */ | 771 | static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf, |
762 | if (type == VERIFY_WRITE) | 772 | size_t count, loff_t pos) |
763 | return sock_recvmsg(sock, &msg, size, msg.msg_flags); | 773 | { |
774 | struct sock_iocb siocb, *x; | ||
764 | 775 | ||
765 | if (sock->type == SOCK_SEQPACKET) | 776 | if (pos != 0) |
766 | msg.msg_flags |= MSG_EOR; | 777 | return -ESPIPE; |
778 | if (count == 0) /* Match SYS5 behaviour */ | ||
779 | return 0; | ||
767 | 780 | ||
768 | return sock_sendmsg(sock, &msg, size); | 781 | x = alloc_sock_iocb(iocb, (void __user *)ubuf, count, &siocb); |
769 | } | 782 | if (!x) |
783 | return -ENOMEM; | ||
770 | 784 | ||
771 | static ssize_t sock_readv(struct file *file, const struct iovec *vector, | 785 | return do_sock_write(&x->async_msg, iocb, iocb->ki_filp, |
772 | unsigned long count, loff_t *ppos) | 786 | &x->async_iov, 1); |
773 | { | ||
774 | size_t tot_len = 0; | ||
775 | int i; | ||
776 | for (i = 0 ; i < count ; i++) | ||
777 | tot_len += vector[i].iov_len; | ||
778 | return sock_readv_writev(VERIFY_WRITE, | ||
779 | file, vector, count, tot_len); | ||
780 | } | ||
781 | |||
782 | static ssize_t sock_writev(struct file *file, const struct iovec *vector, | ||
783 | unsigned long count, loff_t *ppos) | ||
784 | { | ||
785 | size_t tot_len = 0; | ||
786 | int i; | ||
787 | for (i = 0 ; i < count ; i++) | ||
788 | tot_len += vector[i].iov_len; | ||
789 | return sock_readv_writev(VERIFY_READ, | ||
790 | file, vector, count, tot_len); | ||
791 | } | 787 | } |
792 | 788 | ||
793 | 789 | ||
@@ -904,6 +900,13 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
904 | break; | 900 | break; |
905 | default: | 901 | default: |
906 | err = sock->ops->ioctl(sock, cmd, arg); | 902 | err = sock->ops->ioctl(sock, cmd, arg); |
903 | |||
904 | /* | ||
905 | * If this ioctl is unknown try to hand it down | ||
906 | * to the NIC driver. | ||
907 | */ | ||
908 | if (err == -ENOIOCTLCMD) | ||
909 | err = dev_ioctl(cmd, argp); | ||
907 | break; | 910 | break; |
908 | } | 911 | } |
909 | return err; | 912 | return err; |
@@ -2036,7 +2039,7 @@ int sock_unregister(int family) | |||
2036 | return 0; | 2039 | return 0; |
2037 | } | 2040 | } |
2038 | 2041 | ||
2039 | void __init sock_init(void) | 2042 | static int __init sock_init(void) |
2040 | { | 2043 | { |
2041 | /* | 2044 | /* |
2042 | * Initialize sock SLAB cache. | 2045 | * Initialize sock SLAB cache. |
@@ -2044,12 +2047,10 @@ void __init sock_init(void) | |||
2044 | 2047 | ||
2045 | sk_init(); | 2048 | sk_init(); |
2046 | 2049 | ||
2047 | #ifdef SLAB_SKB | ||
2048 | /* | 2050 | /* |
2049 | * Initialize skbuff SLAB cache | 2051 | * Initialize skbuff SLAB cache |
2050 | */ | 2052 | */ |
2051 | skb_init(); | 2053 | skb_init(); |
2052 | #endif | ||
2053 | 2054 | ||
2054 | /* | 2055 | /* |
2055 | * Initialize the protocols module. | 2056 | * Initialize the protocols module. |
@@ -2058,15 +2059,19 @@ void __init sock_init(void) | |||
2058 | init_inodecache(); | 2059 | init_inodecache(); |
2059 | register_filesystem(&sock_fs_type); | 2060 | register_filesystem(&sock_fs_type); |
2060 | sock_mnt = kern_mount(&sock_fs_type); | 2061 | sock_mnt = kern_mount(&sock_fs_type); |
2061 | /* The real protocol initialization is performed when | 2062 | |
2062 | * do_initcalls is run. | 2063 | /* The real protocol initialization is performed in later initcalls. |
2063 | */ | 2064 | */ |
2064 | 2065 | ||
2065 | #ifdef CONFIG_NETFILTER | 2066 | #ifdef CONFIG_NETFILTER |
2066 | netfilter_init(); | 2067 | netfilter_init(); |
2067 | #endif | 2068 | #endif |
2069 | |||
2070 | return 0; | ||
2068 | } | 2071 | } |
2069 | 2072 | ||
2073 | core_initcall(sock_init); /* early initcall */ | ||
2074 | |||
2070 | #ifdef CONFIG_PROC_FS | 2075 | #ifdef CONFIG_PROC_FS |
2071 | void socket_seq_show(struct seq_file *seq) | 2076 | void socket_seq_show(struct seq_file *seq) |
2072 | { | 2077 | { |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index f44f46f1d8e0..8d782282ec19 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -638,7 +638,7 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg *msg) | |||
638 | gss_msg); | 638 | gss_msg); |
639 | atomic_inc(&gss_msg->count); | 639 | atomic_inc(&gss_msg->count); |
640 | gss_unhash_msg(gss_msg); | 640 | gss_unhash_msg(gss_msg); |
641 | if (msg->errno == -ETIMEDOUT || msg->errno == -EPIPE) { | 641 | if (msg->errno == -ETIMEDOUT) { |
642 | unsigned long now = jiffies; | 642 | unsigned long now = jiffies; |
643 | if (time_after(now, ratelimit)) { | 643 | if (time_after(now, ratelimit)) { |
644 | printk(KERN_WARNING "RPC: AUTH_GSS upcall timed out.\n" | 644 | printk(KERN_WARNING "RPC: AUTH_GSS upcall timed out.\n" |
@@ -786,7 +786,9 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags) | |||
786 | cred->gc_flags = 0; | 786 | cred->gc_flags = 0; |
787 | cred->gc_base.cr_ops = &gss_credops; | 787 | cred->gc_base.cr_ops = &gss_credops; |
788 | cred->gc_service = gss_auth->service; | 788 | cred->gc_service = gss_auth->service; |
789 | err = gss_create_upcall(gss_auth, cred); | 789 | do { |
790 | err = gss_create_upcall(gss_auth, cred); | ||
791 | } while (err == -EAGAIN); | ||
790 | if (err < 0) | 792 | if (err < 0) |
791 | goto out_err; | 793 | goto out_err; |
792 | 794 | ||
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index c76ea221798c..16a2458f38f7 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -174,7 +174,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp) | |||
174 | goto out; | 174 | goto out; |
175 | msg = (struct rpc_pipe_msg *)filp->private_data; | 175 | msg = (struct rpc_pipe_msg *)filp->private_data; |
176 | if (msg != NULL) { | 176 | if (msg != NULL) { |
177 | msg->errno = -EPIPE; | 177 | msg->errno = -EAGAIN; |
178 | list_del_init(&msg->list); | 178 | list_del_init(&msg->list); |
179 | rpci->ops->destroy_msg(msg); | 179 | rpci->ops->destroy_msg(msg); |
180 | } | 180 | } |
@@ -183,7 +183,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp) | |||
183 | if (filp->f_mode & FMODE_READ) | 183 | if (filp->f_mode & FMODE_READ) |
184 | rpci->nreaders --; | 184 | rpci->nreaders --; |
185 | if (!rpci->nreaders) | 185 | if (!rpci->nreaders) |
186 | __rpc_purge_upcall(inode, -EPIPE); | 186 | __rpc_purge_upcall(inode, -EAGAIN); |
187 | if (rpci->ops->release_pipe) | 187 | if (rpci->ops->release_pipe) |
188 | rpci->ops->release_pipe(inode); | 188 | rpci->ops->release_pipe(inode); |
189 | out: | 189 | out: |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index c6a51911e71e..d68eba481291 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -758,7 +758,7 @@ svc_tcp_accept(struct svc_sock *svsk) | |||
758 | struct svc_serv *serv = svsk->sk_server; | 758 | struct svc_serv *serv = svsk->sk_server; |
759 | struct socket *sock = svsk->sk_sock; | 759 | struct socket *sock = svsk->sk_sock; |
760 | struct socket *newsock; | 760 | struct socket *newsock; |
761 | struct proto_ops *ops; | 761 | const struct proto_ops *ops; |
762 | struct svc_sock *newsvsk; | 762 | struct svc_sock *newsvsk; |
763 | int err, slen; | 763 | int err, slen; |
764 | 764 | ||
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 0a51fd46a848..77e8800d4127 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -990,6 +990,7 @@ static void xs_udp_connect_worker(void *args) | |||
990 | sk->sk_data_ready = xs_udp_data_ready; | 990 | sk->sk_data_ready = xs_udp_data_ready; |
991 | sk->sk_write_space = xs_udp_write_space; | 991 | sk->sk_write_space = xs_udp_write_space; |
992 | sk->sk_no_check = UDP_CSUM_NORCV; | 992 | sk->sk_no_check = UDP_CSUM_NORCV; |
993 | sk->sk_allocation = GFP_ATOMIC; | ||
993 | 994 | ||
994 | xprt_set_connected(xprt); | 995 | xprt_set_connected(xprt); |
995 | 996 | ||
@@ -1074,6 +1075,7 @@ static void xs_tcp_connect_worker(void *args) | |||
1074 | sk->sk_data_ready = xs_tcp_data_ready; | 1075 | sk->sk_data_ready = xs_tcp_data_ready; |
1075 | sk->sk_state_change = xs_tcp_state_change; | 1076 | sk->sk_state_change = xs_tcp_state_change; |
1076 | sk->sk_write_space = xs_tcp_write_space; | 1077 | sk->sk_write_space = xs_tcp_write_space; |
1078 | sk->sk_allocation = GFP_ATOMIC; | ||
1077 | 1079 | ||
1078 | /* socket options */ | 1080 | /* socket options */ |
1079 | sk->sk_userlocks |= SOCK_BINDPORT_LOCK; | 1081 | sk->sk_userlocks |= SOCK_BINDPORT_LOCK; |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index acc73ba8bade..5f6ae79b8b16 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -121,7 +121,7 @@ | |||
121 | int sysctl_unix_max_dgram_qlen = 10; | 121 | int sysctl_unix_max_dgram_qlen = 10; |
122 | 122 | ||
123 | struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; | 123 | struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; |
124 | DEFINE_RWLOCK(unix_table_lock); | 124 | DEFINE_SPINLOCK(unix_table_lock); |
125 | static atomic_t unix_nr_socks = ATOMIC_INIT(0); | 125 | static atomic_t unix_nr_socks = ATOMIC_INIT(0); |
126 | 126 | ||
127 | #define unix_sockets_unbound (&unix_socket_table[UNIX_HASH_SIZE]) | 127 | #define unix_sockets_unbound (&unix_socket_table[UNIX_HASH_SIZE]) |
@@ -130,7 +130,7 @@ static atomic_t unix_nr_socks = ATOMIC_INIT(0); | |||
130 | 130 | ||
131 | /* | 131 | /* |
132 | * SMP locking strategy: | 132 | * SMP locking strategy: |
133 | * hash table is protected with rwlock unix_table_lock | 133 | * hash table is protected with spinlock unix_table_lock |
134 | * each socket state is protected by separate rwlock. | 134 | * each socket state is protected by separate rwlock. |
135 | */ | 135 | */ |
136 | 136 | ||
@@ -214,16 +214,16 @@ static void __unix_insert_socket(struct hlist_head *list, struct sock *sk) | |||
214 | 214 | ||
215 | static inline void unix_remove_socket(struct sock *sk) | 215 | static inline void unix_remove_socket(struct sock *sk) |
216 | { | 216 | { |
217 | write_lock(&unix_table_lock); | 217 | spin_lock(&unix_table_lock); |
218 | __unix_remove_socket(sk); | 218 | __unix_remove_socket(sk); |
219 | write_unlock(&unix_table_lock); | 219 | spin_unlock(&unix_table_lock); |
220 | } | 220 | } |
221 | 221 | ||
222 | static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk) | 222 | static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk) |
223 | { | 223 | { |
224 | write_lock(&unix_table_lock); | 224 | spin_lock(&unix_table_lock); |
225 | __unix_insert_socket(list, sk); | 225 | __unix_insert_socket(list, sk); |
226 | write_unlock(&unix_table_lock); | 226 | spin_unlock(&unix_table_lock); |
227 | } | 227 | } |
228 | 228 | ||
229 | static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname, | 229 | static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname, |
@@ -250,11 +250,11 @@ static inline struct sock *unix_find_socket_byname(struct sockaddr_un *sunname, | |||
250 | { | 250 | { |
251 | struct sock *s; | 251 | struct sock *s; |
252 | 252 | ||
253 | read_lock(&unix_table_lock); | 253 | spin_lock(&unix_table_lock); |
254 | s = __unix_find_socket_byname(sunname, len, type, hash); | 254 | s = __unix_find_socket_byname(sunname, len, type, hash); |
255 | if (s) | 255 | if (s) |
256 | sock_hold(s); | 256 | sock_hold(s); |
257 | read_unlock(&unix_table_lock); | 257 | spin_unlock(&unix_table_lock); |
258 | return s; | 258 | return s; |
259 | } | 259 | } |
260 | 260 | ||
@@ -263,7 +263,7 @@ static struct sock *unix_find_socket_byinode(struct inode *i) | |||
263 | struct sock *s; | 263 | struct sock *s; |
264 | struct hlist_node *node; | 264 | struct hlist_node *node; |
265 | 265 | ||
266 | read_lock(&unix_table_lock); | 266 | spin_lock(&unix_table_lock); |
267 | sk_for_each(s, node, | 267 | sk_for_each(s, node, |
268 | &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) { | 268 | &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) { |
269 | struct dentry *dentry = unix_sk(s)->dentry; | 269 | struct dentry *dentry = unix_sk(s)->dentry; |
@@ -276,7 +276,7 @@ static struct sock *unix_find_socket_byinode(struct inode *i) | |||
276 | } | 276 | } |
277 | s = NULL; | 277 | s = NULL; |
278 | found: | 278 | found: |
279 | read_unlock(&unix_table_lock); | 279 | spin_unlock(&unix_table_lock); |
280 | return s; | 280 | return s; |
281 | } | 281 | } |
282 | 282 | ||
@@ -473,7 +473,7 @@ static int unix_dgram_connect(struct socket *, struct sockaddr *, | |||
473 | static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *, | 473 | static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *, |
474 | struct msghdr *, size_t); | 474 | struct msghdr *, size_t); |
475 | 475 | ||
476 | static struct proto_ops unix_stream_ops = { | 476 | static const struct proto_ops unix_stream_ops = { |
477 | .family = PF_UNIX, | 477 | .family = PF_UNIX, |
478 | .owner = THIS_MODULE, | 478 | .owner = THIS_MODULE, |
479 | .release = unix_release, | 479 | .release = unix_release, |
@@ -494,7 +494,7 @@ static struct proto_ops unix_stream_ops = { | |||
494 | .sendpage = sock_no_sendpage, | 494 | .sendpage = sock_no_sendpage, |
495 | }; | 495 | }; |
496 | 496 | ||
497 | static struct proto_ops unix_dgram_ops = { | 497 | static const struct proto_ops unix_dgram_ops = { |
498 | .family = PF_UNIX, | 498 | .family = PF_UNIX, |
499 | .owner = THIS_MODULE, | 499 | .owner = THIS_MODULE, |
500 | .release = unix_release, | 500 | .release = unix_release, |
@@ -515,7 +515,7 @@ static struct proto_ops unix_dgram_ops = { | |||
515 | .sendpage = sock_no_sendpage, | 515 | .sendpage = sock_no_sendpage, |
516 | }; | 516 | }; |
517 | 517 | ||
518 | static struct proto_ops unix_seqpacket_ops = { | 518 | static const struct proto_ops unix_seqpacket_ops = { |
519 | .family = PF_UNIX, | 519 | .family = PF_UNIX, |
520 | .owner = THIS_MODULE, | 520 | .owner = THIS_MODULE, |
521 | .release = unix_release, | 521 | .release = unix_release, |
@@ -564,7 +564,7 @@ static struct sock * unix_create1(struct socket *sock) | |||
564 | u = unix_sk(sk); | 564 | u = unix_sk(sk); |
565 | u->dentry = NULL; | 565 | u->dentry = NULL; |
566 | u->mnt = NULL; | 566 | u->mnt = NULL; |
567 | rwlock_init(&u->lock); | 567 | spin_lock_init(&u->lock); |
568 | atomic_set(&u->inflight, sock ? 0 : -1); | 568 | atomic_set(&u->inflight, sock ? 0 : -1); |
569 | init_MUTEX(&u->readsem); /* single task reading lock */ | 569 | init_MUTEX(&u->readsem); /* single task reading lock */ |
570 | init_waitqueue_head(&u->peer_wait); | 570 | init_waitqueue_head(&u->peer_wait); |
@@ -642,12 +642,12 @@ retry: | |||
642 | addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short); | 642 | addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short); |
643 | addr->hash = unix_hash_fold(csum_partial((void*)addr->name, addr->len, 0)); | 643 | addr->hash = unix_hash_fold(csum_partial((void*)addr->name, addr->len, 0)); |
644 | 644 | ||
645 | write_lock(&unix_table_lock); | 645 | spin_lock(&unix_table_lock); |
646 | ordernum = (ordernum+1)&0xFFFFF; | 646 | ordernum = (ordernum+1)&0xFFFFF; |
647 | 647 | ||
648 | if (__unix_find_socket_byname(addr->name, addr->len, sock->type, | 648 | if (__unix_find_socket_byname(addr->name, addr->len, sock->type, |
649 | addr->hash)) { | 649 | addr->hash)) { |
650 | write_unlock(&unix_table_lock); | 650 | spin_unlock(&unix_table_lock); |
651 | /* Sanity yield. It is unusual case, but yet... */ | 651 | /* Sanity yield. It is unusual case, but yet... */ |
652 | if (!(ordernum&0xFF)) | 652 | if (!(ordernum&0xFF)) |
653 | yield(); | 653 | yield(); |
@@ -658,7 +658,7 @@ retry: | |||
658 | __unix_remove_socket(sk); | 658 | __unix_remove_socket(sk); |
659 | u->addr = addr; | 659 | u->addr = addr; |
660 | __unix_insert_socket(&unix_socket_table[addr->hash], sk); | 660 | __unix_insert_socket(&unix_socket_table[addr->hash], sk); |
661 | write_unlock(&unix_table_lock); | 661 | spin_unlock(&unix_table_lock); |
662 | err = 0; | 662 | err = 0; |
663 | 663 | ||
664 | out: up(&u->readsem); | 664 | out: up(&u->readsem); |
@@ -791,7 +791,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
791 | addr->hash = UNIX_HASH_SIZE; | 791 | addr->hash = UNIX_HASH_SIZE; |
792 | } | 792 | } |
793 | 793 | ||
794 | write_lock(&unix_table_lock); | 794 | spin_lock(&unix_table_lock); |
795 | 795 | ||
796 | if (!sunaddr->sun_path[0]) { | 796 | if (!sunaddr->sun_path[0]) { |
797 | err = -EADDRINUSE; | 797 | err = -EADDRINUSE; |
@@ -814,7 +814,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
814 | __unix_insert_socket(list, sk); | 814 | __unix_insert_socket(list, sk); |
815 | 815 | ||
816 | out_unlock: | 816 | out_unlock: |
817 | write_unlock(&unix_table_lock); | 817 | spin_unlock(&unix_table_lock); |
818 | out_up: | 818 | out_up: |
819 | up(&u->readsem); | 819 | up(&u->readsem); |
820 | out: | 820 | out: |
@@ -1063,10 +1063,12 @@ restart: | |||
1063 | /* Set credentials */ | 1063 | /* Set credentials */ |
1064 | sk->sk_peercred = other->sk_peercred; | 1064 | sk->sk_peercred = other->sk_peercred; |
1065 | 1065 | ||
1066 | sock_hold(newsk); | ||
1067 | unix_peer(sk) = newsk; | ||
1068 | sock->state = SS_CONNECTED; | 1066 | sock->state = SS_CONNECTED; |
1069 | sk->sk_state = TCP_ESTABLISHED; | 1067 | sk->sk_state = TCP_ESTABLISHED; |
1068 | sock_hold(newsk); | ||
1069 | |||
1070 | smp_mb__after_atomic_inc(); /* sock_hold() does an atomic_inc() */ | ||
1071 | unix_peer(sk) = newsk; | ||
1070 | 1072 | ||
1071 | unix_state_wunlock(sk); | 1073 | unix_state_wunlock(sk); |
1072 | 1074 | ||
@@ -1414,7 +1416,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1414 | } else { | 1416 | } else { |
1415 | sunaddr = NULL; | 1417 | sunaddr = NULL; |
1416 | err = -ENOTCONN; | 1418 | err = -ENOTCONN; |
1417 | other = unix_peer_get(sk); | 1419 | other = unix_peer(sk); |
1418 | if (!other) | 1420 | if (!other) |
1419 | goto out_err; | 1421 | goto out_err; |
1420 | } | 1422 | } |
@@ -1476,7 +1478,6 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1476 | other->sk_data_ready(other, size); | 1478 | other->sk_data_ready(other, size); |
1477 | sent+=size; | 1479 | sent+=size; |
1478 | } | 1480 | } |
1479 | sock_put(other); | ||
1480 | 1481 | ||
1481 | scm_destroy(siocb->scm); | 1482 | scm_destroy(siocb->scm); |
1482 | siocb->scm = NULL; | 1483 | siocb->scm = NULL; |
@@ -1491,8 +1492,6 @@ pipe_err: | |||
1491 | send_sig(SIGPIPE,current,0); | 1492 | send_sig(SIGPIPE,current,0); |
1492 | err = -EPIPE; | 1493 | err = -EPIPE; |
1493 | out_err: | 1494 | out_err: |
1494 | if (other) | ||
1495 | sock_put(other); | ||
1496 | scm_destroy(siocb->scm); | 1495 | scm_destroy(siocb->scm); |
1497 | siocb->scm = NULL; | 1496 | siocb->scm = NULL; |
1498 | return sent ? : err; | 1497 | return sent ? : err; |
@@ -1860,7 +1859,7 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1860 | } | 1859 | } |
1861 | 1860 | ||
1862 | default: | 1861 | default: |
1863 | err = dev_ioctl(cmd, (void __user *)arg); | 1862 | err = -ENOIOCTLCMD; |
1864 | break; | 1863 | break; |
1865 | } | 1864 | } |
1866 | return err; | 1865 | return err; |
@@ -1917,7 +1916,7 @@ static struct sock *unix_seq_idx(int *iter, loff_t pos) | |||
1917 | 1916 | ||
1918 | static void *unix_seq_start(struct seq_file *seq, loff_t *pos) | 1917 | static void *unix_seq_start(struct seq_file *seq, loff_t *pos) |
1919 | { | 1918 | { |
1920 | read_lock(&unix_table_lock); | 1919 | spin_lock(&unix_table_lock); |
1921 | return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1); | 1920 | return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1); |
1922 | } | 1921 | } |
1923 | 1922 | ||
@@ -1932,7 +1931,7 @@ static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
1932 | 1931 | ||
1933 | static void unix_seq_stop(struct seq_file *seq, void *v) | 1932 | static void unix_seq_stop(struct seq_file *seq, void *v) |
1934 | { | 1933 | { |
1935 | read_unlock(&unix_table_lock); | 1934 | spin_unlock(&unix_table_lock); |
1936 | } | 1935 | } |
1937 | 1936 | ||
1938 | static int unix_seq_show(struct seq_file *seq, void *v) | 1937 | static int unix_seq_show(struct seq_file *seq, void *v) |
diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 6ffc64e1712d..411802bd4d37 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c | |||
@@ -182,7 +182,7 @@ void unix_gc(void) | |||
182 | if (down_trylock(&unix_gc_sem)) | 182 | if (down_trylock(&unix_gc_sem)) |
183 | return; | 183 | return; |
184 | 184 | ||
185 | read_lock(&unix_table_lock); | 185 | spin_lock(&unix_table_lock); |
186 | 186 | ||
187 | forall_unix_sockets(i, s) | 187 | forall_unix_sockets(i, s) |
188 | { | 188 | { |
@@ -301,7 +301,7 @@ void unix_gc(void) | |||
301 | } | 301 | } |
302 | u->gc_tree = GC_ORPHAN; | 302 | u->gc_tree = GC_ORPHAN; |
303 | } | 303 | } |
304 | read_unlock(&unix_table_lock); | 304 | spin_unlock(&unix_table_lock); |
305 | 305 | ||
306 | /* | 306 | /* |
307 | * Here we are. Hitlist is filled. Die. | 307 | * Here we are. Hitlist is filled. Die. |
diff --git a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c index 59fec59b2132..7a43ae4721ed 100644 --- a/net/wanrouter/af_wanpipe.c +++ b/net/wanrouter/af_wanpipe.c | |||
@@ -181,7 +181,7 @@ struct wanpipe_opt | |||
181 | #endif | 181 | #endif |
182 | 182 | ||
183 | static int sk_count; | 183 | static int sk_count; |
184 | extern struct proto_ops wanpipe_ops; | 184 | extern const struct proto_ops wanpipe_ops; |
185 | static unsigned long find_free_critical; | 185 | static unsigned long find_free_critical; |
186 | 186 | ||
187 | static void wanpipe_unlink_driver(struct sock *sk); | 187 | static void wanpipe_unlink_driver(struct sock *sk); |
@@ -1839,7 +1839,7 @@ static int wanpipe_ioctl(struct socket *sock, unsigned int cmd, unsigned long ar | |||
1839 | #endif | 1839 | #endif |
1840 | 1840 | ||
1841 | default: | 1841 | default: |
1842 | return dev_ioctl(cmd,(void __user *) arg); | 1842 | return -ENOIOCTLCMD; |
1843 | } | 1843 | } |
1844 | /*NOTREACHED*/ | 1844 | /*NOTREACHED*/ |
1845 | } | 1845 | } |
@@ -2546,7 +2546,7 @@ static int wanpipe_connect(struct socket *sock, struct sockaddr *uaddr, int addr | |||
2546 | return 0; | 2546 | return 0; |
2547 | } | 2547 | } |
2548 | 2548 | ||
2549 | struct proto_ops wanpipe_ops = { | 2549 | const struct proto_ops wanpipe_ops = { |
2550 | .family = PF_WANPIPE, | 2550 | .family = PF_WANPIPE, |
2551 | .owner = THIS_MODULE, | 2551 | .owner = THIS_MODULE, |
2552 | .release = wanpipe_release, | 2552 | .release = wanpipe_release, |
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 020d73cc8414..16459c7f54b2 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
@@ -64,7 +64,7 @@ int sysctl_x25_ack_holdback_timeout = X25_DEFAULT_T2; | |||
64 | HLIST_HEAD(x25_list); | 64 | HLIST_HEAD(x25_list); |
65 | DEFINE_RWLOCK(x25_list_lock); | 65 | DEFINE_RWLOCK(x25_list_lock); |
66 | 66 | ||
67 | static struct proto_ops x25_proto_ops; | 67 | static const struct proto_ops x25_proto_ops; |
68 | 68 | ||
69 | static struct x25_address null_x25_address = {" "}; | 69 | static struct x25_address null_x25_address = {" "}; |
70 | 70 | ||
@@ -1378,7 +1378,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1378 | } | 1378 | } |
1379 | 1379 | ||
1380 | default: | 1380 | default: |
1381 | rc = dev_ioctl(cmd, argp); | 1381 | rc = -ENOIOCTLCMD; |
1382 | break; | 1382 | break; |
1383 | } | 1383 | } |
1384 | 1384 | ||
@@ -1391,7 +1391,7 @@ static struct net_proto_family x25_family_ops = { | |||
1391 | .owner = THIS_MODULE, | 1391 | .owner = THIS_MODULE, |
1392 | }; | 1392 | }; |
1393 | 1393 | ||
1394 | static struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { | 1394 | static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { |
1395 | .family = AF_X25, | 1395 | .family = AF_X25, |
1396 | .owner = THIS_MODULE, | 1396 | .owner = THIS_MODULE, |
1397 | .release = x25_release, | 1397 | .release = x25_release, |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 0db9e57013fd..64a447375fdb 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * YOSHIFUJI Hideaki | 10 | * YOSHIFUJI Hideaki |
11 | * Split up af-specific portion | 11 | * Split up af-specific portion |
12 | * Derek Atkins <derek@ihtfp.com> Add the post_input processor | 12 | * Derek Atkins <derek@ihtfp.com> Add the post_input processor |
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <asm/bug.h> | 16 | #include <asm/bug.h> |
@@ -256,6 +256,7 @@ void __xfrm_policy_destroy(struct xfrm_policy *policy) | |||
256 | if (del_timer(&policy->timer)) | 256 | if (del_timer(&policy->timer)) |
257 | BUG(); | 257 | BUG(); |
258 | 258 | ||
259 | security_xfrm_policy_free(policy); | ||
259 | kfree(policy); | 260 | kfree(policy); |
260 | } | 261 | } |
261 | EXPORT_SYMBOL(__xfrm_policy_destroy); | 262 | EXPORT_SYMBOL(__xfrm_policy_destroy); |
@@ -346,10 +347,12 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
346 | struct xfrm_policy *pol, **p; | 347 | struct xfrm_policy *pol, **p; |
347 | struct xfrm_policy *delpol = NULL; | 348 | struct xfrm_policy *delpol = NULL; |
348 | struct xfrm_policy **newpos = NULL; | 349 | struct xfrm_policy **newpos = NULL; |
350 | struct dst_entry *gc_list; | ||
349 | 351 | ||
350 | write_lock_bh(&xfrm_policy_lock); | 352 | write_lock_bh(&xfrm_policy_lock); |
351 | for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) { | 353 | for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) { |
352 | if (!delpol && memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0) { | 354 | if (!delpol && memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0 && |
355 | xfrm_sec_ctx_match(pol->security, policy->security)) { | ||
353 | if (excl) { | 356 | if (excl) { |
354 | write_unlock_bh(&xfrm_policy_lock); | 357 | write_unlock_bh(&xfrm_policy_lock); |
355 | return -EEXIST; | 358 | return -EEXIST; |
@@ -381,21 +384,49 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
381 | xfrm_pol_hold(policy); | 384 | xfrm_pol_hold(policy); |
382 | write_unlock_bh(&xfrm_policy_lock); | 385 | write_unlock_bh(&xfrm_policy_lock); |
383 | 386 | ||
384 | if (delpol) { | 387 | if (delpol) |
385 | xfrm_policy_kill(delpol); | 388 | xfrm_policy_kill(delpol); |
389 | |||
390 | read_lock_bh(&xfrm_policy_lock); | ||
391 | gc_list = NULL; | ||
392 | for (policy = policy->next; policy; policy = policy->next) { | ||
393 | struct dst_entry *dst; | ||
394 | |||
395 | write_lock(&policy->lock); | ||
396 | dst = policy->bundles; | ||
397 | if (dst) { | ||
398 | struct dst_entry *tail = dst; | ||
399 | while (tail->next) | ||
400 | tail = tail->next; | ||
401 | tail->next = gc_list; | ||
402 | gc_list = dst; | ||
403 | |||
404 | policy->bundles = NULL; | ||
405 | } | ||
406 | write_unlock(&policy->lock); | ||
407 | } | ||
408 | read_unlock_bh(&xfrm_policy_lock); | ||
409 | |||
410 | while (gc_list) { | ||
411 | struct dst_entry *dst = gc_list; | ||
412 | |||
413 | gc_list = dst->next; | ||
414 | dst_free(dst); | ||
386 | } | 415 | } |
416 | |||
387 | return 0; | 417 | return 0; |
388 | } | 418 | } |
389 | EXPORT_SYMBOL(xfrm_policy_insert); | 419 | EXPORT_SYMBOL(xfrm_policy_insert); |
390 | 420 | ||
391 | struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel, | 421 | struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel, |
392 | int delete) | 422 | struct xfrm_sec_ctx *ctx, int delete) |
393 | { | 423 | { |
394 | struct xfrm_policy *pol, **p; | 424 | struct xfrm_policy *pol, **p; |
395 | 425 | ||
396 | write_lock_bh(&xfrm_policy_lock); | 426 | write_lock_bh(&xfrm_policy_lock); |
397 | for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) { | 427 | for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) { |
398 | if (memcmp(sel, &pol->selector, sizeof(*sel)) == 0) { | 428 | if ((memcmp(sel, &pol->selector, sizeof(*sel)) == 0) && |
429 | (xfrm_sec_ctx_match(ctx, pol->security))) { | ||
399 | xfrm_pol_hold(pol); | 430 | xfrm_pol_hold(pol); |
400 | if (delete) | 431 | if (delete) |
401 | *p = pol->next; | 432 | *p = pol->next; |
@@ -410,7 +441,7 @@ struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel, | |||
410 | } | 441 | } |
411 | return pol; | 442 | return pol; |
412 | } | 443 | } |
413 | EXPORT_SYMBOL(xfrm_policy_bysel); | 444 | EXPORT_SYMBOL(xfrm_policy_bysel_ctx); |
414 | 445 | ||
415 | struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete) | 446 | struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete) |
416 | { | 447 | { |
@@ -491,7 +522,7 @@ EXPORT_SYMBOL(xfrm_policy_walk); | |||
491 | 522 | ||
492 | /* Find policy to apply to this flow. */ | 523 | /* Find policy to apply to this flow. */ |
493 | 524 | ||
494 | static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir, | 525 | static void xfrm_policy_lookup(struct flowi *fl, u32 sk_sid, u16 family, u8 dir, |
495 | void **objp, atomic_t **obj_refp) | 526 | void **objp, atomic_t **obj_refp) |
496 | { | 527 | { |
497 | struct xfrm_policy *pol; | 528 | struct xfrm_policy *pol; |
@@ -505,9 +536,12 @@ static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir, | |||
505 | continue; | 536 | continue; |
506 | 537 | ||
507 | match = xfrm_selector_match(sel, fl, family); | 538 | match = xfrm_selector_match(sel, fl, family); |
539 | |||
508 | if (match) { | 540 | if (match) { |
509 | xfrm_pol_hold(pol); | 541 | if (!security_xfrm_policy_lookup(pol, sk_sid, dir)) { |
510 | break; | 542 | xfrm_pol_hold(pol); |
543 | break; | ||
544 | } | ||
511 | } | 545 | } |
512 | } | 546 | } |
513 | read_unlock_bh(&xfrm_policy_lock); | 547 | read_unlock_bh(&xfrm_policy_lock); |
@@ -515,15 +549,37 @@ static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir, | |||
515 | *obj_refp = &pol->refcnt; | 549 | *obj_refp = &pol->refcnt; |
516 | } | 550 | } |
517 | 551 | ||
518 | static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl) | 552 | static inline int policy_to_flow_dir(int dir) |
553 | { | ||
554 | if (XFRM_POLICY_IN == FLOW_DIR_IN && | ||
555 | XFRM_POLICY_OUT == FLOW_DIR_OUT && | ||
556 | XFRM_POLICY_FWD == FLOW_DIR_FWD) | ||
557 | return dir; | ||
558 | switch (dir) { | ||
559 | default: | ||
560 | case XFRM_POLICY_IN: | ||
561 | return FLOW_DIR_IN; | ||
562 | case XFRM_POLICY_OUT: | ||
563 | return FLOW_DIR_OUT; | ||
564 | case XFRM_POLICY_FWD: | ||
565 | return FLOW_DIR_FWD; | ||
566 | }; | ||
567 | } | ||
568 | |||
569 | static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl, u32 sk_sid) | ||
519 | { | 570 | { |
520 | struct xfrm_policy *pol; | 571 | struct xfrm_policy *pol; |
521 | 572 | ||
522 | read_lock_bh(&xfrm_policy_lock); | 573 | read_lock_bh(&xfrm_policy_lock); |
523 | if ((pol = sk->sk_policy[dir]) != NULL) { | 574 | if ((pol = sk->sk_policy[dir]) != NULL) { |
524 | int match = xfrm_selector_match(&pol->selector, fl, | 575 | int match = xfrm_selector_match(&pol->selector, fl, |
525 | sk->sk_family); | 576 | sk->sk_family); |
577 | int err = 0; | ||
578 | |||
526 | if (match) | 579 | if (match) |
580 | err = security_xfrm_policy_lookup(pol, sk_sid, policy_to_flow_dir(dir)); | ||
581 | |||
582 | if (match && !err) | ||
527 | xfrm_pol_hold(pol); | 583 | xfrm_pol_hold(pol); |
528 | else | 584 | else |
529 | pol = NULL; | 585 | pol = NULL; |
@@ -596,6 +652,10 @@ static struct xfrm_policy *clone_policy(struct xfrm_policy *old, int dir) | |||
596 | 652 | ||
597 | if (newp) { | 653 | if (newp) { |
598 | newp->selector = old->selector; | 654 | newp->selector = old->selector; |
655 | if (security_xfrm_policy_clone(old, newp)) { | ||
656 | kfree(newp); | ||
657 | return NULL; /* ENOMEM */ | ||
658 | } | ||
599 | newp->lft = old->lft; | 659 | newp->lft = old->lft; |
600 | newp->curlft = old->curlft; | 660 | newp->curlft = old->curlft; |
601 | newp->action = old->action; | 661 | newp->action = old->action; |
@@ -707,22 +767,6 @@ xfrm_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx, | |||
707 | return err; | 767 | return err; |
708 | } | 768 | } |
709 | 769 | ||
710 | static inline int policy_to_flow_dir(int dir) | ||
711 | { | ||
712 | if (XFRM_POLICY_IN == FLOW_DIR_IN && | ||
713 | XFRM_POLICY_OUT == FLOW_DIR_OUT && | ||
714 | XFRM_POLICY_FWD == FLOW_DIR_FWD) | ||
715 | return dir; | ||
716 | switch (dir) { | ||
717 | default: | ||
718 | case XFRM_POLICY_IN: | ||
719 | return FLOW_DIR_IN; | ||
720 | case XFRM_POLICY_OUT: | ||
721 | return FLOW_DIR_OUT; | ||
722 | case XFRM_POLICY_FWD: | ||
723 | return FLOW_DIR_FWD; | ||
724 | }; | ||
725 | } | ||
726 | 770 | ||
727 | static int stale_bundle(struct dst_entry *dst); | 771 | static int stale_bundle(struct dst_entry *dst); |
728 | 772 | ||
@@ -741,19 +785,20 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, | |||
741 | int err; | 785 | int err; |
742 | u32 genid; | 786 | u32 genid; |
743 | u16 family = dst_orig->ops->family; | 787 | u16 family = dst_orig->ops->family; |
788 | u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT); | ||
789 | u32 sk_sid = security_sk_sid(sk, fl, dir); | ||
744 | restart: | 790 | restart: |
745 | genid = atomic_read(&flow_cache_genid); | 791 | genid = atomic_read(&flow_cache_genid); |
746 | policy = NULL; | 792 | policy = NULL; |
747 | if (sk && sk->sk_policy[1]) | 793 | if (sk && sk->sk_policy[1]) |
748 | policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); | 794 | policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl, sk_sid); |
749 | 795 | ||
750 | if (!policy) { | 796 | if (!policy) { |
751 | /* To accelerate a bit... */ | 797 | /* To accelerate a bit... */ |
752 | if ((dst_orig->flags & DST_NOXFRM) || !xfrm_policy_list[XFRM_POLICY_OUT]) | 798 | if ((dst_orig->flags & DST_NOXFRM) || !xfrm_policy_list[XFRM_POLICY_OUT]) |
753 | return 0; | 799 | return 0; |
754 | 800 | ||
755 | policy = flow_cache_lookup(fl, family, | 801 | policy = flow_cache_lookup(fl, sk_sid, family, dir, |
756 | policy_to_flow_dir(XFRM_POLICY_OUT), | ||
757 | xfrm_policy_lookup); | 802 | xfrm_policy_lookup); |
758 | } | 803 | } |
759 | 804 | ||
@@ -934,16 +979,20 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
934 | { | 979 | { |
935 | struct xfrm_policy *pol; | 980 | struct xfrm_policy *pol; |
936 | struct flowi fl; | 981 | struct flowi fl; |
982 | u8 fl_dir = policy_to_flow_dir(dir); | ||
983 | u32 sk_sid; | ||
937 | 984 | ||
938 | if (_decode_session(skb, &fl, family) < 0) | 985 | if (_decode_session(skb, &fl, family) < 0) |
939 | return 0; | 986 | return 0; |
940 | 987 | ||
988 | sk_sid = security_sk_sid(sk, &fl, fl_dir); | ||
989 | |||
941 | /* First, check used SA against their selectors. */ | 990 | /* First, check used SA against their selectors. */ |
942 | if (skb->sp) { | 991 | if (skb->sp) { |
943 | int i; | 992 | int i; |
944 | 993 | ||
945 | for (i=skb->sp->len-1; i>=0; i--) { | 994 | for (i=skb->sp->len-1; i>=0; i--) { |
946 | struct sec_decap_state *xvec = &(skb->sp->x[i]); | 995 | struct sec_decap_state *xvec = &(skb->sp->x[i]); |
947 | if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family)) | 996 | if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family)) |
948 | return 0; | 997 | return 0; |
949 | 998 | ||
@@ -958,11 +1007,10 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
958 | 1007 | ||
959 | pol = NULL; | 1008 | pol = NULL; |
960 | if (sk && sk->sk_policy[dir]) | 1009 | if (sk && sk->sk_policy[dir]) |
961 | pol = xfrm_sk_policy_lookup(sk, dir, &fl); | 1010 | pol = xfrm_sk_policy_lookup(sk, dir, &fl, sk_sid); |
962 | 1011 | ||
963 | if (!pol) | 1012 | if (!pol) |
964 | pol = flow_cache_lookup(&fl, family, | 1013 | pol = flow_cache_lookup(&fl, sk_sid, family, fl_dir, |
965 | policy_to_flow_dir(dir), | ||
966 | xfrm_policy_lookup); | 1014 | xfrm_policy_lookup); |
967 | 1015 | ||
968 | if (!pol) | 1016 | if (!pol) |
@@ -1014,13 +1062,12 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family) | |||
1014 | } | 1062 | } |
1015 | EXPORT_SYMBOL(__xfrm_route_forward); | 1063 | EXPORT_SYMBOL(__xfrm_route_forward); |
1016 | 1064 | ||
1017 | /* Optimize later using cookies and generation ids. */ | ||
1018 | |||
1019 | static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie) | 1065 | static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie) |
1020 | { | 1066 | { |
1021 | if (!stale_bundle(dst)) | 1067 | /* If it is marked obsolete, which is how we even get here, |
1022 | return dst; | 1068 | * then we have purged it from the policy bundle list and we |
1023 | 1069 | * did that for a good reason. | |
1070 | */ | ||
1024 | return NULL; | 1071 | return NULL; |
1025 | } | 1072 | } |
1026 | 1073 | ||
@@ -1104,6 +1151,16 @@ int xfrm_flush_bundles(void) | |||
1104 | return 0; | 1151 | return 0; |
1105 | } | 1152 | } |
1106 | 1153 | ||
1154 | static int always_true(struct dst_entry *dst) | ||
1155 | { | ||
1156 | return 1; | ||
1157 | } | ||
1158 | |||
1159 | void xfrm_flush_all_bundles(void) | ||
1160 | { | ||
1161 | xfrm_prune_bundles(always_true); | ||
1162 | } | ||
1163 | |||
1107 | void xfrm_init_pmtu(struct dst_entry *dst) | 1164 | void xfrm_init_pmtu(struct dst_entry *dst) |
1108 | { | 1165 | { |
1109 | do { | 1166 | do { |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 7cf48aa6c95b..e12d0be5f976 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * Split up af-specific functions | 10 | * Split up af-specific functions |
11 | * Derek Atkins <derek@ihtfp.com> | 11 | * Derek Atkins <derek@ihtfp.com> |
12 | * Add UDP Encapsulation | 12 | * Add UDP Encapsulation |
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/workqueue.h> | 16 | #include <linux/workqueue.h> |
@@ -70,6 +70,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x) | |||
70 | x->type->destructor(x); | 70 | x->type->destructor(x); |
71 | xfrm_put_type(x->type); | 71 | xfrm_put_type(x->type); |
72 | } | 72 | } |
73 | security_xfrm_state_free(x); | ||
73 | kfree(x); | 74 | kfree(x); |
74 | } | 75 | } |
75 | 76 | ||
@@ -343,7 +344,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
343 | selector. | 344 | selector. |
344 | */ | 345 | */ |
345 | if (x->km.state == XFRM_STATE_VALID) { | 346 | if (x->km.state == XFRM_STATE_VALID) { |
346 | if (!xfrm_selector_match(&x->sel, fl, family)) | 347 | if (!xfrm_selector_match(&x->sel, fl, family) || |
348 | !xfrm_sec_ctx_match(pol->security, x->security)) | ||
347 | continue; | 349 | continue; |
348 | if (!best || | 350 | if (!best || |
349 | best->km.dying > x->km.dying || | 351 | best->km.dying > x->km.dying || |
@@ -354,7 +356,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
354 | acquire_in_progress = 1; | 356 | acquire_in_progress = 1; |
355 | } else if (x->km.state == XFRM_STATE_ERROR || | 357 | } else if (x->km.state == XFRM_STATE_ERROR || |
356 | x->km.state == XFRM_STATE_EXPIRED) { | 358 | x->km.state == XFRM_STATE_EXPIRED) { |
357 | if (xfrm_selector_match(&x->sel, fl, family)) | 359 | if (xfrm_selector_match(&x->sel, fl, family) && |
360 | xfrm_sec_ctx_match(pol->security, x->security)) | ||
358 | error = -ESRCH; | 361 | error = -ESRCH; |
359 | } | 362 | } |
360 | } | 363 | } |
@@ -431,6 +434,8 @@ void xfrm_state_insert(struct xfrm_state *x) | |||
431 | spin_lock_bh(&xfrm_state_lock); | 434 | spin_lock_bh(&xfrm_state_lock); |
432 | __xfrm_state_insert(x); | 435 | __xfrm_state_insert(x); |
433 | spin_unlock_bh(&xfrm_state_lock); | 436 | spin_unlock_bh(&xfrm_state_lock); |
437 | |||
438 | xfrm_flush_all_bundles(); | ||
434 | } | 439 | } |
435 | EXPORT_SYMBOL(xfrm_state_insert); | 440 | EXPORT_SYMBOL(xfrm_state_insert); |
436 | 441 | ||
@@ -478,6 +483,9 @@ out: | |||
478 | spin_unlock_bh(&xfrm_state_lock); | 483 | spin_unlock_bh(&xfrm_state_lock); |
479 | xfrm_state_put_afinfo(afinfo); | 484 | xfrm_state_put_afinfo(afinfo); |
480 | 485 | ||
486 | if (!err) | ||
487 | xfrm_flush_all_bundles(); | ||
488 | |||
481 | if (x1) { | 489 | if (x1) { |
482 | xfrm_state_delete(x1); | 490 | xfrm_state_delete(x1); |
483 | xfrm_state_put(x1); | 491 | xfrm_state_put(x1); |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 0cdd9a07e043..92e2b804c606 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Kazunori MIYAZAWA @USAGI | 7 | * Kazunori MIYAZAWA @USAGI |
8 | * Kunihiro Ishiguro <kunihiro@ipinfusion.com> | 8 | * Kunihiro Ishiguro <kunihiro@ipinfusion.com> |
9 | * IPv6 support | 9 | * IPv6 support |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
@@ -88,6 +88,34 @@ static int verify_encap_tmpl(struct rtattr **xfrma) | |||
88 | return 0; | 88 | return 0; |
89 | } | 89 | } |
90 | 90 | ||
91 | |||
92 | static inline int verify_sec_ctx_len(struct rtattr **xfrma) | ||
93 | { | ||
94 | struct rtattr *rt = xfrma[XFRMA_SEC_CTX - 1]; | ||
95 | struct xfrm_user_sec_ctx *uctx; | ||
96 | int len = 0; | ||
97 | |||
98 | if (!rt) | ||
99 | return 0; | ||
100 | |||
101 | if (rt->rta_len < sizeof(*uctx)) | ||
102 | return -EINVAL; | ||
103 | |||
104 | uctx = RTA_DATA(rt); | ||
105 | |||
106 | if (uctx->ctx_len > PAGE_SIZE) | ||
107 | return -EINVAL; | ||
108 | |||
109 | len += sizeof(struct xfrm_user_sec_ctx); | ||
110 | len += uctx->ctx_len; | ||
111 | |||
112 | if (uctx->len != len) | ||
113 | return -EINVAL; | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | |||
91 | static int verify_newsa_info(struct xfrm_usersa_info *p, | 119 | static int verify_newsa_info(struct xfrm_usersa_info *p, |
92 | struct rtattr **xfrma) | 120 | struct rtattr **xfrma) |
93 | { | 121 | { |
@@ -145,6 +173,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p, | |||
145 | goto out; | 173 | goto out; |
146 | if ((err = verify_encap_tmpl(xfrma))) | 174 | if ((err = verify_encap_tmpl(xfrma))) |
147 | goto out; | 175 | goto out; |
176 | if ((err = verify_sec_ctx_len(xfrma))) | ||
177 | goto out; | ||
148 | 178 | ||
149 | err = -EINVAL; | 179 | err = -EINVAL; |
150 | switch (p->mode) { | 180 | switch (p->mode) { |
@@ -209,6 +239,30 @@ static int attach_encap_tmpl(struct xfrm_encap_tmpl **encapp, struct rtattr *u_a | |||
209 | return 0; | 239 | return 0; |
210 | } | 240 | } |
211 | 241 | ||
242 | |||
243 | static inline int xfrm_user_sec_ctx_size(struct xfrm_policy *xp) | ||
244 | { | ||
245 | struct xfrm_sec_ctx *xfrm_ctx = xp->security; | ||
246 | int len = 0; | ||
247 | |||
248 | if (xfrm_ctx) { | ||
249 | len += sizeof(struct xfrm_user_sec_ctx); | ||
250 | len += xfrm_ctx->ctx_len; | ||
251 | } | ||
252 | return len; | ||
253 | } | ||
254 | |||
255 | static int attach_sec_ctx(struct xfrm_state *x, struct rtattr *u_arg) | ||
256 | { | ||
257 | struct xfrm_user_sec_ctx *uctx; | ||
258 | |||
259 | if (!u_arg) | ||
260 | return 0; | ||
261 | |||
262 | uctx = RTA_DATA(u_arg); | ||
263 | return security_xfrm_state_alloc(x, uctx); | ||
264 | } | ||
265 | |||
212 | static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p) | 266 | static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p) |
213 | { | 267 | { |
214 | memcpy(&x->id, &p->id, sizeof(x->id)); | 268 | memcpy(&x->id, &p->id, sizeof(x->id)); |
@@ -253,6 +307,9 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p, | |||
253 | if (err) | 307 | if (err) |
254 | goto error; | 308 | goto error; |
255 | 309 | ||
310 | if ((err = attach_sec_ctx(x, xfrma[XFRMA_SEC_CTX-1]))) | ||
311 | goto error; | ||
312 | |||
256 | x->km.seq = p->seq; | 313 | x->km.seq = p->seq; |
257 | 314 | ||
258 | return x; | 315 | return x; |
@@ -272,11 +329,11 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) | |||
272 | int err; | 329 | int err; |
273 | struct km_event c; | 330 | struct km_event c; |
274 | 331 | ||
275 | err = verify_newsa_info(p, (struct rtattr **) xfrma); | 332 | err = verify_newsa_info(p, (struct rtattr **)xfrma); |
276 | if (err) | 333 | if (err) |
277 | return err; | 334 | return err; |
278 | 335 | ||
279 | x = xfrm_state_construct(p, (struct rtattr **) xfrma, &err); | 336 | x = xfrm_state_construct(p, (struct rtattr **)xfrma, &err); |
280 | if (!x) | 337 | if (!x) |
281 | return err; | 338 | return err; |
282 | 339 | ||
@@ -390,6 +447,19 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr) | |||
390 | if (x->encap) | 447 | if (x->encap) |
391 | RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); | 448 | RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); |
392 | 449 | ||
450 | if (x->security) { | ||
451 | int ctx_size = sizeof(struct xfrm_sec_ctx) + | ||
452 | x->security->ctx_len; | ||
453 | struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size); | ||
454 | struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt); | ||
455 | |||
456 | uctx->exttype = XFRMA_SEC_CTX; | ||
457 | uctx->len = ctx_size; | ||
458 | uctx->ctx_doi = x->security->ctx_doi; | ||
459 | uctx->ctx_alg = x->security->ctx_alg; | ||
460 | uctx->ctx_len = x->security->ctx_len; | ||
461 | memcpy(uctx + 1, x->security->ctx_str, x->security->ctx_len); | ||
462 | } | ||
393 | nlh->nlmsg_len = skb->tail - b; | 463 | nlh->nlmsg_len = skb->tail - b; |
394 | out: | 464 | out: |
395 | sp->this_idx++; | 465 | sp->this_idx++; |
@@ -603,6 +673,18 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) | |||
603 | return verify_policy_dir(p->dir); | 673 | return verify_policy_dir(p->dir); |
604 | } | 674 | } |
605 | 675 | ||
676 | static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct rtattr **xfrma) | ||
677 | { | ||
678 | struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1]; | ||
679 | struct xfrm_user_sec_ctx *uctx; | ||
680 | |||
681 | if (!rt) | ||
682 | return 0; | ||
683 | |||
684 | uctx = RTA_DATA(rt); | ||
685 | return security_xfrm_policy_alloc(pol, uctx); | ||
686 | } | ||
687 | |||
606 | static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, | 688 | static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, |
607 | int nr) | 689 | int nr) |
608 | { | 690 | { |
@@ -681,7 +763,10 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p, | |||
681 | } | 763 | } |
682 | 764 | ||
683 | copy_from_user_policy(xp, p); | 765 | copy_from_user_policy(xp, p); |
684 | err = copy_from_user_tmpl(xp, xfrma); | 766 | |
767 | if (!(err = copy_from_user_tmpl(xp, xfrma))) | ||
768 | err = copy_from_user_sec_ctx(xp, xfrma); | ||
769 | |||
685 | if (err) { | 770 | if (err) { |
686 | *errp = err; | 771 | *errp = err; |
687 | kfree(xp); | 772 | kfree(xp); |
@@ -702,8 +787,11 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
702 | err = verify_newpolicy_info(p); | 787 | err = verify_newpolicy_info(p); |
703 | if (err) | 788 | if (err) |
704 | return err; | 789 | return err; |
790 | err = verify_sec_ctx_len((struct rtattr **)xfrma); | ||
791 | if (err) | ||
792 | return err; | ||
705 | 793 | ||
706 | xp = xfrm_policy_construct(p, (struct rtattr **) xfrma, &err); | 794 | xp = xfrm_policy_construct(p, (struct rtattr **)xfrma, &err); |
707 | if (!xp) | 795 | if (!xp) |
708 | return err; | 796 | return err; |
709 | 797 | ||
@@ -761,6 +849,27 @@ rtattr_failure: | |||
761 | return -1; | 849 | return -1; |
762 | } | 850 | } |
763 | 851 | ||
852 | static int copy_to_user_sec_ctx(struct xfrm_policy *xp, struct sk_buff *skb) | ||
853 | { | ||
854 | if (xp->security) { | ||
855 | int ctx_size = sizeof(struct xfrm_sec_ctx) + | ||
856 | xp->security->ctx_len; | ||
857 | struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size); | ||
858 | struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt); | ||
859 | |||
860 | uctx->exttype = XFRMA_SEC_CTX; | ||
861 | uctx->len = ctx_size; | ||
862 | uctx->ctx_doi = xp->security->ctx_doi; | ||
863 | uctx->ctx_alg = xp->security->ctx_alg; | ||
864 | uctx->ctx_len = xp->security->ctx_len; | ||
865 | memcpy(uctx + 1, xp->security->ctx_str, xp->security->ctx_len); | ||
866 | } | ||
867 | return 0; | ||
868 | |||
869 | rtattr_failure: | ||
870 | return -1; | ||
871 | } | ||
872 | |||
764 | static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr) | 873 | static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr) |
765 | { | 874 | { |
766 | struct xfrm_dump_info *sp = ptr; | 875 | struct xfrm_dump_info *sp = ptr; |
@@ -782,6 +891,8 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr | |||
782 | copy_to_user_policy(xp, p, dir); | 891 | copy_to_user_policy(xp, p, dir); |
783 | if (copy_to_user_tmpl(xp, skb) < 0) | 892 | if (copy_to_user_tmpl(xp, skb) < 0) |
784 | goto nlmsg_failure; | 893 | goto nlmsg_failure; |
894 | if (copy_to_user_sec_ctx(xp, skb)) | ||
895 | goto nlmsg_failure; | ||
785 | 896 | ||
786 | nlh->nlmsg_len = skb->tail - b; | 897 | nlh->nlmsg_len = skb->tail - b; |
787 | out: | 898 | out: |
@@ -852,8 +963,25 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
852 | 963 | ||
853 | if (p->index) | 964 | if (p->index) |
854 | xp = xfrm_policy_byid(p->dir, p->index, delete); | 965 | xp = xfrm_policy_byid(p->dir, p->index, delete); |
855 | else | 966 | else { |
856 | xp = xfrm_policy_bysel(p->dir, &p->sel, delete); | 967 | struct rtattr **rtattrs = (struct rtattr **)xfrma; |
968 | struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1]; | ||
969 | struct xfrm_policy tmp; | ||
970 | |||
971 | err = verify_sec_ctx_len(rtattrs); | ||
972 | if (err) | ||
973 | return err; | ||
974 | |||
975 | memset(&tmp, 0, sizeof(struct xfrm_policy)); | ||
976 | if (rt) { | ||
977 | struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt); | ||
978 | |||
979 | if ((err = security_xfrm_policy_alloc(&tmp, uctx))) | ||
980 | return err; | ||
981 | } | ||
982 | xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, delete); | ||
983 | security_xfrm_policy_free(&tmp); | ||
984 | } | ||
857 | if (xp == NULL) | 985 | if (xp == NULL) |
858 | return -ENOENT; | 986 | return -ENOENT; |
859 | 987 | ||
@@ -1224,6 +1352,8 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x, | |||
1224 | 1352 | ||
1225 | if (copy_to_user_tmpl(xp, skb) < 0) | 1353 | if (copy_to_user_tmpl(xp, skb) < 0) |
1226 | goto nlmsg_failure; | 1354 | goto nlmsg_failure; |
1355 | if (copy_to_user_sec_ctx(xp, skb)) | ||
1356 | goto nlmsg_failure; | ||
1227 | 1357 | ||
1228 | nlh->nlmsg_len = skb->tail - b; | 1358 | nlh->nlmsg_len = skb->tail - b; |
1229 | return skb->len; | 1359 | return skb->len; |
@@ -1241,6 +1371,7 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, | |||
1241 | 1371 | ||
1242 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); | 1372 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); |
1243 | len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire)); | 1373 | len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire)); |
1374 | len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); | ||
1244 | skb = alloc_skb(len, GFP_ATOMIC); | 1375 | skb = alloc_skb(len, GFP_ATOMIC); |
1245 | if (skb == NULL) | 1376 | if (skb == NULL) |
1246 | return -ENOMEM; | 1377 | return -ENOMEM; |
@@ -1324,6 +1455,8 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp, | |||
1324 | copy_to_user_policy(xp, &upe->pol, dir); | 1455 | copy_to_user_policy(xp, &upe->pol, dir); |
1325 | if (copy_to_user_tmpl(xp, skb) < 0) | 1456 | if (copy_to_user_tmpl(xp, skb) < 0) |
1326 | goto nlmsg_failure; | 1457 | goto nlmsg_failure; |
1458 | if (copy_to_user_sec_ctx(xp, skb)) | ||
1459 | goto nlmsg_failure; | ||
1327 | upe->hard = !!hard; | 1460 | upe->hard = !!hard; |
1328 | 1461 | ||
1329 | nlh->nlmsg_len = skb->tail - b; | 1462 | nlh->nlmsg_len = skb->tail - b; |
@@ -1341,6 +1474,7 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve | |||
1341 | 1474 | ||
1342 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); | 1475 | len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); |
1343 | len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire)); | 1476 | len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire)); |
1477 | len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); | ||
1344 | skb = alloc_skb(len, GFP_ATOMIC); | 1478 | skb = alloc_skb(len, GFP_ATOMIC); |
1345 | if (skb == NULL) | 1479 | if (skb == NULL) |
1346 | return -ENOMEM; | 1480 | return -ENOMEM; |
diff --git a/security/Kconfig b/security/Kconfig index 64d3f1e9ca85..34f593410d57 100644 --- a/security/Kconfig +++ b/security/Kconfig | |||
@@ -54,6 +54,19 @@ config SECURITY_NETWORK | |||
54 | implement socket and networking access controls. | 54 | implement socket and networking access controls. |
55 | If you are unsure how to answer this question, answer N. | 55 | If you are unsure how to answer this question, answer N. |
56 | 56 | ||
57 | config SECURITY_NETWORK_XFRM | ||
58 | bool "XFRM (IPSec) Networking Security Hooks" | ||
59 | depends on XFRM && SECURITY_NETWORK | ||
60 | help | ||
61 | This enables the XFRM (IPSec) networking security hooks. | ||
62 | If enabled, a security module can use these hooks to | ||
63 | implement per-packet access controls based on labels | ||
64 | derived from IPSec policy. Non-IPSec communications are | ||
65 | designated as unlabelled, and only sockets authorized | ||
66 | to communicate unlabelled data can send without using | ||
67 | IPSec. | ||
68 | If you are unsure how to answer this question, answer N. | ||
69 | |||
57 | config SECURITY_CAPABILITIES | 70 | config SECURITY_CAPABILITIES |
58 | tristate "Default Linux Capabilities" | 71 | tristate "Default Linux Capabilities" |
59 | depends on SECURITY | 72 | depends on SECURITY |
diff --git a/security/dummy.c b/security/dummy.c index 3ca5f2b828a0..a15c54709fde 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -776,8 +776,42 @@ static inline int dummy_sk_alloc_security (struct sock *sk, int family, gfp_t pr | |||
776 | static inline void dummy_sk_free_security (struct sock *sk) | 776 | static inline void dummy_sk_free_security (struct sock *sk) |
777 | { | 777 | { |
778 | } | 778 | } |
779 | |||
780 | static unsigned int dummy_sk_getsid(struct sock *sk, struct flowi *fl, u8 dir) | ||
781 | { | ||
782 | return 0; | ||
783 | } | ||
779 | #endif /* CONFIG_SECURITY_NETWORK */ | 784 | #endif /* CONFIG_SECURITY_NETWORK */ |
780 | 785 | ||
786 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | ||
787 | static int dummy_xfrm_policy_alloc_security(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) | ||
788 | { | ||
789 | return 0; | ||
790 | } | ||
791 | |||
792 | static inline int dummy_xfrm_policy_clone_security(struct xfrm_policy *old, struct xfrm_policy *new) | ||
793 | { | ||
794 | return 0; | ||
795 | } | ||
796 | |||
797 | static void dummy_xfrm_policy_free_security(struct xfrm_policy *xp) | ||
798 | { | ||
799 | } | ||
800 | |||
801 | static int dummy_xfrm_state_alloc_security(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) | ||
802 | { | ||
803 | return 0; | ||
804 | } | ||
805 | |||
806 | static void dummy_xfrm_state_free_security(struct xfrm_state *x) | ||
807 | { | ||
808 | } | ||
809 | |||
810 | static int dummy_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) | ||
811 | { | ||
812 | return 0; | ||
813 | } | ||
814 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ | ||
781 | static int dummy_register_security (const char *name, struct security_operations *ops) | 815 | static int dummy_register_security (const char *name, struct security_operations *ops) |
782 | { | 816 | { |
783 | return -EINVAL; | 817 | return -EINVAL; |
@@ -970,7 +1004,16 @@ void security_fixup_ops (struct security_operations *ops) | |||
970 | set_to_dummy_if_null(ops, socket_getpeersec); | 1004 | set_to_dummy_if_null(ops, socket_getpeersec); |
971 | set_to_dummy_if_null(ops, sk_alloc_security); | 1005 | set_to_dummy_if_null(ops, sk_alloc_security); |
972 | set_to_dummy_if_null(ops, sk_free_security); | 1006 | set_to_dummy_if_null(ops, sk_free_security); |
973 | #endif /* CONFIG_SECURITY_NETWORK */ | 1007 | set_to_dummy_if_null(ops, sk_getsid); |
1008 | #endif /* CONFIG_SECURITY_NETWORK */ | ||
1009 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | ||
1010 | set_to_dummy_if_null(ops, xfrm_policy_alloc_security); | ||
1011 | set_to_dummy_if_null(ops, xfrm_policy_clone_security); | ||
1012 | set_to_dummy_if_null(ops, xfrm_policy_free_security); | ||
1013 | set_to_dummy_if_null(ops, xfrm_state_alloc_security); | ||
1014 | set_to_dummy_if_null(ops, xfrm_state_free_security); | ||
1015 | set_to_dummy_if_null(ops, xfrm_policy_lookup); | ||
1016 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ | ||
974 | #ifdef CONFIG_KEYS | 1017 | #ifdef CONFIG_KEYS |
975 | set_to_dummy_if_null(ops, key_alloc); | 1018 | set_to_dummy_if_null(ops, key_alloc); |
976 | set_to_dummy_if_null(ops, key_free); | 1019 | set_to_dummy_if_null(ops, key_free); |
diff --git a/security/selinux/Makefile b/security/selinux/Makefile index b038cd0fae2e..06d54d9d20a5 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile | |||
@@ -8,5 +8,7 @@ selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o | |||
8 | 8 | ||
9 | selinux-$(CONFIG_SECURITY_NETWORK) += netif.o | 9 | selinux-$(CONFIG_SECURITY_NETWORK) += netif.o |
10 | 10 | ||
11 | selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o | ||
12 | |||
11 | EXTRA_CFLAGS += -Isecurity/selinux/include | 13 | EXTRA_CFLAGS += -Isecurity/selinux/include |
12 | 14 | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index fc774436a264..3d496eae1b47 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -73,6 +73,7 @@ | |||
73 | #include "avc.h" | 73 | #include "avc.h" |
74 | #include "objsec.h" | 74 | #include "objsec.h" |
75 | #include "netif.h" | 75 | #include "netif.h" |
76 | #include "xfrm.h" | ||
76 | 77 | ||
77 | #define XATTR_SELINUX_SUFFIX "selinux" | 78 | #define XATTR_SELINUX_SUFFIX "selinux" |
78 | #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX | 79 | #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX |
@@ -3349,6 +3350,10 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
3349 | err = avc_has_perm(sock_sid, port_sid, | 3350 | err = avc_has_perm(sock_sid, port_sid, |
3350 | sock_class, recv_perm, &ad); | 3351 | sock_class, recv_perm, &ad); |
3351 | } | 3352 | } |
3353 | |||
3354 | if (!err) | ||
3355 | err = selinux_xfrm_sock_rcv_skb(sock_sid, skb); | ||
3356 | |||
3352 | out: | 3357 | out: |
3353 | return err; | 3358 | return err; |
3354 | } | 3359 | } |
@@ -3401,6 +3406,24 @@ static void selinux_sk_free_security(struct sock *sk) | |||
3401 | sk_free_security(sk); | 3406 | sk_free_security(sk); |
3402 | } | 3407 | } |
3403 | 3408 | ||
3409 | static unsigned int selinux_sk_getsid_security(struct sock *sk, struct flowi *fl, u8 dir) | ||
3410 | { | ||
3411 | struct inode_security_struct *isec; | ||
3412 | u32 sock_sid = SECINITSID_ANY_SOCKET; | ||
3413 | |||
3414 | if (!sk) | ||
3415 | return selinux_no_sk_sid(fl); | ||
3416 | |||
3417 | read_lock_bh(&sk->sk_callback_lock); | ||
3418 | isec = get_sock_isec(sk); | ||
3419 | |||
3420 | if (isec) | ||
3421 | sock_sid = isec->sid; | ||
3422 | |||
3423 | read_unlock_bh(&sk->sk_callback_lock); | ||
3424 | return sock_sid; | ||
3425 | } | ||
3426 | |||
3404 | static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) | 3427 | static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) |
3405 | { | 3428 | { |
3406 | int err = 0; | 3429 | int err = 0; |
@@ -3536,6 +3559,11 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum, | |||
3536 | send_perm, &ad) ? NF_DROP : NF_ACCEPT; | 3559 | send_perm, &ad) ? NF_DROP : NF_ACCEPT; |
3537 | } | 3560 | } |
3538 | 3561 | ||
3562 | if (err != NF_ACCEPT) | ||
3563 | goto out; | ||
3564 | |||
3565 | err = selinux_xfrm_postroute_last(isec->sid, skb); | ||
3566 | |||
3539 | out: | 3567 | out: |
3540 | return err; | 3568 | return err; |
3541 | } | 3569 | } |
@@ -4380,6 +4408,16 @@ static struct security_operations selinux_ops = { | |||
4380 | .socket_getpeersec = selinux_socket_getpeersec, | 4408 | .socket_getpeersec = selinux_socket_getpeersec, |
4381 | .sk_alloc_security = selinux_sk_alloc_security, | 4409 | .sk_alloc_security = selinux_sk_alloc_security, |
4382 | .sk_free_security = selinux_sk_free_security, | 4410 | .sk_free_security = selinux_sk_free_security, |
4411 | .sk_getsid = selinux_sk_getsid_security, | ||
4412 | #endif | ||
4413 | |||
4414 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | ||
4415 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, | ||
4416 | .xfrm_policy_clone_security = selinux_xfrm_policy_clone, | ||
4417 | .xfrm_policy_free_security = selinux_xfrm_policy_free, | ||
4418 | .xfrm_state_alloc_security = selinux_xfrm_state_alloc, | ||
4419 | .xfrm_state_free_security = selinux_xfrm_state_free, | ||
4420 | .xfrm_policy_lookup = selinux_xfrm_policy_lookup, | ||
4383 | #endif | 4421 | #endif |
4384 | }; | 4422 | }; |
4385 | 4423 | ||
@@ -4491,6 +4529,7 @@ static int __init selinux_nf_ip_init(void) | |||
4491 | panic("SELinux: nf_register_hook for IPv6: error %d\n", err); | 4529 | panic("SELinux: nf_register_hook for IPv6: error %d\n", err); |
4492 | 4530 | ||
4493 | #endif /* IPV6 */ | 4531 | #endif /* IPV6 */ |
4532 | |||
4494 | out: | 4533 | out: |
4495 | return err; | 4534 | return err; |
4496 | } | 4535 | } |
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h index 1deb59e1b762..71aeb12f07c8 100644 --- a/security/selinux/include/av_perm_to_string.h +++ b/security/selinux/include/av_perm_to_string.h | |||
@@ -238,3 +238,5 @@ | |||
238 | S_(SECCLASS_NSCD, NSCD__SHMEMHOST, "shmemhost") | 238 | S_(SECCLASS_NSCD, NSCD__SHMEMHOST, "shmemhost") |
239 | S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto") | 239 | S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto") |
240 | S_(SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, "recvfrom") | 240 | S_(SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, "recvfrom") |
241 | S_(SECCLASS_ASSOCIATION, ASSOCIATION__RELABELFROM, "relabelfrom") | ||
242 | S_(SECCLASS_ASSOCIATION, ASSOCIATION__RELABELTO, "relabelto") | ||
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h index a78b5d59c9fc..d1d0996049e3 100644 --- a/security/selinux/include/av_permissions.h +++ b/security/selinux/include/av_permissions.h | |||
@@ -908,6 +908,8 @@ | |||
908 | 908 | ||
909 | #define ASSOCIATION__SENDTO 0x00000001UL | 909 | #define ASSOCIATION__SENDTO 0x00000001UL |
910 | #define ASSOCIATION__RECVFROM 0x00000002UL | 910 | #define ASSOCIATION__RECVFROM 0x00000002UL |
911 | #define ASSOCIATION__RELABELFROM 0x00000004UL | ||
912 | #define ASSOCIATION__RELABELTO 0x00000008UL | ||
911 | 913 | ||
912 | #define NETLINK_KOBJECT_UEVENT_SOCKET__IOCTL 0x00000001UL | 914 | #define NETLINK_KOBJECT_UEVENT_SOCKET__IOCTL 0x00000001UL |
913 | #define NETLINK_KOBJECT_UEVENT_SOCKET__READ 0x00000002UL | 915 | #define NETLINK_KOBJECT_UEVENT_SOCKET__READ 0x00000002UL |
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h new file mode 100644 index 000000000000..8e87996c6dd5 --- /dev/null +++ b/security/selinux/include/xfrm.h | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * SELinux support for the XFRM LSM hooks | ||
3 | * | ||
4 | * Author : Trent Jaeger, <jaegert@us.ibm.com> | ||
5 | */ | ||
6 | #ifndef _SELINUX_XFRM_H_ | ||
7 | #define _SELINUX_XFRM_H_ | ||
8 | |||
9 | int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx); | ||
10 | int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new); | ||
11 | void selinux_xfrm_policy_free(struct xfrm_policy *xp); | ||
12 | int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx); | ||
13 | void selinux_xfrm_state_free(struct xfrm_state *x); | ||
14 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir); | ||
15 | |||
16 | /* | ||
17 | * Extract the security blob from the sock (it's actually on the socket) | ||
18 | */ | ||
19 | static inline struct inode_security_struct *get_sock_isec(struct sock *sk) | ||
20 | { | ||
21 | if (!sk->sk_socket) | ||
22 | return NULL; | ||
23 | |||
24 | return SOCK_INODE(sk->sk_socket)->i_security; | ||
25 | } | ||
26 | |||
27 | |||
28 | static inline u32 selinux_no_sk_sid(struct flowi *fl) | ||
29 | { | ||
30 | /* NOTE: no sock occurs on ICMP reply, forwards, ... */ | ||
31 | /* icmp_reply: authorize as kernel packet */ | ||
32 | if (fl && fl->proto == IPPROTO_ICMP) { | ||
33 | return SECINITSID_KERNEL; | ||
34 | } | ||
35 | |||
36 | return SECINITSID_ANY_SOCKET; | ||
37 | } | ||
38 | |||
39 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | ||
40 | int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb); | ||
41 | int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb); | ||
42 | #else | ||
43 | static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb) | ||
44 | { | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb) | ||
49 | { | ||
50 | return NF_ACCEPT; | ||
51 | } | ||
52 | #endif | ||
53 | |||
54 | #endif /* _SELINUX_XFRM_H_ */ | ||
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c new file mode 100644 index 000000000000..c4d87d4dca7b --- /dev/null +++ b/security/selinux/xfrm.c | |||
@@ -0,0 +1,311 @@ | |||
1 | /* | ||
2 | * NSA Security-Enhanced Linux (SELinux) security module | ||
3 | * | ||
4 | * This file contains the SELinux XFRM hook function implementations. | ||
5 | * | ||
6 | * Authors: Serge Hallyn <sergeh@us.ibm.com> | ||
7 | * Trent Jaeger <jaegert@us.ibm.com> | ||
8 | * | ||
9 | * Copyright (C) 2005 International Business Machines Corporation | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2, | ||
13 | * as published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | /* | ||
17 | * USAGE: | ||
18 | * NOTES: | ||
19 | * 1. Make sure to enable the following options in your kernel config: | ||
20 | * CONFIG_SECURITY=y | ||
21 | * CONFIG_SECURITY_NETWORK=y | ||
22 | * CONFIG_SECURITY_NETWORK_XFRM=y | ||
23 | * CONFIG_SECURITY_SELINUX=m/y | ||
24 | * ISSUES: | ||
25 | * 1. Caching packets, so they are not dropped during negotiation | ||
26 | * 2. Emulating a reasonable SO_PEERSEC across machines | ||
27 | * 3. Testing addition of sk_policy's with security context via setsockopt | ||
28 | */ | ||
29 | #include <linux/config.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/security.h> | ||
34 | #include <linux/types.h> | ||
35 | #include <linux/netfilter.h> | ||
36 | #include <linux/netfilter_ipv4.h> | ||
37 | #include <linux/netfilter_ipv6.h> | ||
38 | #include <linux/ip.h> | ||
39 | #include <linux/tcp.h> | ||
40 | #include <linux/skbuff.h> | ||
41 | #include <linux/xfrm.h> | ||
42 | #include <net/xfrm.h> | ||
43 | #include <net/checksum.h> | ||
44 | #include <net/udp.h> | ||
45 | #include <asm/semaphore.h> | ||
46 | |||
47 | #include "avc.h" | ||
48 | #include "objsec.h" | ||
49 | #include "xfrm.h" | ||
50 | |||
51 | |||
52 | /* | ||
53 | * Returns true if an LSM/SELinux context | ||
54 | */ | ||
55 | static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx) | ||
56 | { | ||
57 | return (ctx && | ||
58 | (ctx->ctx_doi == XFRM_SC_DOI_LSM) && | ||
59 | (ctx->ctx_alg == XFRM_SC_ALG_SELINUX)); | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * Returns true if the xfrm contains a security blob for SELinux | ||
64 | */ | ||
65 | static inline int selinux_authorizable_xfrm(struct xfrm_state *x) | ||
66 | { | ||
67 | return selinux_authorizable_ctx(x->security); | ||
68 | } | ||
69 | |||
70 | /* | ||
71 | * LSM hook implementation that authorizes that a socket can be used | ||
72 | * with the corresponding xfrm_sec_ctx and direction. | ||
73 | */ | ||
74 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) | ||
75 | { | ||
76 | int rc = 0; | ||
77 | u32 sel_sid = SECINITSID_UNLABELED; | ||
78 | struct xfrm_sec_ctx *ctx; | ||
79 | |||
80 | /* Context sid is either set to label or ANY_ASSOC */ | ||
81 | if ((ctx = xp->security)) { | ||
82 | if (!selinux_authorizable_ctx(ctx)) | ||
83 | return -EINVAL; | ||
84 | |||
85 | sel_sid = ctx->ctx_sid; | ||
86 | } | ||
87 | |||
88 | rc = avc_has_perm(sk_sid, sel_sid, SECCLASS_ASSOCIATION, | ||
89 | ((dir == FLOW_DIR_IN) ? ASSOCIATION__RECVFROM : | ||
90 | ((dir == FLOW_DIR_OUT) ? ASSOCIATION__SENDTO : | ||
91 | (ASSOCIATION__SENDTO | ASSOCIATION__RECVFROM))), | ||
92 | NULL); | ||
93 | |||
94 | return rc; | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * Security blob allocation for xfrm_policy and xfrm_state | ||
99 | * CTX does not have a meaningful value on input | ||
100 | */ | ||
101 | static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *uctx) | ||
102 | { | ||
103 | int rc = 0; | ||
104 | struct task_security_struct *tsec = current->security; | ||
105 | struct xfrm_sec_ctx *ctx; | ||
106 | |||
107 | BUG_ON(!uctx); | ||
108 | BUG_ON(uctx->ctx_doi != XFRM_SC_ALG_SELINUX); | ||
109 | |||
110 | if (uctx->ctx_len >= PAGE_SIZE) | ||
111 | return -ENOMEM; | ||
112 | |||
113 | *ctxp = ctx = kmalloc(sizeof(*ctx) + | ||
114 | uctx->ctx_len, | ||
115 | GFP_KERNEL); | ||
116 | |||
117 | if (!ctx) | ||
118 | return -ENOMEM; | ||
119 | |||
120 | ctx->ctx_doi = uctx->ctx_doi; | ||
121 | ctx->ctx_len = uctx->ctx_len; | ||
122 | ctx->ctx_alg = uctx->ctx_alg; | ||
123 | |||
124 | memcpy(ctx->ctx_str, | ||
125 | uctx+1, | ||
126 | ctx->ctx_len); | ||
127 | rc = security_context_to_sid(ctx->ctx_str, | ||
128 | ctx->ctx_len, | ||
129 | &ctx->ctx_sid); | ||
130 | |||
131 | if (rc) | ||
132 | goto out; | ||
133 | |||
134 | /* | ||
135 | * Does the subject have permission to set security or permission to | ||
136 | * do the relabel? | ||
137 | * Must be permitted to relabel from default socket type (process type) | ||
138 | * to specified context | ||
139 | */ | ||
140 | rc = avc_has_perm(tsec->sid, tsec->sid, | ||
141 | SECCLASS_ASSOCIATION, | ||
142 | ASSOCIATION__RELABELFROM, NULL); | ||
143 | if (rc) | ||
144 | goto out; | ||
145 | |||
146 | rc = avc_has_perm(tsec->sid, ctx->ctx_sid, | ||
147 | SECCLASS_ASSOCIATION, | ||
148 | ASSOCIATION__RELABELTO, NULL); | ||
149 | if (rc) | ||
150 | goto out; | ||
151 | |||
152 | return rc; | ||
153 | |||
154 | out: | ||
155 | *ctxp = 0; | ||
156 | kfree(ctx); | ||
157 | return rc; | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * LSM hook implementation that allocs and transfers uctx spec to | ||
162 | * xfrm_policy. | ||
163 | */ | ||
164 | int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *uctx) | ||
165 | { | ||
166 | int err; | ||
167 | |||
168 | BUG_ON(!xp); | ||
169 | |||
170 | err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx); | ||
171 | return err; | ||
172 | } | ||
173 | |||
174 | |||
175 | /* | ||
176 | * LSM hook implementation that copies security data structure from old to | ||
177 | * new for policy cloning. | ||
178 | */ | ||
179 | int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) | ||
180 | { | ||
181 | struct xfrm_sec_ctx *old_ctx, *new_ctx; | ||
182 | |||
183 | old_ctx = old->security; | ||
184 | |||
185 | if (old_ctx) { | ||
186 | new_ctx = new->security = kmalloc(sizeof(*new_ctx) + | ||
187 | old_ctx->ctx_len, | ||
188 | GFP_KERNEL); | ||
189 | |||
190 | if (!new_ctx) | ||
191 | return -ENOMEM; | ||
192 | |||
193 | memcpy(new_ctx, old_ctx, sizeof(*new_ctx)); | ||
194 | memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len); | ||
195 | } | ||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | /* | ||
200 | * LSM hook implementation that frees xfrm_policy security information. | ||
201 | */ | ||
202 | void selinux_xfrm_policy_free(struct xfrm_policy *xp) | ||
203 | { | ||
204 | struct xfrm_sec_ctx *ctx = xp->security; | ||
205 | if (ctx) | ||
206 | kfree(ctx); | ||
207 | } | ||
208 | |||
209 | /* | ||
210 | * LSM hook implementation that allocs and transfers sec_ctx spec to | ||
211 | * xfrm_state. | ||
212 | */ | ||
213 | int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uctx) | ||
214 | { | ||
215 | int err; | ||
216 | |||
217 | BUG_ON(!x); | ||
218 | |||
219 | err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx); | ||
220 | return err; | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * LSM hook implementation that frees xfrm_state security information. | ||
225 | */ | ||
226 | void selinux_xfrm_state_free(struct xfrm_state *x) | ||
227 | { | ||
228 | struct xfrm_sec_ctx *ctx = x->security; | ||
229 | if (ctx) | ||
230 | kfree(ctx); | ||
231 | } | ||
232 | |||
233 | /* | ||
234 | * LSM hook that controls access to unlabelled packets. If | ||
235 | * a xfrm_state is authorizable (defined by macro) then it was | ||
236 | * already authorized by the IPSec process. If not, then | ||
237 | * we need to check for unlabelled access since this may not have | ||
238 | * gone thru the IPSec process. | ||
239 | */ | ||
240 | int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb) | ||
241 | { | ||
242 | int i, rc = 0; | ||
243 | struct sec_path *sp; | ||
244 | |||
245 | sp = skb->sp; | ||
246 | |||
247 | if (sp) { | ||
248 | /* | ||
249 | * __xfrm_policy_check does not approve unless xfrm_policy_ok | ||
250 | * says that spi's match for policy and the socket. | ||
251 | * | ||
252 | * Only need to verify the existence of an authorizable sp. | ||
253 | */ | ||
254 | for (i = 0; i < sp->len; i++) { | ||
255 | struct xfrm_state *x = sp->x[i].xvec; | ||
256 | |||
257 | if (x && selinux_authorizable_xfrm(x)) | ||
258 | goto accept; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | /* check SELinux sock for unlabelled access */ | ||
263 | rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION, | ||
264 | ASSOCIATION__RECVFROM, NULL); | ||
265 | if (rc) | ||
266 | goto drop; | ||
267 | |||
268 | accept: | ||
269 | return 0; | ||
270 | |||
271 | drop: | ||
272 | return rc; | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | * POSTROUTE_LAST hook's XFRM processing: | ||
277 | * If we have no security association, then we need to determine | ||
278 | * whether the socket is allowed to send to an unlabelled destination. | ||
279 | * If we do have a authorizable security association, then it has already been | ||
280 | * checked in xfrm_policy_lookup hook. | ||
281 | */ | ||
282 | int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb) | ||
283 | { | ||
284 | struct dst_entry *dst; | ||
285 | int rc = 0; | ||
286 | |||
287 | dst = skb->dst; | ||
288 | |||
289 | if (dst) { | ||
290 | struct dst_entry *dst_test; | ||
291 | |||
292 | for (dst_test = dst; dst_test != 0; | ||
293 | dst_test = dst_test->child) { | ||
294 | struct xfrm_state *x = dst_test->xfrm; | ||
295 | |||
296 | if (x && selinux_authorizable_xfrm(x)) | ||
297 | goto accept; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION, | ||
302 | ASSOCIATION__SENDTO, NULL); | ||
303 | if (rc) | ||
304 | goto drop; | ||
305 | |||
306 | accept: | ||
307 | return NF_ACCEPT; | ||
308 | |||
309 | drop: | ||
310 | return NF_DROP; | ||
311 | } | ||
diff --git a/sound/sparc/Kconfig b/sound/sparc/Kconfig index 09ab138646a6..ef022a846b06 100644 --- a/sound/sparc/Kconfig +++ b/sound/sparc/Kconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # ALSA Sparc drivers | 1 | # ALSA Sparc drivers |
2 | 2 | ||
3 | menu "ALSA Sparc devices" | 3 | menu "ALSA Sparc devices" |
4 | depends on SND!=n && (SPARC32 || SPARC64) | 4 | depends on SND!=n && SPARC |
5 | 5 | ||
6 | config SND_SUN_AMD7930 | 6 | config SND_SUN_AMD7930 |
7 | tristate "Sun AMD7930" | 7 | tristate "Sun AMD7930" |
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 99dae024b640..22f8bb612bff 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -1996,7 +1996,6 @@ static struct usb_device_id usb_audio_ids [] = { | |||
1996 | MODULE_DEVICE_TABLE (usb, usb_audio_ids); | 1996 | MODULE_DEVICE_TABLE (usb, usb_audio_ids); |
1997 | 1997 | ||
1998 | static struct usb_driver usb_audio_driver = { | 1998 | static struct usb_driver usb_audio_driver = { |
1999 | .owner = THIS_MODULE, | ||
2000 | .name = "snd-usb-audio", | 1999 | .name = "snd-usb-audio", |
2001 | .probe = usb_audio_probe, | 2000 | .probe = usb_audio_probe, |
2002 | .disconnect = usb_audio_disconnect, | 2001 | .disconnect = usb_audio_disconnect, |
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c index cf77313c609d..a3967f72ab4e 100644 --- a/sound/usb/usx2y/usbusx2y.c +++ b/sound/usb/usx2y/usbusx2y.c | |||
@@ -409,7 +409,6 @@ static void snd_usX2Y_disconnect(struct usb_interface *intf) | |||
409 | 409 | ||
410 | MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table); | 410 | MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table); |
411 | static struct usb_driver snd_usX2Y_usb_driver = { | 411 | static struct usb_driver snd_usX2Y_usb_driver = { |
412 | .owner = THIS_MODULE, | ||
413 | .name = "snd-usb-usx2y", | 412 | .name = "snd-usb-usx2y", |
414 | .probe = snd_usX2Y_probe, | 413 | .probe = snd_usX2Y_probe, |
415 | .disconnect = snd_usX2Y_disconnect, | 414 | .disconnect = snd_usX2Y_disconnect, |