diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-03-23 17:05:10 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-03-23 17:05:10 -0400 |
commit | 5617c05d44ebd7b75973b5b31a9f2e55e5882d3f (patch) | |
tree | 7250f4b5690c141115a13afdb21c12cc720ae79c | |
parent | 22db87ba6bbefcb12493ae9c7be2037f5f12639d (diff) | |
parent | 25cd9721c2b16ee0d775e36ec3af31f392003f80 (diff) |
Merge tag 'fixes-for-v4.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus
Felipe writes:
usb: fixes for v4.11-rc4
f_acm got an endianness fix by Oliver Neukum. This has been around for a
long time but it's finally fixed.
f_hid learned that it should never access hidg->req without first
grabbing the spinlock.
Roger Quadros fixed two bugs in the f_uvc function driver.
Janusz Dziedzic fixed a very peculiar bug with EP0, one that's rather
difficult to trigger. When we're dealing with bounced EP0 requests, we
should delay unmap until after ->complete() is called.
UDC class got a use-after-free fix.
372 files changed, 5757 insertions, 2949 deletions
diff --git a/Documentation/cgroup-v2.txt b/Documentation/cgroup-v2.txt index 3b8449f8ac7e..49d7c997fa1e 100644 --- a/Documentation/cgroup-v2.txt +++ b/Documentation/cgroup-v2.txt | |||
@@ -1142,16 +1142,17 @@ used by the kernel. | |||
1142 | 1142 | ||
1143 | pids.max | 1143 | pids.max |
1144 | 1144 | ||
1145 | A read-write single value file which exists on non-root cgroups. The | 1145 | A read-write single value file which exists on non-root |
1146 | default is "max". | 1146 | cgroups. The default is "max". |
1147 | 1147 | ||
1148 | Hard limit of number of processes. | 1148 | Hard limit of number of processes. |
1149 | 1149 | ||
1150 | pids.current | 1150 | pids.current |
1151 | 1151 | ||
1152 | A read-only single value file which exists on all cgroups. | 1152 | A read-only single value file which exists on all cgroups. |
1153 | 1153 | ||
1154 | The number of processes currently in the cgroup and its descendants. | 1154 | The number of processes currently in the cgroup and its |
1155 | descendants. | ||
1155 | 1156 | ||
1156 | Organisational operations are not blocked by cgroup policies, so it is | 1157 | Organisational operations are not blocked by cgroup policies, so it is |
1157 | possible to have pids.current > pids.max. This can be done by either | 1158 | possible to have pids.current > pids.max. This can be done by either |
diff --git a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt index 712baf6c3e24..44b842b6ca15 100644 --- a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt +++ b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt | |||
@@ -71,6 +71,9 @@ | |||
71 | For Axon it can be absent, though my current driver | 71 | For Axon it can be absent, though my current driver |
72 | doesn't handle phy-address yet so for now, keep | 72 | doesn't handle phy-address yet so for now, keep |
73 | 0x00ffffff in it. | 73 | 0x00ffffff in it. |
74 | - phy-handle : Used to describe configurations where a external PHY | ||
75 | is used. Please refer to: | ||
76 | Documentation/devicetree/bindings/net/ethernet.txt | ||
74 | - rx-fifo-size-gige : 1 cell, Rx fifo size in bytes for 1000 Mb/sec | 77 | - rx-fifo-size-gige : 1 cell, Rx fifo size in bytes for 1000 Mb/sec |
75 | operations (if absent the value is the same as | 78 | operations (if absent the value is the same as |
76 | rx-fifo-size). For Axon, either absent or 2048. | 79 | rx-fifo-size). For Axon, either absent or 2048. |
@@ -81,8 +84,22 @@ | |||
81 | offload, phandle of the TAH device node. | 84 | offload, phandle of the TAH device node. |
82 | - tah-channel : 1 cell, optional. If appropriate, channel used on the | 85 | - tah-channel : 1 cell, optional. If appropriate, channel used on the |
83 | TAH engine. | 86 | TAH engine. |
87 | - fixed-link : Fixed-link subnode describing a link to a non-MDIO | ||
88 | managed entity. See | ||
89 | Documentation/devicetree/bindings/net/fixed-link.txt | ||
90 | for details. | ||
91 | - mdio subnode : When the EMAC has a phy connected to its local | ||
92 | mdio, which us supported by the kernel's network | ||
93 | PHY library in drivers/net/phy, there must be device | ||
94 | tree subnode with the following required properties: | ||
95 | - #address-cells: Must be <1>. | ||
96 | - #size-cells: Must be <0>. | ||
84 | 97 | ||
85 | Example: | 98 | For PHY definitions: Please refer to |
99 | Documentation/devicetree/bindings/net/phy.txt and | ||
100 | Documentation/devicetree/bindings/net/ethernet.txt | ||
101 | |||
102 | Examples: | ||
86 | 103 | ||
87 | EMAC0: ethernet@40000800 { | 104 | EMAC0: ethernet@40000800 { |
88 | device_type = "network"; | 105 | device_type = "network"; |
@@ -104,6 +121,48 @@ | |||
104 | zmii-channel = <0>; | 121 | zmii-channel = <0>; |
105 | }; | 122 | }; |
106 | 123 | ||
124 | EMAC1: ethernet@ef600c00 { | ||
125 | device_type = "network"; | ||
126 | compatible = "ibm,emac-apm821xx", "ibm,emac4sync"; | ||
127 | interrupt-parent = <&EMAC1>; | ||
128 | interrupts = <0 1>; | ||
129 | #interrupt-cells = <1>; | ||
130 | #address-cells = <0>; | ||
131 | #size-cells = <0>; | ||
132 | interrupt-map = <0 &UIC2 0x10 IRQ_TYPE_LEVEL_HIGH /* Status */ | ||
133 | 1 &UIC2 0x14 IRQ_TYPE_LEVEL_HIGH /* Wake */>; | ||
134 | reg = <0xef600c00 0x000000c4>; | ||
135 | local-mac-address = [000000000000]; /* Filled in by U-Boot */ | ||
136 | mal-device = <&MAL0>; | ||
137 | mal-tx-channel = <0>; | ||
138 | mal-rx-channel = <0>; | ||
139 | cell-index = <0>; | ||
140 | max-frame-size = <9000>; | ||
141 | rx-fifo-size = <16384>; | ||
142 | tx-fifo-size = <2048>; | ||
143 | fifo-entry-size = <10>; | ||
144 | phy-mode = "rgmii"; | ||
145 | phy-handle = <&phy0>; | ||
146 | phy-map = <0x00000000>; | ||
147 | rgmii-device = <&RGMII0>; | ||
148 | rgmii-channel = <0>; | ||
149 | tah-device = <&TAH0>; | ||
150 | tah-channel = <0>; | ||
151 | has-inverted-stacr-oc; | ||
152 | has-new-stacr-staopc; | ||
153 | |||
154 | mdio { | ||
155 | #address-cells = <1>; | ||
156 | #size-cells = <0>; | ||
157 | |||
158 | phy0: ethernet-phy@0 { | ||
159 | compatible = "ethernet-phy-ieee802.3-c22"; | ||
160 | reg = <0>; | ||
161 | }; | ||
162 | }; | ||
163 | }; | ||
164 | |||
165 | |||
107 | ii) McMAL node | 166 | ii) McMAL node |
108 | 167 | ||
109 | Required properties: | 168 | Required properties: |
@@ -145,4 +204,3 @@ | |||
145 | - revision : as provided by the RGMII new version register if | 204 | - revision : as provided by the RGMII new version register if |
146 | available. | 205 | available. |
147 | For Axon: 0x0000012a | 206 | For Axon: 0x0000012a |
148 | |||
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index fc73eeb7b3b8..ab0230461377 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
@@ -1006,7 +1006,8 @@ accept_redirects - BOOLEAN | |||
1006 | FALSE (router) | 1006 | FALSE (router) |
1007 | 1007 | ||
1008 | forwarding - BOOLEAN | 1008 | forwarding - BOOLEAN |
1009 | Enable IP forwarding on this interface. | 1009 | Enable IP forwarding on this interface. This controls whether packets |
1010 | received _on_ this interface can be forwarded. | ||
1010 | 1011 | ||
1011 | mc_forwarding - BOOLEAN | 1012 | mc_forwarding - BOOLEAN |
1012 | Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE | 1013 | Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 4 | 1 | VERSION = 4 |
2 | PATCHLEVEL = 11 | 2 | PATCHLEVEL = 11 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = -rc2 | 4 | EXTRAVERSION = -rc3 |
5 | NAME = Fearless Coyote | 5 | NAME = Fearless Coyote |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl index 3c2cb5d5adfa..0bb0e9c6376c 100644 --- a/arch/arm/tools/syscall.tbl +++ b/arch/arm/tools/syscall.tbl | |||
@@ -411,3 +411,4 @@ | |||
411 | 394 common pkey_mprotect sys_pkey_mprotect | 411 | 394 common pkey_mprotect sys_pkey_mprotect |
412 | 395 common pkey_alloc sys_pkey_alloc | 412 | 395 common pkey_alloc sys_pkey_alloc |
413 | 396 common pkey_free sys_pkey_free | 413 | 396 common pkey_free sys_pkey_free |
414 | 397 common statx sys_statx | ||
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 8c7c244247b6..3741859765cf 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -1073,6 +1073,10 @@ config SYSVIPC_COMPAT | |||
1073 | def_bool y | 1073 | def_bool y |
1074 | depends on COMPAT && SYSVIPC | 1074 | depends on COMPAT && SYSVIPC |
1075 | 1075 | ||
1076 | config KEYS_COMPAT | ||
1077 | def_bool y | ||
1078 | depends on COMPAT && KEYS | ||
1079 | |||
1076 | endmenu | 1080 | endmenu |
1077 | 1081 | ||
1078 | menu "Power management options" | 1082 | menu "Power management options" |
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index 05310ad8c5ab..f31c48d0cd68 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h | |||
@@ -251,7 +251,7 @@ static inline bool system_supports_fpsimd(void) | |||
251 | static inline bool system_uses_ttbr0_pan(void) | 251 | static inline bool system_uses_ttbr0_pan(void) |
252 | { | 252 | { |
253 | return IS_ENABLED(CONFIG_ARM64_SW_TTBR0_PAN) && | 253 | return IS_ENABLED(CONFIG_ARM64_SW_TTBR0_PAN) && |
254 | !cpus_have_cap(ARM64_HAS_PAN); | 254 | !cpus_have_const_cap(ARM64_HAS_PAN); |
255 | } | 255 | } |
256 | 256 | ||
257 | #endif /* __ASSEMBLY__ */ | 257 | #endif /* __ASSEMBLY__ */ |
diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c index 75a0f8acef66..fd691087dc9a 100644 --- a/arch/arm64/kernel/cpuidle.c +++ b/arch/arm64/kernel/cpuidle.c | |||
@@ -30,7 +30,7 @@ int arm_cpuidle_init(unsigned int cpu) | |||
30 | } | 30 | } |
31 | 31 | ||
32 | /** | 32 | /** |
33 | * cpu_suspend() - function to enter a low-power idle state | 33 | * arm_cpuidle_suspend() - function to enter a low-power idle state |
34 | * @arg: argument to pass to CPU suspend operations | 34 | * @arg: argument to pass to CPU suspend operations |
35 | * | 35 | * |
36 | * Return: 0 on success, -EOPNOTSUPP if CPU suspend hook not initialized, CPU | 36 | * Return: 0 on success, -EOPNOTSUPP if CPU suspend hook not initialized, CPU |
diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c index 2a07aae5b8a2..c5c45942fb6e 100644 --- a/arch/arm64/kernel/probes/kprobes.c +++ b/arch/arm64/kernel/probes/kprobes.c | |||
@@ -372,12 +372,6 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr) | |||
372 | return 0; | 372 | return 0; |
373 | } | 373 | } |
374 | 374 | ||
375 | int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | ||
376 | unsigned long val, void *data) | ||
377 | { | ||
378 | return NOTIFY_DONE; | ||
379 | } | ||
380 | |||
381 | static void __kprobes kprobe_handler(struct pt_regs *regs) | 375 | static void __kprobes kprobe_handler(struct pt_regs *regs) |
382 | { | 376 | { |
383 | struct kprobe *p, *cur_kprobe; | 377 | struct kprobe *p, *cur_kprobe; |
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c index 55d1e9205543..687a358a3733 100644 --- a/arch/arm64/mm/kasan_init.c +++ b/arch/arm64/mm/kasan_init.c | |||
@@ -162,7 +162,7 @@ void __init kasan_init(void) | |||
162 | clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END); | 162 | clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END); |
163 | 163 | ||
164 | vmemmap_populate(kimg_shadow_start, kimg_shadow_end, | 164 | vmemmap_populate(kimg_shadow_start, kimg_shadow_end, |
165 | pfn_to_nid(virt_to_pfn(_text))); | 165 | pfn_to_nid(virt_to_pfn(lm_alias(_text)))); |
166 | 166 | ||
167 | /* | 167 | /* |
168 | * vmemmap_populate() has populated the shadow region that covers the | 168 | * vmemmap_populate() has populated the shadow region that covers the |
diff --git a/arch/openrisc/include/asm/cmpxchg.h b/arch/openrisc/include/asm/cmpxchg.h index 5fcb9ac72693..f0a5d8b844d6 100644 --- a/arch/openrisc/include/asm/cmpxchg.h +++ b/arch/openrisc/include/asm/cmpxchg.h | |||
@@ -77,7 +77,11 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr, | |||
77 | return val; | 77 | return val; |
78 | } | 78 | } |
79 | 79 | ||
80 | #define xchg(ptr, with) \ | 80 | #define xchg(ptr, with) \ |
81 | ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), sizeof(*(ptr)))) | 81 | ({ \ |
82 | (__typeof__(*(ptr))) __xchg((unsigned long)(with), \ | ||
83 | (ptr), \ | ||
84 | sizeof(*(ptr))); \ | ||
85 | }) | ||
82 | 86 | ||
83 | #endif /* __ASM_OPENRISC_CMPXCHG_H */ | 87 | #endif /* __ASM_OPENRISC_CMPXCHG_H */ |
diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h index 140faa16685a..1311e6b13991 100644 --- a/arch/openrisc/include/asm/uaccess.h +++ b/arch/openrisc/include/asm/uaccess.h | |||
@@ -211,7 +211,7 @@ do { \ | |||
211 | case 1: __get_user_asm(x, ptr, retval, "l.lbz"); break; \ | 211 | case 1: __get_user_asm(x, ptr, retval, "l.lbz"); break; \ |
212 | case 2: __get_user_asm(x, ptr, retval, "l.lhz"); break; \ | 212 | case 2: __get_user_asm(x, ptr, retval, "l.lhz"); break; \ |
213 | case 4: __get_user_asm(x, ptr, retval, "l.lwz"); break; \ | 213 | case 4: __get_user_asm(x, ptr, retval, "l.lwz"); break; \ |
214 | case 8: __get_user_asm2(x, ptr, retval); \ | 214 | case 8: __get_user_asm2(x, ptr, retval); break; \ |
215 | default: (x) = __get_user_bad(); \ | 215 | default: (x) = __get_user_bad(); \ |
216 | } \ | 216 | } \ |
217 | } while (0) | 217 | } while (0) |
diff --git a/arch/openrisc/kernel/or32_ksyms.c b/arch/openrisc/kernel/or32_ksyms.c index 5c4695d13542..ee3e604959e1 100644 --- a/arch/openrisc/kernel/or32_ksyms.c +++ b/arch/openrisc/kernel/or32_ksyms.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/hardirq.h> | 30 | #include <asm/hardirq.h> |
31 | #include <asm/delay.h> | 31 | #include <asm/delay.h> |
32 | #include <asm/pgalloc.h> | 32 | #include <asm/pgalloc.h> |
33 | #include <asm/pgtable.h> | ||
33 | 34 | ||
34 | #define DECLARE_EXPORT(name) extern void name(void); EXPORT_SYMBOL(name) | 35 | #define DECLARE_EXPORT(name) extern void name(void); EXPORT_SYMBOL(name) |
35 | 36 | ||
@@ -42,6 +43,9 @@ DECLARE_EXPORT(__muldi3); | |||
42 | DECLARE_EXPORT(__ashrdi3); | 43 | DECLARE_EXPORT(__ashrdi3); |
43 | DECLARE_EXPORT(__ashldi3); | 44 | DECLARE_EXPORT(__ashldi3); |
44 | DECLARE_EXPORT(__lshrdi3); | 45 | DECLARE_EXPORT(__lshrdi3); |
46 | DECLARE_EXPORT(__ucmpdi2); | ||
45 | 47 | ||
48 | EXPORT_SYMBOL(empty_zero_page); | ||
46 | EXPORT_SYMBOL(__copy_tofrom_user); | 49 | EXPORT_SYMBOL(__copy_tofrom_user); |
50 | EXPORT_SYMBOL(__clear_user); | ||
47 | EXPORT_SYMBOL(memset); | 51 | EXPORT_SYMBOL(memset); |
diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c index 828a29110459..f8da545854f9 100644 --- a/arch/openrisc/kernel/process.c +++ b/arch/openrisc/kernel/process.c | |||
@@ -90,6 +90,7 @@ void arch_cpu_idle(void) | |||
90 | } | 90 | } |
91 | 91 | ||
92 | void (*pm_power_off) (void) = machine_power_off; | 92 | void (*pm_power_off) (void) = machine_power_off; |
93 | EXPORT_SYMBOL(pm_power_off); | ||
93 | 94 | ||
94 | /* | 95 | /* |
95 | * When a process does an "exec", machine state like FPU and debug | 96 | * When a process does an "exec", machine state like FPU and debug |
diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h index 19c9c3c5f267..c7e15cc5c668 100644 --- a/arch/parisc/include/asm/cacheflush.h +++ b/arch/parisc/include/asm/cacheflush.h | |||
@@ -43,28 +43,9 @@ static inline void flush_kernel_dcache_page(struct page *page) | |||
43 | 43 | ||
44 | #define flush_kernel_dcache_range(start,size) \ | 44 | #define flush_kernel_dcache_range(start,size) \ |
45 | flush_kernel_dcache_range_asm((start), (start)+(size)); | 45 | flush_kernel_dcache_range_asm((start), (start)+(size)); |
46 | /* vmap range flushes and invalidates. Architecturally, we don't need | ||
47 | * the invalidate, because the CPU should refuse to speculate once an | ||
48 | * area has been flushed, so invalidate is left empty */ | ||
49 | static inline void flush_kernel_vmap_range(void *vaddr, int size) | ||
50 | { | ||
51 | unsigned long start = (unsigned long)vaddr; | ||
52 | |||
53 | flush_kernel_dcache_range_asm(start, start + size); | ||
54 | } | ||
55 | static inline void invalidate_kernel_vmap_range(void *vaddr, int size) | ||
56 | { | ||
57 | unsigned long start = (unsigned long)vaddr; | ||
58 | void *cursor = vaddr; | ||
59 | 46 | ||
60 | for ( ; cursor < vaddr + size; cursor += PAGE_SIZE) { | 47 | void flush_kernel_vmap_range(void *vaddr, int size); |
61 | struct page *page = vmalloc_to_page(cursor); | 48 | void invalidate_kernel_vmap_range(void *vaddr, int size); |
62 | |||
63 | if (test_and_clear_bit(PG_dcache_dirty, &page->flags)) | ||
64 | flush_kernel_dcache_page(page); | ||
65 | } | ||
66 | flush_kernel_dcache_range_asm(start, start + size); | ||
67 | } | ||
68 | 49 | ||
69 | #define flush_cache_vmap(start, end) flush_cache_all() | 50 | #define flush_cache_vmap(start, end) flush_cache_all() |
70 | #define flush_cache_vunmap(start, end) flush_cache_all() | 51 | #define flush_cache_vunmap(start, end) flush_cache_all() |
diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h index fb4382c28259..edfbf9d6a6dd 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h | |||
@@ -32,7 +32,8 @@ | |||
32 | * that put_user is the same as __put_user, etc. | 32 | * that put_user is the same as __put_user, etc. |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #define access_ok(type, uaddr, size) (1) | 35 | #define access_ok(type, uaddr, size) \ |
36 | ( (uaddr) == (uaddr) ) | ||
36 | 37 | ||
37 | #define put_user __put_user | 38 | #define put_user __put_user |
38 | #define get_user __get_user | 39 | #define get_user __get_user |
diff --git a/arch/parisc/include/uapi/asm/unistd.h b/arch/parisc/include/uapi/asm/unistd.h index 6b0741e7a7ed..667c99421003 100644 --- a/arch/parisc/include/uapi/asm/unistd.h +++ b/arch/parisc/include/uapi/asm/unistd.h | |||
@@ -362,8 +362,9 @@ | |||
362 | #define __NR_copy_file_range (__NR_Linux + 346) | 362 | #define __NR_copy_file_range (__NR_Linux + 346) |
363 | #define __NR_preadv2 (__NR_Linux + 347) | 363 | #define __NR_preadv2 (__NR_Linux + 347) |
364 | #define __NR_pwritev2 (__NR_Linux + 348) | 364 | #define __NR_pwritev2 (__NR_Linux + 348) |
365 | #define __NR_statx (__NR_Linux + 349) | ||
365 | 366 | ||
366 | #define __NR_Linux_syscalls (__NR_pwritev2 + 1) | 367 | #define __NR_Linux_syscalls (__NR_statx + 1) |
367 | 368 | ||
368 | 369 | ||
369 | #define __IGNORE_select /* newselect */ | 370 | #define __IGNORE_select /* newselect */ |
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 0dc72d5de861..c32a09095216 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c | |||
@@ -616,3 +616,25 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long | |||
616 | __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn)); | 616 | __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn)); |
617 | } | 617 | } |
618 | } | 618 | } |
619 | |||
620 | void flush_kernel_vmap_range(void *vaddr, int size) | ||
621 | { | ||
622 | unsigned long start = (unsigned long)vaddr; | ||
623 | |||
624 | if ((unsigned long)size > parisc_cache_flush_threshold) | ||
625 | flush_data_cache(); | ||
626 | else | ||
627 | flush_kernel_dcache_range_asm(start, start + size); | ||
628 | } | ||
629 | EXPORT_SYMBOL(flush_kernel_vmap_range); | ||
630 | |||
631 | void invalidate_kernel_vmap_range(void *vaddr, int size) | ||
632 | { | ||
633 | unsigned long start = (unsigned long)vaddr; | ||
634 | |||
635 | if ((unsigned long)size > parisc_cache_flush_threshold) | ||
636 | flush_data_cache(); | ||
637 | else | ||
638 | flush_kernel_dcache_range_asm(start, start + size); | ||
639 | } | ||
640 | EXPORT_SYMBOL(invalidate_kernel_vmap_range); | ||
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index a0ecdb4abcc8..c66c943d9322 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c | |||
@@ -620,6 +620,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, | |||
620 | */ | 620 | */ |
621 | *loc = fsel(val, addend); | 621 | *loc = fsel(val, addend); |
622 | break; | 622 | break; |
623 | case R_PARISC_SECREL32: | ||
624 | /* 32-bit section relative address. */ | ||
625 | *loc = fsel(val, addend); | ||
626 | break; | ||
623 | case R_PARISC_DPREL21L: | 627 | case R_PARISC_DPREL21L: |
624 | /* left 21 bit of relative address */ | 628 | /* left 21 bit of relative address */ |
625 | val = lrsel(val - dp, addend); | 629 | val = lrsel(val - dp, addend); |
@@ -807,6 +811,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, | |||
807 | */ | 811 | */ |
808 | *loc = fsel(val, addend); | 812 | *loc = fsel(val, addend); |
809 | break; | 813 | break; |
814 | case R_PARISC_SECREL32: | ||
815 | /* 32-bit section relative address. */ | ||
816 | *loc = fsel(val, addend); | ||
817 | break; | ||
810 | case R_PARISC_FPTR64: | 818 | case R_PARISC_FPTR64: |
811 | /* 64-bit function address */ | 819 | /* 64-bit function address */ |
812 | if(in_local(me, (void *)(val + addend))) { | 820 | if(in_local(me, (void *)(val + addend))) { |
diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c index e282a5131d77..6017a5af2e6e 100644 --- a/arch/parisc/kernel/perf.c +++ b/arch/parisc/kernel/perf.c | |||
@@ -39,7 +39,7 @@ | |||
39 | * the PDC INTRIGUE calls. This is done to eliminate bugs introduced | 39 | * the PDC INTRIGUE calls. This is done to eliminate bugs introduced |
40 | * in various PDC revisions. The code is much more maintainable | 40 | * in various PDC revisions. The code is much more maintainable |
41 | * and reliable this way vs having to debug on every version of PDC | 41 | * and reliable this way vs having to debug on every version of PDC |
42 | * on every box. | 42 | * on every box. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <linux/capability.h> | 45 | #include <linux/capability.h> |
@@ -195,8 +195,8 @@ static int perf_config(uint32_t *image_ptr); | |||
195 | static int perf_release(struct inode *inode, struct file *file); | 195 | static int perf_release(struct inode *inode, struct file *file); |
196 | static int perf_open(struct inode *inode, struct file *file); | 196 | static int perf_open(struct inode *inode, struct file *file); |
197 | static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos); | 197 | static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos); |
198 | static ssize_t perf_write(struct file *file, const char __user *buf, size_t count, | 198 | static ssize_t perf_write(struct file *file, const char __user *buf, |
199 | loff_t *ppos); | 199 | size_t count, loff_t *ppos); |
200 | static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | 200 | static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
201 | static void perf_start_counters(void); | 201 | static void perf_start_counters(void); |
202 | static int perf_stop_counters(uint32_t *raddr); | 202 | static int perf_stop_counters(uint32_t *raddr); |
@@ -222,7 +222,7 @@ extern void perf_intrigue_disable_perf_counters (void); | |||
222 | /* | 222 | /* |
223 | * configure: | 223 | * configure: |
224 | * | 224 | * |
225 | * Configure the cpu with a given data image. First turn off the counters, | 225 | * Configure the cpu with a given data image. First turn off the counters, |
226 | * then download the image, then turn the counters back on. | 226 | * then download the image, then turn the counters back on. |
227 | */ | 227 | */ |
228 | static int perf_config(uint32_t *image_ptr) | 228 | static int perf_config(uint32_t *image_ptr) |
@@ -234,7 +234,7 @@ static int perf_config(uint32_t *image_ptr) | |||
234 | error = perf_stop_counters(raddr); | 234 | error = perf_stop_counters(raddr); |
235 | if (error != 0) { | 235 | if (error != 0) { |
236 | printk("perf_config: perf_stop_counters = %ld\n", error); | 236 | printk("perf_config: perf_stop_counters = %ld\n", error); |
237 | return -EINVAL; | 237 | return -EINVAL; |
238 | } | 238 | } |
239 | 239 | ||
240 | printk("Preparing to write image\n"); | 240 | printk("Preparing to write image\n"); |
@@ -242,7 +242,7 @@ printk("Preparing to write image\n"); | |||
242 | error = perf_write_image((uint64_t *)image_ptr); | 242 | error = perf_write_image((uint64_t *)image_ptr); |
243 | if (error != 0) { | 243 | if (error != 0) { |
244 | printk("perf_config: DOWNLOAD = %ld\n", error); | 244 | printk("perf_config: DOWNLOAD = %ld\n", error); |
245 | return -EINVAL; | 245 | return -EINVAL; |
246 | } | 246 | } |
247 | 247 | ||
248 | printk("Preparing to start counters\n"); | 248 | printk("Preparing to start counters\n"); |
@@ -254,7 +254,7 @@ printk("Preparing to start counters\n"); | |||
254 | } | 254 | } |
255 | 255 | ||
256 | /* | 256 | /* |
257 | * Open the device and initialize all of its memory. The device is only | 257 | * Open the device and initialize all of its memory. The device is only |
258 | * opened once, but can be "queried" by multiple processes that know its | 258 | * opened once, but can be "queried" by multiple processes that know its |
259 | * file descriptor. | 259 | * file descriptor. |
260 | */ | 260 | */ |
@@ -298,19 +298,19 @@ static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t | |||
298 | * called on the processor that the download should happen | 298 | * called on the processor that the download should happen |
299 | * on. | 299 | * on. |
300 | */ | 300 | */ |
301 | static ssize_t perf_write(struct file *file, const char __user *buf, size_t count, | 301 | static ssize_t perf_write(struct file *file, const char __user *buf, |
302 | loff_t *ppos) | 302 | size_t count, loff_t *ppos) |
303 | { | 303 | { |
304 | size_t image_size; | 304 | size_t image_size; |
305 | uint32_t image_type; | 305 | uint32_t image_type; |
306 | uint32_t interface_type; | 306 | uint32_t interface_type; |
307 | uint32_t test; | 307 | uint32_t test; |
308 | 308 | ||
309 | if (perf_processor_interface == ONYX_INTF) | 309 | if (perf_processor_interface == ONYX_INTF) |
310 | image_size = PCXU_IMAGE_SIZE; | 310 | image_size = PCXU_IMAGE_SIZE; |
311 | else if (perf_processor_interface == CUDA_INTF) | 311 | else if (perf_processor_interface == CUDA_INTF) |
312 | image_size = PCXW_IMAGE_SIZE; | 312 | image_size = PCXW_IMAGE_SIZE; |
313 | else | 313 | else |
314 | return -EFAULT; | 314 | return -EFAULT; |
315 | 315 | ||
316 | if (!capable(CAP_SYS_ADMIN)) | 316 | if (!capable(CAP_SYS_ADMIN)) |
@@ -330,22 +330,22 @@ static ssize_t perf_write(struct file *file, const char __user *buf, size_t coun | |||
330 | 330 | ||
331 | /* First check the machine type is correct for | 331 | /* First check the machine type is correct for |
332 | the requested image */ | 332 | the requested image */ |
333 | if (((perf_processor_interface == CUDA_INTF) && | 333 | if (((perf_processor_interface == CUDA_INTF) && |
334 | (interface_type != CUDA_INTF)) || | 334 | (interface_type != CUDA_INTF)) || |
335 | ((perf_processor_interface == ONYX_INTF) && | 335 | ((perf_processor_interface == ONYX_INTF) && |
336 | (interface_type != ONYX_INTF))) | 336 | (interface_type != ONYX_INTF))) |
337 | return -EINVAL; | 337 | return -EINVAL; |
338 | 338 | ||
339 | /* Next check to make sure the requested image | 339 | /* Next check to make sure the requested image |
340 | is valid */ | 340 | is valid */ |
341 | if (((interface_type == CUDA_INTF) && | 341 | if (((interface_type == CUDA_INTF) && |
342 | (test >= MAX_CUDA_IMAGES)) || | 342 | (test >= MAX_CUDA_IMAGES)) || |
343 | ((interface_type == ONYX_INTF) && | 343 | ((interface_type == ONYX_INTF) && |
344 | (test >= MAX_ONYX_IMAGES))) | 344 | (test >= MAX_ONYX_IMAGES))) |
345 | return -EINVAL; | 345 | return -EINVAL; |
346 | 346 | ||
347 | /* Copy the image into the processor */ | 347 | /* Copy the image into the processor */ |
348 | if (interface_type == CUDA_INTF) | 348 | if (interface_type == CUDA_INTF) |
349 | return perf_config(cuda_images[test]); | 349 | return perf_config(cuda_images[test]); |
350 | else | 350 | else |
351 | return perf_config(onyx_images[test]); | 351 | return perf_config(onyx_images[test]); |
@@ -359,7 +359,7 @@ static ssize_t perf_write(struct file *file, const char __user *buf, size_t coun | |||
359 | static void perf_patch_images(void) | 359 | static void perf_patch_images(void) |
360 | { | 360 | { |
361 | #if 0 /* FIXME!! */ | 361 | #if 0 /* FIXME!! */ |
362 | /* | 362 | /* |
363 | * NOTE: this routine is VERY specific to the current TLB image. | 363 | * NOTE: this routine is VERY specific to the current TLB image. |
364 | * If the image is changed, this routine might also need to be changed. | 364 | * If the image is changed, this routine might also need to be changed. |
365 | */ | 365 | */ |
@@ -367,9 +367,9 @@ static void perf_patch_images(void) | |||
367 | extern void $i_dtlb_miss_2_0(); | 367 | extern void $i_dtlb_miss_2_0(); |
368 | extern void PA2_0_iva(); | 368 | extern void PA2_0_iva(); |
369 | 369 | ||
370 | /* | 370 | /* |
371 | * We can only use the lower 32-bits, the upper 32-bits should be 0 | 371 | * We can only use the lower 32-bits, the upper 32-bits should be 0 |
372 | * anyway given this is in the kernel | 372 | * anyway given this is in the kernel |
373 | */ | 373 | */ |
374 | uint32_t itlb_addr = (uint32_t)&($i_itlb_miss_2_0); | 374 | uint32_t itlb_addr = (uint32_t)&($i_itlb_miss_2_0); |
375 | uint32_t dtlb_addr = (uint32_t)&($i_dtlb_miss_2_0); | 375 | uint32_t dtlb_addr = (uint32_t)&($i_dtlb_miss_2_0); |
@@ -377,21 +377,21 @@ static void perf_patch_images(void) | |||
377 | 377 | ||
378 | if (perf_processor_interface == ONYX_INTF) { | 378 | if (perf_processor_interface == ONYX_INTF) { |
379 | /* clear last 2 bytes */ | 379 | /* clear last 2 bytes */ |
380 | onyx_images[TLBMISS][15] &= 0xffffff00; | 380 | onyx_images[TLBMISS][15] &= 0xffffff00; |
381 | /* set 2 bytes */ | 381 | /* set 2 bytes */ |
382 | onyx_images[TLBMISS][15] |= (0x000000ff&((dtlb_addr) >> 24)); | 382 | onyx_images[TLBMISS][15] |= (0x000000ff&((dtlb_addr) >> 24)); |
383 | onyx_images[TLBMISS][16] = (dtlb_addr << 8)&0xffffff00; | 383 | onyx_images[TLBMISS][16] = (dtlb_addr << 8)&0xffffff00; |
384 | onyx_images[TLBMISS][17] = itlb_addr; | 384 | onyx_images[TLBMISS][17] = itlb_addr; |
385 | 385 | ||
386 | /* clear last 2 bytes */ | 386 | /* clear last 2 bytes */ |
387 | onyx_images[TLBHANDMISS][15] &= 0xffffff00; | 387 | onyx_images[TLBHANDMISS][15] &= 0xffffff00; |
388 | /* set 2 bytes */ | 388 | /* set 2 bytes */ |
389 | onyx_images[TLBHANDMISS][15] |= (0x000000ff&((dtlb_addr) >> 24)); | 389 | onyx_images[TLBHANDMISS][15] |= (0x000000ff&((dtlb_addr) >> 24)); |
390 | onyx_images[TLBHANDMISS][16] = (dtlb_addr << 8)&0xffffff00; | 390 | onyx_images[TLBHANDMISS][16] = (dtlb_addr << 8)&0xffffff00; |
391 | onyx_images[TLBHANDMISS][17] = itlb_addr; | 391 | onyx_images[TLBHANDMISS][17] = itlb_addr; |
392 | 392 | ||
393 | /* clear last 2 bytes */ | 393 | /* clear last 2 bytes */ |
394 | onyx_images[BIG_CPI][15] &= 0xffffff00; | 394 | onyx_images[BIG_CPI][15] &= 0xffffff00; |
395 | /* set 2 bytes */ | 395 | /* set 2 bytes */ |
396 | onyx_images[BIG_CPI][15] |= (0x000000ff&((dtlb_addr) >> 24)); | 396 | onyx_images[BIG_CPI][15] |= (0x000000ff&((dtlb_addr) >> 24)); |
397 | onyx_images[BIG_CPI][16] = (dtlb_addr << 8)&0xffffff00; | 397 | onyx_images[BIG_CPI][16] = (dtlb_addr << 8)&0xffffff00; |
@@ -404,24 +404,24 @@ static void perf_patch_images(void) | |||
404 | 404 | ||
405 | } else if (perf_processor_interface == CUDA_INTF) { | 405 | } else if (perf_processor_interface == CUDA_INTF) { |
406 | /* Cuda interface */ | 406 | /* Cuda interface */ |
407 | cuda_images[TLBMISS][16] = | 407 | cuda_images[TLBMISS][16] = |
408 | (cuda_images[TLBMISS][16]&0xffff0000) | | 408 | (cuda_images[TLBMISS][16]&0xffff0000) | |
409 | ((dtlb_addr >> 8)&0x0000ffff); | 409 | ((dtlb_addr >> 8)&0x0000ffff); |
410 | cuda_images[TLBMISS][17] = | 410 | cuda_images[TLBMISS][17] = |
411 | ((dtlb_addr << 24)&0xff000000) | ((itlb_addr >> 16)&0x000000ff); | 411 | ((dtlb_addr << 24)&0xff000000) | ((itlb_addr >> 16)&0x000000ff); |
412 | cuda_images[TLBMISS][18] = (itlb_addr << 16)&0xffff0000; | 412 | cuda_images[TLBMISS][18] = (itlb_addr << 16)&0xffff0000; |
413 | 413 | ||
414 | cuda_images[TLBHANDMISS][16] = | 414 | cuda_images[TLBHANDMISS][16] = |
415 | (cuda_images[TLBHANDMISS][16]&0xffff0000) | | 415 | (cuda_images[TLBHANDMISS][16]&0xffff0000) | |
416 | ((dtlb_addr >> 8)&0x0000ffff); | 416 | ((dtlb_addr >> 8)&0x0000ffff); |
417 | cuda_images[TLBHANDMISS][17] = | 417 | cuda_images[TLBHANDMISS][17] = |
418 | ((dtlb_addr << 24)&0xff000000) | ((itlb_addr >> 16)&0x000000ff); | 418 | ((dtlb_addr << 24)&0xff000000) | ((itlb_addr >> 16)&0x000000ff); |
419 | cuda_images[TLBHANDMISS][18] = (itlb_addr << 16)&0xffff0000; | 419 | cuda_images[TLBHANDMISS][18] = (itlb_addr << 16)&0xffff0000; |
420 | 420 | ||
421 | cuda_images[BIG_CPI][16] = | 421 | cuda_images[BIG_CPI][16] = |
422 | (cuda_images[BIG_CPI][16]&0xffff0000) | | 422 | (cuda_images[BIG_CPI][16]&0xffff0000) | |
423 | ((dtlb_addr >> 8)&0x0000ffff); | 423 | ((dtlb_addr >> 8)&0x0000ffff); |
424 | cuda_images[BIG_CPI][17] = | 424 | cuda_images[BIG_CPI][17] = |
425 | ((dtlb_addr << 24)&0xff000000) | ((itlb_addr >> 16)&0x000000ff); | 425 | ((dtlb_addr << 24)&0xff000000) | ((itlb_addr >> 16)&0x000000ff); |
426 | cuda_images[BIG_CPI][18] = (itlb_addr << 16)&0xffff0000; | 426 | cuda_images[BIG_CPI][18] = (itlb_addr << 16)&0xffff0000; |
427 | } else { | 427 | } else { |
@@ -433,7 +433,7 @@ static void perf_patch_images(void) | |||
433 | 433 | ||
434 | /* | 434 | /* |
435 | * ioctl routine | 435 | * ioctl routine |
436 | * All routines effect the processor that they are executed on. Thus you | 436 | * All routines effect the processor that they are executed on. Thus you |
437 | * must be running on the processor that you wish to change. | 437 | * must be running on the processor that you wish to change. |
438 | */ | 438 | */ |
439 | 439 | ||
@@ -459,7 +459,7 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
459 | } | 459 | } |
460 | 460 | ||
461 | /* copy out the Counters */ | 461 | /* copy out the Counters */ |
462 | if (copy_to_user((void __user *)arg, raddr, | 462 | if (copy_to_user((void __user *)arg, raddr, |
463 | sizeof (raddr)) != 0) { | 463 | sizeof (raddr)) != 0) { |
464 | error = -EFAULT; | 464 | error = -EFAULT; |
465 | break; | 465 | break; |
@@ -487,7 +487,7 @@ static const struct file_operations perf_fops = { | |||
487 | .open = perf_open, | 487 | .open = perf_open, |
488 | .release = perf_release | 488 | .release = perf_release |
489 | }; | 489 | }; |
490 | 490 | ||
491 | static struct miscdevice perf_dev = { | 491 | static struct miscdevice perf_dev = { |
492 | MISC_DYNAMIC_MINOR, | 492 | MISC_DYNAMIC_MINOR, |
493 | PA_PERF_DEV, | 493 | PA_PERF_DEV, |
@@ -595,7 +595,7 @@ static int perf_stop_counters(uint32_t *raddr) | |||
595 | /* OR sticky2 (bit 1496) to counter2 bit 32 */ | 595 | /* OR sticky2 (bit 1496) to counter2 bit 32 */ |
596 | tmp64 |= (userbuf[23] >> 8) & 0x0000000080000000; | 596 | tmp64 |= (userbuf[23] >> 8) & 0x0000000080000000; |
597 | raddr[2] = (uint32_t)tmp64; | 597 | raddr[2] = (uint32_t)tmp64; |
598 | 598 | ||
599 | /* Counter3 is bits 1497 to 1528 */ | 599 | /* Counter3 is bits 1497 to 1528 */ |
600 | tmp64 = (userbuf[23] >> 7) & 0x00000000ffffffff; | 600 | tmp64 = (userbuf[23] >> 7) & 0x00000000ffffffff; |
601 | /* OR sticky3 (bit 1529) to counter3 bit 32 */ | 601 | /* OR sticky3 (bit 1529) to counter3 bit 32 */ |
@@ -617,7 +617,7 @@ static int perf_stop_counters(uint32_t *raddr) | |||
617 | userbuf[22] = 0; | 617 | userbuf[22] = 0; |
618 | userbuf[23] = 0; | 618 | userbuf[23] = 0; |
619 | 619 | ||
620 | /* | 620 | /* |
621 | * Write back the zeroed bytes + the image given | 621 | * Write back the zeroed bytes + the image given |
622 | * the read was destructive. | 622 | * the read was destructive. |
623 | */ | 623 | */ |
@@ -625,13 +625,13 @@ static int perf_stop_counters(uint32_t *raddr) | |||
625 | } else { | 625 | } else { |
626 | 626 | ||
627 | /* | 627 | /* |
628 | * Read RDR-15 which contains the counters and sticky bits | 628 | * Read RDR-15 which contains the counters and sticky bits |
629 | */ | 629 | */ |
630 | if (!perf_rdr_read_ubuf(15, userbuf)) { | 630 | if (!perf_rdr_read_ubuf(15, userbuf)) { |
631 | return -13; | 631 | return -13; |
632 | } | 632 | } |
633 | 633 | ||
634 | /* | 634 | /* |
635 | * Clear out the counters | 635 | * Clear out the counters |
636 | */ | 636 | */ |
637 | perf_rdr_clear(15); | 637 | perf_rdr_clear(15); |
@@ -644,7 +644,7 @@ static int perf_stop_counters(uint32_t *raddr) | |||
644 | raddr[2] = (uint32_t)((userbuf[1] >> 32) & 0x00000000ffffffffUL); | 644 | raddr[2] = (uint32_t)((userbuf[1] >> 32) & 0x00000000ffffffffUL); |
645 | raddr[3] = (uint32_t)(userbuf[1] & 0x00000000ffffffffUL); | 645 | raddr[3] = (uint32_t)(userbuf[1] & 0x00000000ffffffffUL); |
646 | } | 646 | } |
647 | 647 | ||
648 | return 0; | 648 | return 0; |
649 | } | 649 | } |
650 | 650 | ||
@@ -682,7 +682,7 @@ static int perf_rdr_read_ubuf(uint32_t rdr_num, uint64_t *buffer) | |||
682 | i = tentry->num_words; | 682 | i = tentry->num_words; |
683 | while (i--) { | 683 | while (i--) { |
684 | buffer[i] = 0; | 684 | buffer[i] = 0; |
685 | } | 685 | } |
686 | 686 | ||
687 | /* Check for bits an even number of 64 */ | 687 | /* Check for bits an even number of 64 */ |
688 | if ((xbits = width & 0x03f) != 0) { | 688 | if ((xbits = width & 0x03f) != 0) { |
@@ -808,18 +808,22 @@ static int perf_write_image(uint64_t *memaddr) | |||
808 | } | 808 | } |
809 | 809 | ||
810 | runway = ioremap_nocache(cpu_device->hpa.start, 4096); | 810 | runway = ioremap_nocache(cpu_device->hpa.start, 4096); |
811 | if (!runway) { | ||
812 | pr_err("perf_write_image: ioremap failed!\n"); | ||
813 | return -ENOMEM; | ||
814 | } | ||
811 | 815 | ||
812 | /* Merge intrigue bits into Runway STATUS 0 */ | 816 | /* Merge intrigue bits into Runway STATUS 0 */ |
813 | tmp64 = __raw_readq(runway + RUNWAY_STATUS) & 0xffecfffffffffffful; | 817 | tmp64 = __raw_readq(runway + RUNWAY_STATUS) & 0xffecfffffffffffful; |
814 | __raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000ul), | 818 | __raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000ul), |
815 | runway + RUNWAY_STATUS); | 819 | runway + RUNWAY_STATUS); |
816 | 820 | ||
817 | /* Write RUNWAY DEBUG registers */ | 821 | /* Write RUNWAY DEBUG registers */ |
818 | for (i = 0; i < 8; i++) { | 822 | for (i = 0; i < 8; i++) { |
819 | __raw_writeq(*memaddr++, runway + RUNWAY_DEBUG); | 823 | __raw_writeq(*memaddr++, runway + RUNWAY_DEBUG); |
820 | } | 824 | } |
821 | 825 | ||
822 | return 0; | 826 | return 0; |
823 | } | 827 | } |
824 | 828 | ||
825 | /* | 829 | /* |
@@ -843,7 +847,7 @@ printk("perf_rdr_write\n"); | |||
843 | perf_rdr_shift_out_U(rdr_num, buffer[i]); | 847 | perf_rdr_shift_out_U(rdr_num, buffer[i]); |
844 | } else { | 848 | } else { |
845 | perf_rdr_shift_out_W(rdr_num, buffer[i]); | 849 | perf_rdr_shift_out_W(rdr_num, buffer[i]); |
846 | } | 850 | } |
847 | } | 851 | } |
848 | printk("perf_rdr_write done\n"); | 852 | printk("perf_rdr_write done\n"); |
849 | } | 853 | } |
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 06f7ca7fe70b..b76f503eee4a 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c | |||
@@ -142,6 +142,8 @@ void machine_power_off(void) | |||
142 | 142 | ||
143 | printk(KERN_EMERG "System shut down completed.\n" | 143 | printk(KERN_EMERG "System shut down completed.\n" |
144 | "Please power this system off now."); | 144 | "Please power this system off now."); |
145 | |||
146 | for (;;); | ||
145 | } | 147 | } |
146 | 148 | ||
147 | void (*pm_power_off)(void) = machine_power_off; | 149 | void (*pm_power_off)(void) = machine_power_off; |
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 3cfef1de8061..44aeaa9c039f 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S | |||
@@ -444,6 +444,7 @@ | |||
444 | ENTRY_SAME(copy_file_range) | 444 | ENTRY_SAME(copy_file_range) |
445 | ENTRY_COMP(preadv2) | 445 | ENTRY_COMP(preadv2) |
446 | ENTRY_COMP(pwritev2) | 446 | ENTRY_COMP(pwritev2) |
447 | ENTRY_SAME(statx) | ||
447 | 448 | ||
448 | 449 | ||
449 | .ifne (. - 90b) - (__NR_Linux_syscalls * (91b - 90b)) | 450 | .ifne (. - 90b) - (__NR_Linux_syscalls * (91b - 90b)) |
diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S index 861e72109df2..f080abfc2f83 100644 --- a/arch/powerpc/boot/zImage.lds.S +++ b/arch/powerpc/boot/zImage.lds.S | |||
@@ -68,6 +68,7 @@ SECTIONS | |||
68 | } | 68 | } |
69 | 69 | ||
70 | #ifdef CONFIG_PPC64_BOOT_WRAPPER | 70 | #ifdef CONFIG_PPC64_BOOT_WRAPPER |
71 | . = ALIGN(256); | ||
71 | .got : | 72 | .got : |
72 | { | 73 | { |
73 | __toc_start = .; | 74 | __toc_start = .; |
diff --git a/arch/powerpc/crypto/crc32c-vpmsum_glue.c b/arch/powerpc/crypto/crc32c-vpmsum_glue.c index 9fa046d56eba..411994551afc 100644 --- a/arch/powerpc/crypto/crc32c-vpmsum_glue.c +++ b/arch/powerpc/crypto/crc32c-vpmsum_glue.c | |||
@@ -52,7 +52,7 @@ static int crc32c_vpmsum_cra_init(struct crypto_tfm *tfm) | |||
52 | { | 52 | { |
53 | u32 *key = crypto_tfm_ctx(tfm); | 53 | u32 *key = crypto_tfm_ctx(tfm); |
54 | 54 | ||
55 | *key = 0; | 55 | *key = ~0; |
56 | 56 | ||
57 | return 0; | 57 | return 0; |
58 | } | 58 | } |
diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h index 73eb794d6163..bc5fdfd22788 100644 --- a/arch/powerpc/include/asm/bitops.h +++ b/arch/powerpc/include/asm/bitops.h | |||
@@ -51,6 +51,10 @@ | |||
51 | #define PPC_BIT(bit) (1UL << PPC_BITLSHIFT(bit)) | 51 | #define PPC_BIT(bit) (1UL << PPC_BITLSHIFT(bit)) |
52 | #define PPC_BITMASK(bs, be) ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs)) | 52 | #define PPC_BITMASK(bs, be) ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs)) |
53 | 53 | ||
54 | /* Put a PPC bit into a "normal" bit position */ | ||
55 | #define PPC_BITEXTRACT(bits, ppc_bit, dst_bit) \ | ||
56 | ((((bits) >> PPC_BITLSHIFT(ppc_bit)) & 1) << (dst_bit)) | ||
57 | |||
54 | #include <asm/barrier.h> | 58 | #include <asm/barrier.h> |
55 | 59 | ||
56 | /* Macro for generating the ***_bits() functions */ | 60 | /* Macro for generating the ***_bits() functions */ |
diff --git a/arch/powerpc/include/asm/mce.h b/arch/powerpc/include/asm/mce.h index f97d8cb6bdf6..ed62efe01e49 100644 --- a/arch/powerpc/include/asm/mce.h +++ b/arch/powerpc/include/asm/mce.h | |||
@@ -66,6 +66,55 @@ | |||
66 | 66 | ||
67 | #define P8_DSISR_MC_SLB_ERRORS (P7_DSISR_MC_SLB_ERRORS | \ | 67 | #define P8_DSISR_MC_SLB_ERRORS (P7_DSISR_MC_SLB_ERRORS | \ |
68 | P8_DSISR_MC_ERAT_MULTIHIT_SEC) | 68 | P8_DSISR_MC_ERAT_MULTIHIT_SEC) |
69 | |||
70 | /* | ||
71 | * Machine Check bits on power9 | ||
72 | */ | ||
73 | #define P9_SRR1_MC_LOADSTORE(srr1) (((srr1) >> PPC_BITLSHIFT(42)) & 1) | ||
74 | |||
75 | #define P9_SRR1_MC_IFETCH(srr1) ( \ | ||
76 | PPC_BITEXTRACT(srr1, 45, 0) | \ | ||
77 | PPC_BITEXTRACT(srr1, 44, 1) | \ | ||
78 | PPC_BITEXTRACT(srr1, 43, 2) | \ | ||
79 | PPC_BITEXTRACT(srr1, 36, 3) ) | ||
80 | |||
81 | /* 0 is reserved */ | ||
82 | #define P9_SRR1_MC_IFETCH_UE 1 | ||
83 | #define P9_SRR1_MC_IFETCH_SLB_PARITY 2 | ||
84 | #define P9_SRR1_MC_IFETCH_SLB_MULTIHIT 3 | ||
85 | #define P9_SRR1_MC_IFETCH_ERAT_MULTIHIT 4 | ||
86 | #define P9_SRR1_MC_IFETCH_TLB_MULTIHIT 5 | ||
87 | #define P9_SRR1_MC_IFETCH_UE_TLB_RELOAD 6 | ||
88 | /* 7 is reserved */ | ||
89 | #define P9_SRR1_MC_IFETCH_LINK_TIMEOUT 8 | ||
90 | #define P9_SRR1_MC_IFETCH_LINK_TABLEWALK_TIMEOUT 9 | ||
91 | /* 10 ? */ | ||
92 | #define P9_SRR1_MC_IFETCH_RA 11 | ||
93 | #define P9_SRR1_MC_IFETCH_RA_TABLEWALK 12 | ||
94 | #define P9_SRR1_MC_IFETCH_RA_ASYNC_STORE 13 | ||
95 | #define P9_SRR1_MC_IFETCH_LINK_ASYNC_STORE_TIMEOUT 14 | ||
96 | #define P9_SRR1_MC_IFETCH_RA_TABLEWALK_FOREIGN 15 | ||
97 | |||
98 | /* DSISR bits for machine check (On Power9) */ | ||
99 | #define P9_DSISR_MC_UE (PPC_BIT(48)) | ||
100 | #define P9_DSISR_MC_UE_TABLEWALK (PPC_BIT(49)) | ||
101 | #define P9_DSISR_MC_LINK_LOAD_TIMEOUT (PPC_BIT(50)) | ||
102 | #define P9_DSISR_MC_LINK_TABLEWALK_TIMEOUT (PPC_BIT(51)) | ||
103 | #define P9_DSISR_MC_ERAT_MULTIHIT (PPC_BIT(52)) | ||
104 | #define P9_DSISR_MC_TLB_MULTIHIT_MFTLB (PPC_BIT(53)) | ||
105 | #define P9_DSISR_MC_USER_TLBIE (PPC_BIT(54)) | ||
106 | #define P9_DSISR_MC_SLB_PARITY_MFSLB (PPC_BIT(55)) | ||
107 | #define P9_DSISR_MC_SLB_MULTIHIT_MFSLB (PPC_BIT(56)) | ||
108 | #define P9_DSISR_MC_RA_LOAD (PPC_BIT(57)) | ||
109 | #define P9_DSISR_MC_RA_TABLEWALK (PPC_BIT(58)) | ||
110 | #define P9_DSISR_MC_RA_TABLEWALK_FOREIGN (PPC_BIT(59)) | ||
111 | #define P9_DSISR_MC_RA_FOREIGN (PPC_BIT(60)) | ||
112 | |||
113 | /* SLB error bits */ | ||
114 | #define P9_DSISR_MC_SLB_ERRORS (P9_DSISR_MC_ERAT_MULTIHIT | \ | ||
115 | P9_DSISR_MC_SLB_PARITY_MFSLB | \ | ||
116 | P9_DSISR_MC_SLB_MULTIHIT_MFSLB) | ||
117 | |||
69 | enum MCE_Version { | 118 | enum MCE_Version { |
70 | MCE_V1 = 1, | 119 | MCE_V1 = 1, |
71 | }; | 120 | }; |
@@ -93,6 +142,9 @@ enum MCE_ErrorType { | |||
93 | MCE_ERROR_TYPE_SLB = 2, | 142 | MCE_ERROR_TYPE_SLB = 2, |
94 | MCE_ERROR_TYPE_ERAT = 3, | 143 | MCE_ERROR_TYPE_ERAT = 3, |
95 | MCE_ERROR_TYPE_TLB = 4, | 144 | MCE_ERROR_TYPE_TLB = 4, |
145 | MCE_ERROR_TYPE_USER = 5, | ||
146 | MCE_ERROR_TYPE_RA = 6, | ||
147 | MCE_ERROR_TYPE_LINK = 7, | ||
96 | }; | 148 | }; |
97 | 149 | ||
98 | enum MCE_UeErrorType { | 150 | enum MCE_UeErrorType { |
@@ -121,6 +173,32 @@ enum MCE_TlbErrorType { | |||
121 | MCE_TLB_ERROR_MULTIHIT = 2, | 173 | MCE_TLB_ERROR_MULTIHIT = 2, |
122 | }; | 174 | }; |
123 | 175 | ||
176 | enum MCE_UserErrorType { | ||
177 | MCE_USER_ERROR_INDETERMINATE = 0, | ||
178 | MCE_USER_ERROR_TLBIE = 1, | ||
179 | }; | ||
180 | |||
181 | enum MCE_RaErrorType { | ||
182 | MCE_RA_ERROR_INDETERMINATE = 0, | ||
183 | MCE_RA_ERROR_IFETCH = 1, | ||
184 | MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH = 2, | ||
185 | MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH_FOREIGN = 3, | ||
186 | MCE_RA_ERROR_LOAD = 4, | ||
187 | MCE_RA_ERROR_STORE = 5, | ||
188 | MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE = 6, | ||
189 | MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE_FOREIGN = 7, | ||
190 | MCE_RA_ERROR_LOAD_STORE_FOREIGN = 8, | ||
191 | }; | ||
192 | |||
193 | enum MCE_LinkErrorType { | ||
194 | MCE_LINK_ERROR_INDETERMINATE = 0, | ||
195 | MCE_LINK_ERROR_IFETCH_TIMEOUT = 1, | ||
196 | MCE_LINK_ERROR_PAGE_TABLE_WALK_IFETCH_TIMEOUT = 2, | ||
197 | MCE_LINK_ERROR_LOAD_TIMEOUT = 3, | ||
198 | MCE_LINK_ERROR_STORE_TIMEOUT = 4, | ||
199 | MCE_LINK_ERROR_PAGE_TABLE_WALK_LOAD_STORE_TIMEOUT = 5, | ||
200 | }; | ||
201 | |||
124 | struct machine_check_event { | 202 | struct machine_check_event { |
125 | enum MCE_Version version:8; /* 0x00 */ | 203 | enum MCE_Version version:8; /* 0x00 */ |
126 | uint8_t in_use; /* 0x01 */ | 204 | uint8_t in_use; /* 0x01 */ |
@@ -166,6 +244,30 @@ struct machine_check_event { | |||
166 | uint64_t effective_address; | 244 | uint64_t effective_address; |
167 | uint8_t reserved_2[16]; | 245 | uint8_t reserved_2[16]; |
168 | } tlb_error; | 246 | } tlb_error; |
247 | |||
248 | struct { | ||
249 | enum MCE_UserErrorType user_error_type:8; | ||
250 | uint8_t effective_address_provided; | ||
251 | uint8_t reserved_1[6]; | ||
252 | uint64_t effective_address; | ||
253 | uint8_t reserved_2[16]; | ||
254 | } user_error; | ||
255 | |||
256 | struct { | ||
257 | enum MCE_RaErrorType ra_error_type:8; | ||
258 | uint8_t effective_address_provided; | ||
259 | uint8_t reserved_1[6]; | ||
260 | uint64_t effective_address; | ||
261 | uint8_t reserved_2[16]; | ||
262 | } ra_error; | ||
263 | |||
264 | struct { | ||
265 | enum MCE_LinkErrorType link_error_type:8; | ||
266 | uint8_t effective_address_provided; | ||
267 | uint8_t reserved_1[6]; | ||
268 | uint64_t effective_address; | ||
269 | uint8_t reserved_2[16]; | ||
270 | } link_error; | ||
169 | } u; | 271 | } u; |
170 | }; | 272 | }; |
171 | 273 | ||
@@ -176,8 +278,12 @@ struct mce_error_info { | |||
176 | enum MCE_SlbErrorType slb_error_type:8; | 278 | enum MCE_SlbErrorType slb_error_type:8; |
177 | enum MCE_EratErrorType erat_error_type:8; | 279 | enum MCE_EratErrorType erat_error_type:8; |
178 | enum MCE_TlbErrorType tlb_error_type:8; | 280 | enum MCE_TlbErrorType tlb_error_type:8; |
281 | enum MCE_UserErrorType user_error_type:8; | ||
282 | enum MCE_RaErrorType ra_error_type:8; | ||
283 | enum MCE_LinkErrorType link_error_type:8; | ||
179 | } u; | 284 | } u; |
180 | uint8_t reserved[2]; | 285 | enum MCE_Severity severity:8; |
286 | enum MCE_Initiator initiator:8; | ||
181 | }; | 287 | }; |
182 | 288 | ||
183 | #define MAX_MC_EVT 100 | 289 | #define MAX_MC_EVT 100 |
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 4b369d83fe9c..1c9470881c4a 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h | |||
@@ -387,3 +387,4 @@ SYSCALL(copy_file_range) | |||
387 | COMPAT_SYS_SPU(preadv2) | 387 | COMPAT_SYS_SPU(preadv2) |
388 | COMPAT_SYS_SPU(pwritev2) | 388 | COMPAT_SYS_SPU(pwritev2) |
389 | SYSCALL(kexec_file_load) | 389 | SYSCALL(kexec_file_load) |
390 | SYSCALL(statx) | ||
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index eb1acee91a20..9ba11dbcaca9 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <uapi/asm/unistd.h> | 12 | #include <uapi/asm/unistd.h> |
13 | 13 | ||
14 | 14 | ||
15 | #define NR_syscalls 383 | 15 | #define NR_syscalls 384 |
16 | 16 | ||
17 | #define __NR__exit __NR_exit | 17 | #define __NR__exit __NR_exit |
18 | 18 | ||
diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h index 2f26335a3c42..b85f14228857 100644 --- a/arch/powerpc/include/uapi/asm/unistd.h +++ b/arch/powerpc/include/uapi/asm/unistd.h | |||
@@ -393,5 +393,6 @@ | |||
393 | #define __NR_preadv2 380 | 393 | #define __NR_preadv2 380 |
394 | #define __NR_pwritev2 381 | 394 | #define __NR_pwritev2 381 |
395 | #define __NR_kexec_file_load 382 | 395 | #define __NR_kexec_file_load 382 |
396 | #define __NR_statx 383 | ||
396 | 397 | ||
397 | #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ | 398 | #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index bb7a1890aeb7..e79b9daa873c 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -77,6 +77,7 @@ extern void __flush_tlb_power8(unsigned int action); | |||
77 | extern void __flush_tlb_power9(unsigned int action); | 77 | extern void __flush_tlb_power9(unsigned int action); |
78 | extern long __machine_check_early_realmode_p7(struct pt_regs *regs); | 78 | extern long __machine_check_early_realmode_p7(struct pt_regs *regs); |
79 | extern long __machine_check_early_realmode_p8(struct pt_regs *regs); | 79 | extern long __machine_check_early_realmode_p8(struct pt_regs *regs); |
80 | extern long __machine_check_early_realmode_p9(struct pt_regs *regs); | ||
80 | #endif /* CONFIG_PPC64 */ | 81 | #endif /* CONFIG_PPC64 */ |
81 | #if defined(CONFIG_E500) | 82 | #if defined(CONFIG_E500) |
82 | extern void __setup_cpu_e5500(unsigned long offset, struct cpu_spec* spec); | 83 | extern void __setup_cpu_e5500(unsigned long offset, struct cpu_spec* spec); |
@@ -540,6 +541,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
540 | .cpu_setup = __setup_cpu_power9, | 541 | .cpu_setup = __setup_cpu_power9, |
541 | .cpu_restore = __restore_cpu_power9, | 542 | .cpu_restore = __restore_cpu_power9, |
542 | .flush_tlb = __flush_tlb_power9, | 543 | .flush_tlb = __flush_tlb_power9, |
544 | .machine_check_early = __machine_check_early_realmode_p9, | ||
543 | .platform = "power9", | 545 | .platform = "power9", |
544 | }, | 546 | }, |
545 | { /* Power9 */ | 547 | { /* Power9 */ |
@@ -559,6 +561,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
559 | .cpu_setup = __setup_cpu_power9, | 561 | .cpu_setup = __setup_cpu_power9, |
560 | .cpu_restore = __restore_cpu_power9, | 562 | .cpu_restore = __restore_cpu_power9, |
561 | .flush_tlb = __flush_tlb_power9, | 563 | .flush_tlb = __flush_tlb_power9, |
564 | .machine_check_early = __machine_check_early_realmode_p9, | ||
562 | .platform = "power9", | 565 | .platform = "power9", |
563 | }, | 566 | }, |
564 | { /* Cell Broadband Engine */ | 567 | { /* Cell Broadband Engine */ |
diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c index c6923ff45131..a1475e6aef3a 100644 --- a/arch/powerpc/kernel/mce.c +++ b/arch/powerpc/kernel/mce.c | |||
@@ -58,6 +58,15 @@ static void mce_set_error_info(struct machine_check_event *mce, | |||
58 | case MCE_ERROR_TYPE_TLB: | 58 | case MCE_ERROR_TYPE_TLB: |
59 | mce->u.tlb_error.tlb_error_type = mce_err->u.tlb_error_type; | 59 | mce->u.tlb_error.tlb_error_type = mce_err->u.tlb_error_type; |
60 | break; | 60 | break; |
61 | case MCE_ERROR_TYPE_USER: | ||
62 | mce->u.user_error.user_error_type = mce_err->u.user_error_type; | ||
63 | break; | ||
64 | case MCE_ERROR_TYPE_RA: | ||
65 | mce->u.ra_error.ra_error_type = mce_err->u.ra_error_type; | ||
66 | break; | ||
67 | case MCE_ERROR_TYPE_LINK: | ||
68 | mce->u.link_error.link_error_type = mce_err->u.link_error_type; | ||
69 | break; | ||
61 | case MCE_ERROR_TYPE_UNKNOWN: | 70 | case MCE_ERROR_TYPE_UNKNOWN: |
62 | default: | 71 | default: |
63 | break; | 72 | break; |
@@ -90,13 +99,14 @@ void save_mce_event(struct pt_regs *regs, long handled, | |||
90 | mce->gpr3 = regs->gpr[3]; | 99 | mce->gpr3 = regs->gpr[3]; |
91 | mce->in_use = 1; | 100 | mce->in_use = 1; |
92 | 101 | ||
93 | mce->initiator = MCE_INITIATOR_CPU; | ||
94 | /* Mark it recovered if we have handled it and MSR(RI=1). */ | 102 | /* Mark it recovered if we have handled it and MSR(RI=1). */ |
95 | if (handled && (regs->msr & MSR_RI)) | 103 | if (handled && (regs->msr & MSR_RI)) |
96 | mce->disposition = MCE_DISPOSITION_RECOVERED; | 104 | mce->disposition = MCE_DISPOSITION_RECOVERED; |
97 | else | 105 | else |
98 | mce->disposition = MCE_DISPOSITION_NOT_RECOVERED; | 106 | mce->disposition = MCE_DISPOSITION_NOT_RECOVERED; |
99 | mce->severity = MCE_SEV_ERROR_SYNC; | 107 | |
108 | mce->initiator = mce_err->initiator; | ||
109 | mce->severity = mce_err->severity; | ||
100 | 110 | ||
101 | /* | 111 | /* |
102 | * Populate the mce error_type and type-specific error_type. | 112 | * Populate the mce error_type and type-specific error_type. |
@@ -115,6 +125,15 @@ void save_mce_event(struct pt_regs *regs, long handled, | |||
115 | } else if (mce->error_type == MCE_ERROR_TYPE_ERAT) { | 125 | } else if (mce->error_type == MCE_ERROR_TYPE_ERAT) { |
116 | mce->u.erat_error.effective_address_provided = true; | 126 | mce->u.erat_error.effective_address_provided = true; |
117 | mce->u.erat_error.effective_address = addr; | 127 | mce->u.erat_error.effective_address = addr; |
128 | } else if (mce->error_type == MCE_ERROR_TYPE_USER) { | ||
129 | mce->u.user_error.effective_address_provided = true; | ||
130 | mce->u.user_error.effective_address = addr; | ||
131 | } else if (mce->error_type == MCE_ERROR_TYPE_RA) { | ||
132 | mce->u.ra_error.effective_address_provided = true; | ||
133 | mce->u.ra_error.effective_address = addr; | ||
134 | } else if (mce->error_type == MCE_ERROR_TYPE_LINK) { | ||
135 | mce->u.link_error.effective_address_provided = true; | ||
136 | mce->u.link_error.effective_address = addr; | ||
118 | } else if (mce->error_type == MCE_ERROR_TYPE_UE) { | 137 | } else if (mce->error_type == MCE_ERROR_TYPE_UE) { |
119 | mce->u.ue_error.effective_address_provided = true; | 138 | mce->u.ue_error.effective_address_provided = true; |
120 | mce->u.ue_error.effective_address = addr; | 139 | mce->u.ue_error.effective_address = addr; |
@@ -239,6 +258,29 @@ void machine_check_print_event_info(struct machine_check_event *evt) | |||
239 | "Parity", | 258 | "Parity", |
240 | "Multihit", | 259 | "Multihit", |
241 | }; | 260 | }; |
261 | static const char *mc_user_types[] = { | ||
262 | "Indeterminate", | ||
263 | "tlbie(l) invalid", | ||
264 | }; | ||
265 | static const char *mc_ra_types[] = { | ||
266 | "Indeterminate", | ||
267 | "Instruction fetch (bad)", | ||
268 | "Page table walk ifetch (bad)", | ||
269 | "Page table walk ifetch (foreign)", | ||
270 | "Load (bad)", | ||
271 | "Store (bad)", | ||
272 | "Page table walk Load/Store (bad)", | ||
273 | "Page table walk Load/Store (foreign)", | ||
274 | "Load/Store (foreign)", | ||
275 | }; | ||
276 | static const char *mc_link_types[] = { | ||
277 | "Indeterminate", | ||
278 | "Instruction fetch (timeout)", | ||
279 | "Page table walk ifetch (timeout)", | ||
280 | "Load (timeout)", | ||
281 | "Store (timeout)", | ||
282 | "Page table walk Load/Store (timeout)", | ||
283 | }; | ||
242 | 284 | ||
243 | /* Print things out */ | 285 | /* Print things out */ |
244 | if (evt->version != MCE_V1) { | 286 | if (evt->version != MCE_V1) { |
@@ -315,6 +357,36 @@ void machine_check_print_event_info(struct machine_check_event *evt) | |||
315 | printk("%s Effective address: %016llx\n", | 357 | printk("%s Effective address: %016llx\n", |
316 | level, evt->u.tlb_error.effective_address); | 358 | level, evt->u.tlb_error.effective_address); |
317 | break; | 359 | break; |
360 | case MCE_ERROR_TYPE_USER: | ||
361 | subtype = evt->u.user_error.user_error_type < | ||
362 | ARRAY_SIZE(mc_user_types) ? | ||
363 | mc_user_types[evt->u.user_error.user_error_type] | ||
364 | : "Unknown"; | ||
365 | printk("%s Error type: User [%s]\n", level, subtype); | ||
366 | if (evt->u.user_error.effective_address_provided) | ||
367 | printk("%s Effective address: %016llx\n", | ||
368 | level, evt->u.user_error.effective_address); | ||
369 | break; | ||
370 | case MCE_ERROR_TYPE_RA: | ||
371 | subtype = evt->u.ra_error.ra_error_type < | ||
372 | ARRAY_SIZE(mc_ra_types) ? | ||
373 | mc_ra_types[evt->u.ra_error.ra_error_type] | ||
374 | : "Unknown"; | ||
375 | printk("%s Error type: Real address [%s]\n", level, subtype); | ||
376 | if (evt->u.ra_error.effective_address_provided) | ||
377 | printk("%s Effective address: %016llx\n", | ||
378 | level, evt->u.ra_error.effective_address); | ||
379 | break; | ||
380 | case MCE_ERROR_TYPE_LINK: | ||
381 | subtype = evt->u.link_error.link_error_type < | ||
382 | ARRAY_SIZE(mc_link_types) ? | ||
383 | mc_link_types[evt->u.link_error.link_error_type] | ||
384 | : "Unknown"; | ||
385 | printk("%s Error type: Link [%s]\n", level, subtype); | ||
386 | if (evt->u.link_error.effective_address_provided) | ||
387 | printk("%s Effective address: %016llx\n", | ||
388 | level, evt->u.link_error.effective_address); | ||
389 | break; | ||
318 | default: | 390 | default: |
319 | case MCE_ERROR_TYPE_UNKNOWN: | 391 | case MCE_ERROR_TYPE_UNKNOWN: |
320 | printk("%s Error type: Unknown\n", level); | 392 | printk("%s Error type: Unknown\n", level); |
@@ -341,6 +413,18 @@ uint64_t get_mce_fault_addr(struct machine_check_event *evt) | |||
341 | if (evt->u.tlb_error.effective_address_provided) | 413 | if (evt->u.tlb_error.effective_address_provided) |
342 | return evt->u.tlb_error.effective_address; | 414 | return evt->u.tlb_error.effective_address; |
343 | break; | 415 | break; |
416 | case MCE_ERROR_TYPE_USER: | ||
417 | if (evt->u.user_error.effective_address_provided) | ||
418 | return evt->u.user_error.effective_address; | ||
419 | break; | ||
420 | case MCE_ERROR_TYPE_RA: | ||
421 | if (evt->u.ra_error.effective_address_provided) | ||
422 | return evt->u.ra_error.effective_address; | ||
423 | break; | ||
424 | case MCE_ERROR_TYPE_LINK: | ||
425 | if (evt->u.link_error.effective_address_provided) | ||
426 | return evt->u.link_error.effective_address; | ||
427 | break; | ||
344 | default: | 428 | default: |
345 | case MCE_ERROR_TYPE_UNKNOWN: | 429 | case MCE_ERROR_TYPE_UNKNOWN: |
346 | break; | 430 | break; |
diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c index 7353991c4ece..763d6f58caa8 100644 --- a/arch/powerpc/kernel/mce_power.c +++ b/arch/powerpc/kernel/mce_power.c | |||
@@ -116,6 +116,51 @@ static void flush_and_reload_slb(void) | |||
116 | } | 116 | } |
117 | #endif | 117 | #endif |
118 | 118 | ||
119 | static void flush_erat(void) | ||
120 | { | ||
121 | asm volatile(PPC_INVALIDATE_ERAT : : :"memory"); | ||
122 | } | ||
123 | |||
124 | #define MCE_FLUSH_SLB 1 | ||
125 | #define MCE_FLUSH_TLB 2 | ||
126 | #define MCE_FLUSH_ERAT 3 | ||
127 | |||
128 | static int mce_flush(int what) | ||
129 | { | ||
130 | #ifdef CONFIG_PPC_STD_MMU_64 | ||
131 | if (what == MCE_FLUSH_SLB) { | ||
132 | flush_and_reload_slb(); | ||
133 | return 1; | ||
134 | } | ||
135 | #endif | ||
136 | if (what == MCE_FLUSH_ERAT) { | ||
137 | flush_erat(); | ||
138 | return 1; | ||
139 | } | ||
140 | if (what == MCE_FLUSH_TLB) { | ||
141 | if (cur_cpu_spec && cur_cpu_spec->flush_tlb) { | ||
142 | cur_cpu_spec->flush_tlb(TLB_INVAL_SCOPE_GLOBAL); | ||
143 | return 1; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static int mce_handle_flush_derrors(uint64_t dsisr, uint64_t slb, uint64_t tlb, uint64_t erat) | ||
151 | { | ||
152 | if ((dsisr & slb) && mce_flush(MCE_FLUSH_SLB)) | ||
153 | dsisr &= ~slb; | ||
154 | if ((dsisr & erat) && mce_flush(MCE_FLUSH_ERAT)) | ||
155 | dsisr &= ~erat; | ||
156 | if ((dsisr & tlb) && mce_flush(MCE_FLUSH_TLB)) | ||
157 | dsisr &= ~tlb; | ||
158 | /* Any other errors we don't understand? */ | ||
159 | if (dsisr) | ||
160 | return 0; | ||
161 | return 1; | ||
162 | } | ||
163 | |||
119 | static long mce_handle_derror(uint64_t dsisr, uint64_t slb_error_bits) | 164 | static long mce_handle_derror(uint64_t dsisr, uint64_t slb_error_bits) |
120 | { | 165 | { |
121 | long handled = 1; | 166 | long handled = 1; |
@@ -281,6 +326,9 @@ long __machine_check_early_realmode_p7(struct pt_regs *regs) | |||
281 | long handled = 1; | 326 | long handled = 1; |
282 | struct mce_error_info mce_error_info = { 0 }; | 327 | struct mce_error_info mce_error_info = { 0 }; |
283 | 328 | ||
329 | mce_error_info.severity = MCE_SEV_ERROR_SYNC; | ||
330 | mce_error_info.initiator = MCE_INITIATOR_CPU; | ||
331 | |||
284 | srr1 = regs->msr; | 332 | srr1 = regs->msr; |
285 | nip = regs->nip; | 333 | nip = regs->nip; |
286 | 334 | ||
@@ -352,6 +400,9 @@ long __machine_check_early_realmode_p8(struct pt_regs *regs) | |||
352 | long handled = 1; | 400 | long handled = 1; |
353 | struct mce_error_info mce_error_info = { 0 }; | 401 | struct mce_error_info mce_error_info = { 0 }; |
354 | 402 | ||
403 | mce_error_info.severity = MCE_SEV_ERROR_SYNC; | ||
404 | mce_error_info.initiator = MCE_INITIATOR_CPU; | ||
405 | |||
355 | srr1 = regs->msr; | 406 | srr1 = regs->msr; |
356 | nip = regs->nip; | 407 | nip = regs->nip; |
357 | 408 | ||
@@ -372,3 +423,189 @@ long __machine_check_early_realmode_p8(struct pt_regs *regs) | |||
372 | save_mce_event(regs, handled, &mce_error_info, nip, addr); | 423 | save_mce_event(regs, handled, &mce_error_info, nip, addr); |
373 | return handled; | 424 | return handled; |
374 | } | 425 | } |
426 | |||
427 | static int mce_handle_derror_p9(struct pt_regs *regs) | ||
428 | { | ||
429 | uint64_t dsisr = regs->dsisr; | ||
430 | |||
431 | return mce_handle_flush_derrors(dsisr, | ||
432 | P9_DSISR_MC_SLB_PARITY_MFSLB | | ||
433 | P9_DSISR_MC_SLB_MULTIHIT_MFSLB, | ||
434 | |||
435 | P9_DSISR_MC_TLB_MULTIHIT_MFTLB, | ||
436 | |||
437 | P9_DSISR_MC_ERAT_MULTIHIT); | ||
438 | } | ||
439 | |||
440 | static int mce_handle_ierror_p9(struct pt_regs *regs) | ||
441 | { | ||
442 | uint64_t srr1 = regs->msr; | ||
443 | |||
444 | switch (P9_SRR1_MC_IFETCH(srr1)) { | ||
445 | case P9_SRR1_MC_IFETCH_SLB_PARITY: | ||
446 | case P9_SRR1_MC_IFETCH_SLB_MULTIHIT: | ||
447 | return mce_flush(MCE_FLUSH_SLB); | ||
448 | case P9_SRR1_MC_IFETCH_TLB_MULTIHIT: | ||
449 | return mce_flush(MCE_FLUSH_TLB); | ||
450 | case P9_SRR1_MC_IFETCH_ERAT_MULTIHIT: | ||
451 | return mce_flush(MCE_FLUSH_ERAT); | ||
452 | default: | ||
453 | return 0; | ||
454 | } | ||
455 | } | ||
456 | |||
457 | static void mce_get_derror_p9(struct pt_regs *regs, | ||
458 | struct mce_error_info *mce_err, uint64_t *addr) | ||
459 | { | ||
460 | uint64_t dsisr = regs->dsisr; | ||
461 | |||
462 | mce_err->severity = MCE_SEV_ERROR_SYNC; | ||
463 | mce_err->initiator = MCE_INITIATOR_CPU; | ||
464 | |||
465 | if (dsisr & P9_DSISR_MC_USER_TLBIE) | ||
466 | *addr = regs->nip; | ||
467 | else | ||
468 | *addr = regs->dar; | ||
469 | |||
470 | if (dsisr & P9_DSISR_MC_UE) { | ||
471 | mce_err->error_type = MCE_ERROR_TYPE_UE; | ||
472 | mce_err->u.ue_error_type = MCE_UE_ERROR_LOAD_STORE; | ||
473 | } else if (dsisr & P9_DSISR_MC_UE_TABLEWALK) { | ||
474 | mce_err->error_type = MCE_ERROR_TYPE_UE; | ||
475 | mce_err->u.ue_error_type = MCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE; | ||
476 | } else if (dsisr & P9_DSISR_MC_LINK_LOAD_TIMEOUT) { | ||
477 | mce_err->error_type = MCE_ERROR_TYPE_LINK; | ||
478 | mce_err->u.link_error_type = MCE_LINK_ERROR_LOAD_TIMEOUT; | ||
479 | } else if (dsisr & P9_DSISR_MC_LINK_TABLEWALK_TIMEOUT) { | ||
480 | mce_err->error_type = MCE_ERROR_TYPE_LINK; | ||
481 | mce_err->u.link_error_type = MCE_LINK_ERROR_PAGE_TABLE_WALK_LOAD_STORE_TIMEOUT; | ||
482 | } else if (dsisr & P9_DSISR_MC_ERAT_MULTIHIT) { | ||
483 | mce_err->error_type = MCE_ERROR_TYPE_ERAT; | ||
484 | mce_err->u.erat_error_type = MCE_ERAT_ERROR_MULTIHIT; | ||
485 | } else if (dsisr & P9_DSISR_MC_TLB_MULTIHIT_MFTLB) { | ||
486 | mce_err->error_type = MCE_ERROR_TYPE_TLB; | ||
487 | mce_err->u.tlb_error_type = MCE_TLB_ERROR_MULTIHIT; | ||
488 | } else if (dsisr & P9_DSISR_MC_USER_TLBIE) { | ||
489 | mce_err->error_type = MCE_ERROR_TYPE_USER; | ||
490 | mce_err->u.user_error_type = MCE_USER_ERROR_TLBIE; | ||
491 | } else if (dsisr & P9_DSISR_MC_SLB_PARITY_MFSLB) { | ||
492 | mce_err->error_type = MCE_ERROR_TYPE_SLB; | ||
493 | mce_err->u.slb_error_type = MCE_SLB_ERROR_PARITY; | ||
494 | } else if (dsisr & P9_DSISR_MC_SLB_MULTIHIT_MFSLB) { | ||
495 | mce_err->error_type = MCE_ERROR_TYPE_SLB; | ||
496 | mce_err->u.slb_error_type = MCE_SLB_ERROR_MULTIHIT; | ||
497 | } else if (dsisr & P9_DSISR_MC_RA_LOAD) { | ||
498 | mce_err->error_type = MCE_ERROR_TYPE_RA; | ||
499 | mce_err->u.ra_error_type = MCE_RA_ERROR_LOAD; | ||
500 | } else if (dsisr & P9_DSISR_MC_RA_TABLEWALK) { | ||
501 | mce_err->error_type = MCE_ERROR_TYPE_RA; | ||
502 | mce_err->u.ra_error_type = MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE; | ||
503 | } else if (dsisr & P9_DSISR_MC_RA_TABLEWALK_FOREIGN) { | ||
504 | mce_err->error_type = MCE_ERROR_TYPE_RA; | ||
505 | mce_err->u.ra_error_type = MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE_FOREIGN; | ||
506 | } else if (dsisr & P9_DSISR_MC_RA_FOREIGN) { | ||
507 | mce_err->error_type = MCE_ERROR_TYPE_RA; | ||
508 | mce_err->u.ra_error_type = MCE_RA_ERROR_LOAD_STORE_FOREIGN; | ||
509 | } | ||
510 | } | ||
511 | |||
512 | static void mce_get_ierror_p9(struct pt_regs *regs, | ||
513 | struct mce_error_info *mce_err, uint64_t *addr) | ||
514 | { | ||
515 | uint64_t srr1 = regs->msr; | ||
516 | |||
517 | switch (P9_SRR1_MC_IFETCH(srr1)) { | ||
518 | case P9_SRR1_MC_IFETCH_RA_ASYNC_STORE: | ||
519 | case P9_SRR1_MC_IFETCH_LINK_ASYNC_STORE_TIMEOUT: | ||
520 | mce_err->severity = MCE_SEV_FATAL; | ||
521 | break; | ||
522 | default: | ||
523 | mce_err->severity = MCE_SEV_ERROR_SYNC; | ||
524 | break; | ||
525 | } | ||
526 | |||
527 | mce_err->initiator = MCE_INITIATOR_CPU; | ||
528 | |||
529 | *addr = regs->nip; | ||
530 | |||
531 | switch (P9_SRR1_MC_IFETCH(srr1)) { | ||
532 | case P9_SRR1_MC_IFETCH_UE: | ||
533 | mce_err->error_type = MCE_ERROR_TYPE_UE; | ||
534 | mce_err->u.ue_error_type = MCE_UE_ERROR_IFETCH; | ||
535 | break; | ||
536 | case P9_SRR1_MC_IFETCH_SLB_PARITY: | ||
537 | mce_err->error_type = MCE_ERROR_TYPE_SLB; | ||
538 | mce_err->u.slb_error_type = MCE_SLB_ERROR_PARITY; | ||
539 | break; | ||
540 | case P9_SRR1_MC_IFETCH_SLB_MULTIHIT: | ||
541 | mce_err->error_type = MCE_ERROR_TYPE_SLB; | ||
542 | mce_err->u.slb_error_type = MCE_SLB_ERROR_MULTIHIT; | ||
543 | break; | ||
544 | case P9_SRR1_MC_IFETCH_ERAT_MULTIHIT: | ||
545 | mce_err->error_type = MCE_ERROR_TYPE_ERAT; | ||
546 | mce_err->u.erat_error_type = MCE_ERAT_ERROR_MULTIHIT; | ||
547 | break; | ||
548 | case P9_SRR1_MC_IFETCH_TLB_MULTIHIT: | ||
549 | mce_err->error_type = MCE_ERROR_TYPE_TLB; | ||
550 | mce_err->u.tlb_error_type = MCE_TLB_ERROR_MULTIHIT; | ||
551 | break; | ||
552 | case P9_SRR1_MC_IFETCH_UE_TLB_RELOAD: | ||
553 | mce_err->error_type = MCE_ERROR_TYPE_UE; | ||
554 | mce_err->u.ue_error_type = MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH; | ||
555 | break; | ||
556 | case P9_SRR1_MC_IFETCH_LINK_TIMEOUT: | ||
557 | mce_err->error_type = MCE_ERROR_TYPE_LINK; | ||
558 | mce_err->u.link_error_type = MCE_LINK_ERROR_IFETCH_TIMEOUT; | ||
559 | break; | ||
560 | case P9_SRR1_MC_IFETCH_LINK_TABLEWALK_TIMEOUT: | ||
561 | mce_err->error_type = MCE_ERROR_TYPE_LINK; | ||
562 | mce_err->u.link_error_type = MCE_LINK_ERROR_PAGE_TABLE_WALK_IFETCH_TIMEOUT; | ||
563 | break; | ||
564 | case P9_SRR1_MC_IFETCH_RA: | ||
565 | mce_err->error_type = MCE_ERROR_TYPE_RA; | ||
566 | mce_err->u.ra_error_type = MCE_RA_ERROR_IFETCH; | ||
567 | break; | ||
568 | case P9_SRR1_MC_IFETCH_RA_TABLEWALK: | ||
569 | mce_err->error_type = MCE_ERROR_TYPE_RA; | ||
570 | mce_err->u.ra_error_type = MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH; | ||
571 | break; | ||
572 | case P9_SRR1_MC_IFETCH_RA_ASYNC_STORE: | ||
573 | mce_err->error_type = MCE_ERROR_TYPE_RA; | ||
574 | mce_err->u.ra_error_type = MCE_RA_ERROR_STORE; | ||
575 | break; | ||
576 | case P9_SRR1_MC_IFETCH_LINK_ASYNC_STORE_TIMEOUT: | ||
577 | mce_err->error_type = MCE_ERROR_TYPE_LINK; | ||
578 | mce_err->u.link_error_type = MCE_LINK_ERROR_STORE_TIMEOUT; | ||
579 | break; | ||
580 | case P9_SRR1_MC_IFETCH_RA_TABLEWALK_FOREIGN: | ||
581 | mce_err->error_type = MCE_ERROR_TYPE_RA; | ||
582 | mce_err->u.ra_error_type = MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH_FOREIGN; | ||
583 | break; | ||
584 | default: | ||
585 | break; | ||
586 | } | ||
587 | } | ||
588 | |||
589 | long __machine_check_early_realmode_p9(struct pt_regs *regs) | ||
590 | { | ||
591 | uint64_t nip, addr; | ||
592 | long handled; | ||
593 | struct mce_error_info mce_error_info = { 0 }; | ||
594 | |||
595 | nip = regs->nip; | ||
596 | |||
597 | if (P9_SRR1_MC_LOADSTORE(regs->msr)) { | ||
598 | handled = mce_handle_derror_p9(regs); | ||
599 | mce_get_derror_p9(regs, &mce_error_info, &addr); | ||
600 | } else { | ||
601 | handled = mce_handle_ierror_p9(regs); | ||
602 | mce_get_ierror_p9(regs, &mce_error_info, &addr); | ||
603 | } | ||
604 | |||
605 | /* Handle UE error. */ | ||
606 | if (mce_error_info.error_type == MCE_ERROR_TYPE_UE) | ||
607 | handled = mce_handle_ue_error(regs); | ||
608 | |||
609 | save_mce_event(regs, handled, &mce_error_info, nip, addr); | ||
610 | return handled; | ||
611 | } | ||
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 595dd718ea87..2ff13249f87a 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c | |||
@@ -188,6 +188,8 @@ static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp) | |||
188 | sdsync = POWER7P_MMCRA_SDAR_VALID; | 188 | sdsync = POWER7P_MMCRA_SDAR_VALID; |
189 | else if (ppmu->flags & PPMU_ALT_SIPR) | 189 | else if (ppmu->flags & PPMU_ALT_SIPR) |
190 | sdsync = POWER6_MMCRA_SDSYNC; | 190 | sdsync = POWER6_MMCRA_SDSYNC; |
191 | else if (ppmu->flags & PPMU_NO_SIAR) | ||
192 | sdsync = MMCRA_SAMPLE_ENABLE; | ||
191 | else | 193 | else |
192 | sdsync = MMCRA_SDSYNC; | 194 | sdsync = MMCRA_SDSYNC; |
193 | 195 | ||
diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c index e79fb5fb817d..cd951fd231c4 100644 --- a/arch/powerpc/perf/isa207-common.c +++ b/arch/powerpc/perf/isa207-common.c | |||
@@ -65,12 +65,41 @@ static bool is_event_valid(u64 event) | |||
65 | return !(event & ~valid_mask); | 65 | return !(event & ~valid_mask); |
66 | } | 66 | } |
67 | 67 | ||
68 | static u64 mmcra_sdar_mode(u64 event) | 68 | static inline bool is_event_marked(u64 event) |
69 | { | 69 | { |
70 | if (cpu_has_feature(CPU_FTR_ARCH_300) && !cpu_has_feature(CPU_FTR_POWER9_DD1)) | 70 | if (event & EVENT_IS_MARKED) |
71 | return p9_SDAR_MODE(event) << MMCRA_SDAR_MODE_SHIFT; | 71 | return true; |
72 | |||
73 | return false; | ||
74 | } | ||
72 | 75 | ||
73 | return MMCRA_SDAR_MODE_TLB; | 76 | static void mmcra_sdar_mode(u64 event, unsigned long *mmcra) |
77 | { | ||
78 | /* | ||
79 | * MMCRA[SDAR_MODE] specifices how the SDAR should be updated in | ||
80 | * continous sampling mode. | ||
81 | * | ||
82 | * Incase of Power8: | ||
83 | * MMCRA[SDAR_MODE] will be programmed as "0b01" for continous sampling | ||
84 | * mode and will be un-changed when setting MMCRA[63] (Marked events). | ||
85 | * | ||
86 | * Incase of Power9: | ||
87 | * Marked event: MMCRA[SDAR_MODE] will be set to 0b00 ('No Updates'), | ||
88 | * or if group already have any marked events. | ||
89 | * Non-Marked events (for DD1): | ||
90 | * MMCRA[SDAR_MODE] will be set to 0b01 | ||
91 | * For rest | ||
92 | * MMCRA[SDAR_MODE] will be set from event code. | ||
93 | */ | ||
94 | if (cpu_has_feature(CPU_FTR_ARCH_300)) { | ||
95 | if (is_event_marked(event) || (*mmcra & MMCRA_SAMPLE_ENABLE)) | ||
96 | *mmcra &= MMCRA_SDAR_MODE_NO_UPDATES; | ||
97 | else if (!cpu_has_feature(CPU_FTR_POWER9_DD1)) | ||
98 | *mmcra |= p9_SDAR_MODE(event) << MMCRA_SDAR_MODE_SHIFT; | ||
99 | else if (cpu_has_feature(CPU_FTR_POWER9_DD1)) | ||
100 | *mmcra |= MMCRA_SDAR_MODE_TLB; | ||
101 | } else | ||
102 | *mmcra |= MMCRA_SDAR_MODE_TLB; | ||
74 | } | 103 | } |
75 | 104 | ||
76 | static u64 thresh_cmp_val(u64 value) | 105 | static u64 thresh_cmp_val(u64 value) |
@@ -180,7 +209,7 @@ int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp) | |||
180 | value |= CNST_L1_QUAL_VAL(cache); | 209 | value |= CNST_L1_QUAL_VAL(cache); |
181 | } | 210 | } |
182 | 211 | ||
183 | if (event & EVENT_IS_MARKED) { | 212 | if (is_event_marked(event)) { |
184 | mask |= CNST_SAMPLE_MASK; | 213 | mask |= CNST_SAMPLE_MASK; |
185 | value |= CNST_SAMPLE_VAL(event >> EVENT_SAMPLE_SHIFT); | 214 | value |= CNST_SAMPLE_VAL(event >> EVENT_SAMPLE_SHIFT); |
186 | } | 215 | } |
@@ -276,7 +305,7 @@ int isa207_compute_mmcr(u64 event[], int n_ev, | |||
276 | } | 305 | } |
277 | 306 | ||
278 | /* In continuous sampling mode, update SDAR on TLB miss */ | 307 | /* In continuous sampling mode, update SDAR on TLB miss */ |
279 | mmcra |= mmcra_sdar_mode(event[i]); | 308 | mmcra_sdar_mode(event[i], &mmcra); |
280 | 309 | ||
281 | if (event[i] & EVENT_IS_L1) { | 310 | if (event[i] & EVENT_IS_L1) { |
282 | cache = event[i] >> EVENT_CACHE_SEL_SHIFT; | 311 | cache = event[i] >> EVENT_CACHE_SEL_SHIFT; |
@@ -285,7 +314,7 @@ int isa207_compute_mmcr(u64 event[], int n_ev, | |||
285 | mmcr1 |= (cache & 1) << MMCR1_DC_QUAL_SHIFT; | 314 | mmcr1 |= (cache & 1) << MMCR1_DC_QUAL_SHIFT; |
286 | } | 315 | } |
287 | 316 | ||
288 | if (event[i] & EVENT_IS_MARKED) { | 317 | if (is_event_marked(event[i])) { |
289 | mmcra |= MMCRA_SAMPLE_ENABLE; | 318 | mmcra |= MMCRA_SAMPLE_ENABLE; |
290 | 319 | ||
291 | val = (event[i] >> EVENT_SAMPLE_SHIFT) & EVENT_SAMPLE_MASK; | 320 | val = (event[i] >> EVENT_SAMPLE_SHIFT) & EVENT_SAMPLE_MASK; |
diff --git a/arch/powerpc/perf/isa207-common.h b/arch/powerpc/perf/isa207-common.h index cf9bd8990159..899210f14ee4 100644 --- a/arch/powerpc/perf/isa207-common.h +++ b/arch/powerpc/perf/isa207-common.h | |||
@@ -246,6 +246,7 @@ | |||
246 | #define MMCRA_THR_CMP_SHIFT 32 | 246 | #define MMCRA_THR_CMP_SHIFT 32 |
247 | #define MMCRA_SDAR_MODE_SHIFT 42 | 247 | #define MMCRA_SDAR_MODE_SHIFT 42 |
248 | #define MMCRA_SDAR_MODE_TLB (1ull << MMCRA_SDAR_MODE_SHIFT) | 248 | #define MMCRA_SDAR_MODE_TLB (1ull << MMCRA_SDAR_MODE_SHIFT) |
249 | #define MMCRA_SDAR_MODE_NO_UPDATES ~(0x3ull << MMCRA_SDAR_MODE_SHIFT) | ||
249 | #define MMCRA_IFM_SHIFT 30 | 250 | #define MMCRA_IFM_SHIFT 30 |
250 | 251 | ||
251 | /* MMCR1 Threshold Compare bit constant for power9 */ | 252 | /* MMCR1 Threshold Compare bit constant for power9 */ |
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 86d9fde93c17..e0f856bfbfe8 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c | |||
@@ -395,7 +395,6 @@ static int opal_recover_mce(struct pt_regs *regs, | |||
395 | struct machine_check_event *evt) | 395 | struct machine_check_event *evt) |
396 | { | 396 | { |
397 | int recovered = 0; | 397 | int recovered = 0; |
398 | uint64_t ea = get_mce_fault_addr(evt); | ||
399 | 398 | ||
400 | if (!(regs->msr & MSR_RI)) { | 399 | if (!(regs->msr & MSR_RI)) { |
401 | /* If MSR_RI isn't set, we cannot recover */ | 400 | /* If MSR_RI isn't set, we cannot recover */ |
@@ -404,26 +403,18 @@ static int opal_recover_mce(struct pt_regs *regs, | |||
404 | } else if (evt->disposition == MCE_DISPOSITION_RECOVERED) { | 403 | } else if (evt->disposition == MCE_DISPOSITION_RECOVERED) { |
405 | /* Platform corrected itself */ | 404 | /* Platform corrected itself */ |
406 | recovered = 1; | 405 | recovered = 1; |
407 | } else if (ea && !is_kernel_addr(ea)) { | 406 | } else if (evt->severity == MCE_SEV_FATAL) { |
407 | /* Fatal machine check */ | ||
408 | pr_err("Machine check interrupt is fatal\n"); | ||
409 | recovered = 0; | ||
410 | } else if ((evt->severity == MCE_SEV_ERROR_SYNC) && | ||
411 | (user_mode(regs) && !is_global_init(current))) { | ||
408 | /* | 412 | /* |
409 | * Faulting address is not in kernel text. We should be fine. | ||
410 | * We need to find which process uses this address. | ||
411 | * For now, kill the task if we have received exception when | 413 | * For now, kill the task if we have received exception when |
412 | * in userspace. | 414 | * in userspace. |
413 | * | 415 | * |
414 | * TODO: Queue up this address for hwpoisioning later. | 416 | * TODO: Queue up this address for hwpoisioning later. |
415 | */ | 417 | */ |
416 | if (user_mode(regs) && !is_global_init(current)) { | ||
417 | _exception(SIGBUS, regs, BUS_MCEERR_AR, regs->nip); | ||
418 | recovered = 1; | ||
419 | } else | ||
420 | recovered = 0; | ||
421 | } else if (user_mode(regs) && !is_global_init(current) && | ||
422 | evt->severity == MCE_SEV_ERROR_SYNC) { | ||
423 | /* | ||
424 | * If we have received a synchronous error when in userspace | ||
425 | * kill the task. | ||
426 | */ | ||
427 | _exception(SIGBUS, regs, BUS_MCEERR_AR, regs->nip); | 418 | _exception(SIGBUS, regs, BUS_MCEERR_AR, regs->nip); |
428 | recovered = 1; | 419 | recovered = 1; |
429 | } | 420 | } |
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 6901a06da2f9..e36738291c32 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
@@ -1775,17 +1775,20 @@ static u64 pnv_pci_ioda_dma_get_required_mask(struct pci_dev *pdev) | |||
1775 | } | 1775 | } |
1776 | 1776 | ||
1777 | static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, | 1777 | static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, |
1778 | struct pci_bus *bus) | 1778 | struct pci_bus *bus, |
1779 | bool add_to_group) | ||
1779 | { | 1780 | { |
1780 | struct pci_dev *dev; | 1781 | struct pci_dev *dev; |
1781 | 1782 | ||
1782 | list_for_each_entry(dev, &bus->devices, bus_list) { | 1783 | list_for_each_entry(dev, &bus->devices, bus_list) { |
1783 | set_iommu_table_base(&dev->dev, pe->table_group.tables[0]); | 1784 | set_iommu_table_base(&dev->dev, pe->table_group.tables[0]); |
1784 | set_dma_offset(&dev->dev, pe->tce_bypass_base); | 1785 | set_dma_offset(&dev->dev, pe->tce_bypass_base); |
1785 | iommu_add_device(&dev->dev); | 1786 | if (add_to_group) |
1787 | iommu_add_device(&dev->dev); | ||
1786 | 1788 | ||
1787 | if ((pe->flags & PNV_IODA_PE_BUS_ALL) && dev->subordinate) | 1789 | if ((pe->flags & PNV_IODA_PE_BUS_ALL) && dev->subordinate) |
1788 | pnv_ioda_setup_bus_dma(pe, dev->subordinate); | 1790 | pnv_ioda_setup_bus_dma(pe, dev->subordinate, |
1791 | add_to_group); | ||
1789 | } | 1792 | } |
1790 | } | 1793 | } |
1791 | 1794 | ||
@@ -2191,7 +2194,7 @@ found: | |||
2191 | set_iommu_table_base(&pe->pdev->dev, tbl); | 2194 | set_iommu_table_base(&pe->pdev->dev, tbl); |
2192 | iommu_add_device(&pe->pdev->dev); | 2195 | iommu_add_device(&pe->pdev->dev); |
2193 | } else if (pe->flags & (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL)) | 2196 | } else if (pe->flags & (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL)) |
2194 | pnv_ioda_setup_bus_dma(pe, pe->pbus); | 2197 | pnv_ioda_setup_bus_dma(pe, pe->pbus, true); |
2195 | 2198 | ||
2196 | return; | 2199 | return; |
2197 | fail: | 2200 | fail: |
@@ -2426,6 +2429,8 @@ static void pnv_ioda2_take_ownership(struct iommu_table_group *table_group) | |||
2426 | 2429 | ||
2427 | pnv_pci_ioda2_set_bypass(pe, false); | 2430 | pnv_pci_ioda2_set_bypass(pe, false); |
2428 | pnv_pci_ioda2_unset_window(&pe->table_group, 0); | 2431 | pnv_pci_ioda2_unset_window(&pe->table_group, 0); |
2432 | if (pe->pbus) | ||
2433 | pnv_ioda_setup_bus_dma(pe, pe->pbus, false); | ||
2429 | pnv_ioda2_table_free(tbl); | 2434 | pnv_ioda2_table_free(tbl); |
2430 | } | 2435 | } |
2431 | 2436 | ||
@@ -2435,6 +2440,8 @@ static void pnv_ioda2_release_ownership(struct iommu_table_group *table_group) | |||
2435 | table_group); | 2440 | table_group); |
2436 | 2441 | ||
2437 | pnv_pci_ioda2_setup_default_config(pe); | 2442 | pnv_pci_ioda2_setup_default_config(pe); |
2443 | if (pe->pbus) | ||
2444 | pnv_ioda_setup_bus_dma(pe, pe->pbus, false); | ||
2438 | } | 2445 | } |
2439 | 2446 | ||
2440 | static struct iommu_table_group_ops pnv_pci_ioda2_ops = { | 2447 | static struct iommu_table_group_ops pnv_pci_ioda2_ops = { |
@@ -2624,6 +2631,9 @@ static long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset, | |||
2624 | level_shift = entries_shift + 3; | 2631 | level_shift = entries_shift + 3; |
2625 | level_shift = max_t(unsigned, level_shift, PAGE_SHIFT); | 2632 | level_shift = max_t(unsigned, level_shift, PAGE_SHIFT); |
2626 | 2633 | ||
2634 | if ((level_shift - 3) * levels + page_shift >= 60) | ||
2635 | return -EINVAL; | ||
2636 | |||
2627 | /* Allocate TCE table */ | 2637 | /* Allocate TCE table */ |
2628 | addr = pnv_pci_ioda2_table_do_alloc_pages(nid, level_shift, | 2638 | addr = pnv_pci_ioda2_table_do_alloc_pages(nid, level_shift, |
2629 | levels, tce_table_size, &offset, &total_allocated); | 2639 | levels, tce_table_size, &offset, &total_allocated); |
@@ -2728,7 +2738,7 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb, | |||
2728 | if (pe->flags & PNV_IODA_PE_DEV) | 2738 | if (pe->flags & PNV_IODA_PE_DEV) |
2729 | iommu_add_device(&pe->pdev->dev); | 2739 | iommu_add_device(&pe->pdev->dev); |
2730 | else if (pe->flags & (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL)) | 2740 | else if (pe->flags & (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL)) |
2731 | pnv_ioda_setup_bus_dma(pe, pe->pbus); | 2741 | pnv_ioda_setup_bus_dma(pe, pe->pbus, true); |
2732 | } | 2742 | } |
2733 | 2743 | ||
2734 | #ifdef CONFIG_PCI_MSI | 2744 | #ifdef CONFIG_PCI_MSI |
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 251060cf1713..8b1fe895daa3 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
@@ -751,7 +751,9 @@ void __init hpte_init_pseries(void) | |||
751 | mmu_hash_ops.flush_hash_range = pSeries_lpar_flush_hash_range; | 751 | mmu_hash_ops.flush_hash_range = pSeries_lpar_flush_hash_range; |
752 | mmu_hash_ops.hpte_clear_all = pseries_hpte_clear_all; | 752 | mmu_hash_ops.hpte_clear_all = pseries_hpte_clear_all; |
753 | mmu_hash_ops.hugepage_invalidate = pSeries_lpar_hugepage_invalidate; | 753 | mmu_hash_ops.hugepage_invalidate = pSeries_lpar_hugepage_invalidate; |
754 | mmu_hash_ops.resize_hpt = pseries_lpar_resize_hpt; | 754 | |
755 | if (firmware_has_feature(FW_FEATURE_HPT_RESIZE)) | ||
756 | mmu_hash_ops.resize_hpt = pseries_lpar_resize_hpt; | ||
755 | } | 757 | } |
756 | 758 | ||
757 | void radix_init_pseries(void) | 759 | void radix_init_pseries(void) |
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 349d4d17aa7f..2aa1ad194db2 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c | |||
@@ -2101,8 +2101,8 @@ static int x86_pmu_event_init(struct perf_event *event) | |||
2101 | 2101 | ||
2102 | static void refresh_pce(void *ignored) | 2102 | static void refresh_pce(void *ignored) |
2103 | { | 2103 | { |
2104 | if (current->mm) | 2104 | if (current->active_mm) |
2105 | load_mm_cr4(current->mm); | 2105 | load_mm_cr4(current->active_mm); |
2106 | } | 2106 | } |
2107 | 2107 | ||
2108 | static void x86_pmu_event_mapped(struct perf_event *event) | 2108 | static void x86_pmu_event_mapped(struct perf_event *event) |
@@ -2110,6 +2110,18 @@ static void x86_pmu_event_mapped(struct perf_event *event) | |||
2110 | if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED)) | 2110 | if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED)) |
2111 | return; | 2111 | return; |
2112 | 2112 | ||
2113 | /* | ||
2114 | * This function relies on not being called concurrently in two | ||
2115 | * tasks in the same mm. Otherwise one task could observe | ||
2116 | * perf_rdpmc_allowed > 1 and return all the way back to | ||
2117 | * userspace with CR4.PCE clear while another task is still | ||
2118 | * doing on_each_cpu_mask() to propagate CR4.PCE. | ||
2119 | * | ||
2120 | * For now, this can't happen because all callers hold mmap_sem | ||
2121 | * for write. If this changes, we'll need a different solution. | ||
2122 | */ | ||
2123 | lockdep_assert_held_exclusive(¤t->mm->mmap_sem); | ||
2124 | |||
2113 | if (atomic_inc_return(¤t->mm->context.perf_rdpmc_allowed) == 1) | 2125 | if (atomic_inc_return(¤t->mm->context.perf_rdpmc_allowed) == 1) |
2114 | on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1); | 2126 | on_each_cpu_mask(mm_cpumask(current->mm), refresh_pce, NULL, 1); |
2115 | } | 2127 | } |
diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h index 72277b1028a5..50d35e3185f5 100644 --- a/arch/x86/include/asm/pgtable-3level.h +++ b/arch/x86/include/asm/pgtable-3level.h | |||
@@ -121,12 +121,9 @@ static inline void native_pmd_clear(pmd_t *pmd) | |||
121 | *(tmp + 1) = 0; | 121 | *(tmp + 1) = 0; |
122 | } | 122 | } |
123 | 123 | ||
124 | #if !defined(CONFIG_SMP) || (defined(CONFIG_HIGHMEM64G) && \ | ||
125 | defined(CONFIG_PARAVIRT)) | ||
126 | static inline void native_pud_clear(pud_t *pudp) | 124 | static inline void native_pud_clear(pud_t *pudp) |
127 | { | 125 | { |
128 | } | 126 | } |
129 | #endif | ||
130 | 127 | ||
131 | static inline void pud_clear(pud_t *pudp) | 128 | static inline void pud_clear(pud_t *pudp) |
132 | { | 129 | { |
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 1cfb36b8c024..585ee0d42d18 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h | |||
@@ -62,7 +62,7 @@ extern struct mm_struct *pgd_page_get_mm(struct page *page); | |||
62 | # define set_pud(pudp, pud) native_set_pud(pudp, pud) | 62 | # define set_pud(pudp, pud) native_set_pud(pudp, pud) |
63 | #endif | 63 | #endif |
64 | 64 | ||
65 | #ifndef __PAGETABLE_PMD_FOLDED | 65 | #ifndef __PAGETABLE_PUD_FOLDED |
66 | #define pud_clear(pud) native_pud_clear(pud) | 66 | #define pud_clear(pud) native_pud_clear(pud) |
67 | #endif | 67 | #endif |
68 | 68 | ||
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index ae32838cac5f..b2879cc23db4 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -179,10 +179,15 @@ static int acpi_register_lapic(int id, u32 acpiid, u8 enabled) | |||
179 | return -EINVAL; | 179 | return -EINVAL; |
180 | } | 180 | } |
181 | 181 | ||
182 | if (!enabled) { | ||
183 | ++disabled_cpus; | ||
184 | return -EINVAL; | ||
185 | } | ||
186 | |||
182 | if (boot_cpu_physical_apicid != -1U) | 187 | if (boot_cpu_physical_apicid != -1U) |
183 | ver = boot_cpu_apic_version; | 188 | ver = boot_cpu_apic_version; |
184 | 189 | ||
185 | cpu = __generic_processor_info(id, ver, enabled); | 190 | cpu = generic_processor_info(id, ver); |
186 | if (cpu >= 0) | 191 | if (cpu >= 0) |
187 | early_per_cpu(x86_cpu_to_acpiid, cpu) = acpiid; | 192 | early_per_cpu(x86_cpu_to_acpiid, cpu) = acpiid; |
188 | 193 | ||
@@ -710,7 +715,7 @@ static void __init acpi_set_irq_model_ioapic(void) | |||
710 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | 715 | #ifdef CONFIG_ACPI_HOTPLUG_CPU |
711 | #include <acpi/processor.h> | 716 | #include <acpi/processor.h> |
712 | 717 | ||
713 | int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) | 718 | static int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) |
714 | { | 719 | { |
715 | #ifdef CONFIG_ACPI_NUMA | 720 | #ifdef CONFIG_ACPI_NUMA |
716 | int nid; | 721 | int nid; |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index aee7deddabd0..8ccb7ef512e0 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -2063,7 +2063,7 @@ static int allocate_logical_cpuid(int apicid) | |||
2063 | return nr_logical_cpuids++; | 2063 | return nr_logical_cpuids++; |
2064 | } | 2064 | } |
2065 | 2065 | ||
2066 | int __generic_processor_info(int apicid, int version, bool enabled) | 2066 | int generic_processor_info(int apicid, int version) |
2067 | { | 2067 | { |
2068 | int cpu, max = nr_cpu_ids; | 2068 | int cpu, max = nr_cpu_ids; |
2069 | bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid, | 2069 | bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid, |
@@ -2121,11 +2121,9 @@ int __generic_processor_info(int apicid, int version, bool enabled) | |||
2121 | if (num_processors >= nr_cpu_ids) { | 2121 | if (num_processors >= nr_cpu_ids) { |
2122 | int thiscpu = max + disabled_cpus; | 2122 | int thiscpu = max + disabled_cpus; |
2123 | 2123 | ||
2124 | if (enabled) { | 2124 | pr_warning("APIC: NR_CPUS/possible_cpus limit of %i " |
2125 | pr_warning("APIC: NR_CPUS/possible_cpus limit of %i " | 2125 | "reached. Processor %d/0x%x ignored.\n", |
2126 | "reached. Processor %d/0x%x ignored.\n", | 2126 | max, thiscpu, apicid); |
2127 | max, thiscpu, apicid); | ||
2128 | } | ||
2129 | 2127 | ||
2130 | disabled_cpus++; | 2128 | disabled_cpus++; |
2131 | return -EINVAL; | 2129 | return -EINVAL; |
@@ -2177,23 +2175,13 @@ int __generic_processor_info(int apicid, int version, bool enabled) | |||
2177 | apic->x86_32_early_logical_apicid(cpu); | 2175 | apic->x86_32_early_logical_apicid(cpu); |
2178 | #endif | 2176 | #endif |
2179 | set_cpu_possible(cpu, true); | 2177 | set_cpu_possible(cpu, true); |
2180 | 2178 | physid_set(apicid, phys_cpu_present_map); | |
2181 | if (enabled) { | 2179 | set_cpu_present(cpu, true); |
2182 | num_processors++; | 2180 | num_processors++; |
2183 | physid_set(apicid, phys_cpu_present_map); | ||
2184 | set_cpu_present(cpu, true); | ||
2185 | } else { | ||
2186 | disabled_cpus++; | ||
2187 | } | ||
2188 | 2181 | ||
2189 | return cpu; | 2182 | return cpu; |
2190 | } | 2183 | } |
2191 | 2184 | ||
2192 | int generic_processor_info(int apicid, int version) | ||
2193 | { | ||
2194 | return __generic_processor_info(apicid, version, true); | ||
2195 | } | ||
2196 | |||
2197 | int hard_smp_processor_id(void) | 2185 | int hard_smp_processor_id(void) |
2198 | { | 2186 | { |
2199 | return read_apic_id(); | 2187 | return read_apic_id(); |
diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c index c05509d38b1f..9ac2a5cdd9c2 100644 --- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | |||
@@ -727,7 +727,7 @@ void rdtgroup_kn_unlock(struct kernfs_node *kn) | |||
727 | if (atomic_dec_and_test(&rdtgrp->waitcount) && | 727 | if (atomic_dec_and_test(&rdtgrp->waitcount) && |
728 | (rdtgrp->flags & RDT_DELETED)) { | 728 | (rdtgrp->flags & RDT_DELETED)) { |
729 | kernfs_unbreak_active_protection(kn); | 729 | kernfs_unbreak_active_protection(kn); |
730 | kernfs_put(kn); | 730 | kernfs_put(rdtgrp->kn); |
731 | kfree(rdtgrp); | 731 | kfree(rdtgrp); |
732 | } else { | 732 | } else { |
733 | kernfs_unbreak_active_protection(kn); | 733 | kernfs_unbreak_active_protection(kn); |
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 54a2372f5dbb..b5785c197e53 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE | 4 | * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #define DISABLE_BRANCH_PROFILING | ||
7 | #include <linux/init.h> | 8 | #include <linux/init.h> |
8 | #include <linux/linkage.h> | 9 | #include <linux/linkage.h> |
9 | #include <linux/types.h> | 10 | #include <linux/types.h> |
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index f088ea4c66e7..a723ae9440ab 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c | |||
@@ -166,11 +166,9 @@ int __register_nmi_handler(unsigned int type, struct nmiaction *action) | |||
166 | spin_lock_irqsave(&desc->lock, flags); | 166 | spin_lock_irqsave(&desc->lock, flags); |
167 | 167 | ||
168 | /* | 168 | /* |
169 | * most handlers of type NMI_UNKNOWN never return because | 169 | * Indicate if there are multiple registrations on the |
170 | * they just assume the NMI is theirs. Just a sanity check | 170 | * internal NMI handler call chains (SERR and IO_CHECK). |
171 | * to manage expectations | ||
172 | */ | 171 | */ |
173 | WARN_ON_ONCE(type == NMI_UNKNOWN && !list_empty(&desc->head)); | ||
174 | WARN_ON_ONCE(type == NMI_SERR && !list_empty(&desc->head)); | 172 | WARN_ON_ONCE(type == NMI_SERR && !list_empty(&desc->head)); |
175 | WARN_ON_ONCE(type == NMI_IO_CHECK && !list_empty(&desc->head)); | 173 | WARN_ON_ONCE(type == NMI_IO_CHECK && !list_empty(&desc->head)); |
176 | 174 | ||
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 4f7a9833d8e5..c73a7f9e881a 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -1333,6 +1333,8 @@ static int __init init_tsc_clocksource(void) | |||
1333 | * the refined calibration and directly register it as a clocksource. | 1333 | * the refined calibration and directly register it as a clocksource. |
1334 | */ | 1334 | */ |
1335 | if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) { | 1335 | if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) { |
1336 | if (boot_cpu_has(X86_FEATURE_ART)) | ||
1337 | art_related_clocksource = &clocksource_tsc; | ||
1336 | clocksource_register_khz(&clocksource_tsc, tsc_khz); | 1338 | clocksource_register_khz(&clocksource_tsc, tsc_khz); |
1337 | return 0; | 1339 | return 0; |
1338 | } | 1340 | } |
diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c index 478d15dbaee4..08339262b666 100644 --- a/arch/x86/kernel/unwind_frame.c +++ b/arch/x86/kernel/unwind_frame.c | |||
@@ -82,19 +82,43 @@ static size_t regs_size(struct pt_regs *regs) | |||
82 | return sizeof(*regs); | 82 | return sizeof(*regs); |
83 | } | 83 | } |
84 | 84 | ||
85 | #ifdef CONFIG_X86_32 | ||
86 | #define GCC_REALIGN_WORDS 3 | ||
87 | #else | ||
88 | #define GCC_REALIGN_WORDS 1 | ||
89 | #endif | ||
90 | |||
85 | static bool is_last_task_frame(struct unwind_state *state) | 91 | static bool is_last_task_frame(struct unwind_state *state) |
86 | { | 92 | { |
87 | unsigned long bp = (unsigned long)state->bp; | 93 | unsigned long *last_bp = (unsigned long *)task_pt_regs(state->task) - 2; |
88 | unsigned long regs = (unsigned long)task_pt_regs(state->task); | 94 | unsigned long *aligned_bp = last_bp - GCC_REALIGN_WORDS; |
89 | 95 | ||
90 | /* | 96 | /* |
91 | * We have to check for the last task frame at two different locations | 97 | * We have to check for the last task frame at two different locations |
92 | * because gcc can occasionally decide to realign the stack pointer and | 98 | * because gcc can occasionally decide to realign the stack pointer and |
93 | * change the offset of the stack frame by a word in the prologue of a | 99 | * change the offset of the stack frame in the prologue of a function |
94 | * function called by head/entry code. | 100 | * called by head/entry code. Examples: |
101 | * | ||
102 | * <start_secondary>: | ||
103 | * push %edi | ||
104 | * lea 0x8(%esp),%edi | ||
105 | * and $0xfffffff8,%esp | ||
106 | * pushl -0x4(%edi) | ||
107 | * push %ebp | ||
108 | * mov %esp,%ebp | ||
109 | * | ||
110 | * <x86_64_start_kernel>: | ||
111 | * lea 0x8(%rsp),%r10 | ||
112 | * and $0xfffffffffffffff0,%rsp | ||
113 | * pushq -0x8(%r10) | ||
114 | * push %rbp | ||
115 | * mov %rsp,%rbp | ||
116 | * | ||
117 | * Note that after aligning the stack, it pushes a duplicate copy of | ||
118 | * the return address before pushing the frame pointer. | ||
95 | */ | 119 | */ |
96 | return bp == regs - FRAME_HEADER_SIZE || | 120 | return (state->bp == last_bp || |
97 | bp == regs - FRAME_HEADER_SIZE - sizeof(long); | 121 | (state->bp == aligned_bp && *(aligned_bp+1) == *(last_bp+1))); |
98 | } | 122 | } |
99 | 123 | ||
100 | /* | 124 | /* |
diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c index 8d63d7a104c3..4c90cfdc128b 100644 --- a/arch/x86/mm/kasan_init_64.c +++ b/arch/x86/mm/kasan_init_64.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #define DISABLE_BRANCH_PROFILING | ||
1 | #define pr_fmt(fmt) "kasan: " fmt | 2 | #define pr_fmt(fmt) "kasan: " fmt |
2 | #include <linux/bootmem.h> | 3 | #include <linux/bootmem.h> |
3 | #include <linux/kasan.h> | 4 | #include <linux/kasan.h> |
diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c index 5126dfd52b18..cd44ae727df7 100644 --- a/arch/x86/mm/mpx.c +++ b/arch/x86/mm/mpx.c | |||
@@ -590,7 +590,7 @@ static unsigned long mpx_bd_entry_to_bt_addr(struct mm_struct *mm, | |||
590 | * we might run off the end of the bounds table if we are on | 590 | * we might run off the end of the bounds table if we are on |
591 | * a 64-bit kernel and try to get 8 bytes. | 591 | * a 64-bit kernel and try to get 8 bytes. |
592 | */ | 592 | */ |
593 | int get_user_bd_entry(struct mm_struct *mm, unsigned long *bd_entry_ret, | 593 | static int get_user_bd_entry(struct mm_struct *mm, unsigned long *bd_entry_ret, |
594 | long __user *bd_entry_ptr) | 594 | long __user *bd_entry_ptr) |
595 | { | 595 | { |
596 | u32 bd_entry_32; | 596 | u32 bd_entry_32; |
diff --git a/arch/x86/platform/intel-mid/device_libs/Makefile b/arch/x86/platform/intel-mid/device_libs/Makefile index a7dbec4dce27..3dbde04febdc 100644 --- a/arch/x86/platform/intel-mid/device_libs/Makefile +++ b/arch/x86/platform/intel-mid/device_libs/Makefile | |||
@@ -26,5 +26,6 @@ obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_pcal9555a.o | |||
26 | obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_tca6416.o | 26 | obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_tca6416.o |
27 | # MISC Devices | 27 | # MISC Devices |
28 | obj-$(subst m,y,$(CONFIG_KEYBOARD_GPIO)) += platform_gpio_keys.o | 28 | obj-$(subst m,y,$(CONFIG_KEYBOARD_GPIO)) += platform_gpio_keys.o |
29 | obj-$(subst m,y,$(CONFIG_INTEL_MID_POWER_BUTTON)) += platform_mrfld_power_btn.o | ||
29 | obj-$(subst m,y,$(CONFIG_RTC_DRV_CMOS)) += platform_mrfld_rtc.o | 30 | obj-$(subst m,y,$(CONFIG_RTC_DRV_CMOS)) += platform_mrfld_rtc.o |
30 | obj-$(subst m,y,$(CONFIG_INTEL_MID_WATCHDOG)) += platform_mrfld_wdt.o | 31 | obj-$(subst m,y,$(CONFIG_INTEL_MID_WATCHDOG)) += platform_mrfld_wdt.o |
diff --git a/arch/x86/platform/intel-mid/device_libs/platform_mrfld_power_btn.c b/arch/x86/platform/intel-mid/device_libs/platform_mrfld_power_btn.c new file mode 100644 index 000000000000..a6c3705a28ad --- /dev/null +++ b/arch/x86/platform/intel-mid/device_libs/platform_mrfld_power_btn.c | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * Intel Merrifield power button support | ||
3 | * | ||
4 | * (C) Copyright 2017 Intel Corporation | ||
5 | * | ||
6 | * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||
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; version 2 | ||
11 | * of the License. | ||
12 | */ | ||
13 | |||
14 | #include <linux/init.h> | ||
15 | #include <linux/ioport.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/sfi.h> | ||
18 | |||
19 | #include <asm/intel-mid.h> | ||
20 | #include <asm/intel_scu_ipc.h> | ||
21 | |||
22 | static struct resource mrfld_power_btn_resources[] = { | ||
23 | { | ||
24 | .flags = IORESOURCE_IRQ, | ||
25 | }, | ||
26 | }; | ||
27 | |||
28 | static struct platform_device mrfld_power_btn_dev = { | ||
29 | .name = "msic_power_btn", | ||
30 | .id = PLATFORM_DEVID_NONE, | ||
31 | .num_resources = ARRAY_SIZE(mrfld_power_btn_resources), | ||
32 | .resource = mrfld_power_btn_resources, | ||
33 | }; | ||
34 | |||
35 | static int mrfld_power_btn_scu_status_change(struct notifier_block *nb, | ||
36 | unsigned long code, void *data) | ||
37 | { | ||
38 | if (code == SCU_DOWN) { | ||
39 | platform_device_unregister(&mrfld_power_btn_dev); | ||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | return platform_device_register(&mrfld_power_btn_dev); | ||
44 | } | ||
45 | |||
46 | static struct notifier_block mrfld_power_btn_scu_notifier = { | ||
47 | .notifier_call = mrfld_power_btn_scu_status_change, | ||
48 | }; | ||
49 | |||
50 | static int __init register_mrfld_power_btn(void) | ||
51 | { | ||
52 | if (intel_mid_identify_cpu() != INTEL_MID_CPU_CHIP_TANGIER) | ||
53 | return -ENODEV; | ||
54 | |||
55 | /* | ||
56 | * We need to be sure that the SCU IPC is ready before | ||
57 | * PMIC power button device can be registered: | ||
58 | */ | ||
59 | intel_scu_notifier_add(&mrfld_power_btn_scu_notifier); | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | arch_initcall(register_mrfld_power_btn); | ||
64 | |||
65 | static void __init *mrfld_power_btn_platform_data(void *info) | ||
66 | { | ||
67 | struct resource *res = mrfld_power_btn_resources; | ||
68 | struct sfi_device_table_entry *pentry = info; | ||
69 | |||
70 | res->start = res->end = pentry->irq; | ||
71 | return NULL; | ||
72 | } | ||
73 | |||
74 | static const struct devs_id mrfld_power_btn_dev_id __initconst = { | ||
75 | .name = "bcove_power_btn", | ||
76 | .type = SFI_DEV_TYPE_IPC, | ||
77 | .delay = 1, | ||
78 | .msic = 1, | ||
79 | .get_platform_data = &mrfld_power_btn_platform_data, | ||
80 | }; | ||
81 | |||
82 | sfi_device(mrfld_power_btn_dev_id); | ||
diff --git a/arch/x86/platform/intel-mid/device_libs/platform_mrfld_wdt.c b/arch/x86/platform/intel-mid/device_libs/platform_mrfld_wdt.c index 86edd1e941eb..9e304e2ea4f5 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_mrfld_wdt.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_mrfld_wdt.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <asm/intel_scu_ipc.h> | 19 | #include <asm/intel_scu_ipc.h> |
20 | #include <asm/io_apic.h> | 20 | #include <asm/io_apic.h> |
21 | 21 | ||
22 | #define TANGIER_EXT_TIMER0_MSI 15 | 22 | #define TANGIER_EXT_TIMER0_MSI 12 |
23 | 23 | ||
24 | static struct platform_device wdt_dev = { | 24 | static struct platform_device wdt_dev = { |
25 | .name = "intel_mid_wdt", | 25 | .name = "intel_mid_wdt", |
diff --git a/arch/x86/platform/intel-mid/mfld.c b/arch/x86/platform/intel-mid/mfld.c index e793fe509971..e42978d4deaf 100644 --- a/arch/x86/platform/intel-mid/mfld.c +++ b/arch/x86/platform/intel-mid/mfld.c | |||
@@ -17,16 +17,6 @@ | |||
17 | 17 | ||
18 | #include "intel_mid_weak_decls.h" | 18 | #include "intel_mid_weak_decls.h" |
19 | 19 | ||
20 | static void penwell_arch_setup(void); | ||
21 | /* penwell arch ops */ | ||
22 | static struct intel_mid_ops penwell_ops = { | ||
23 | .arch_setup = penwell_arch_setup, | ||
24 | }; | ||
25 | |||
26 | static void mfld_power_off(void) | ||
27 | { | ||
28 | } | ||
29 | |||
30 | static unsigned long __init mfld_calibrate_tsc(void) | 20 | static unsigned long __init mfld_calibrate_tsc(void) |
31 | { | 21 | { |
32 | unsigned long fast_calibrate; | 22 | unsigned long fast_calibrate; |
@@ -63,9 +53,12 @@ static unsigned long __init mfld_calibrate_tsc(void) | |||
63 | static void __init penwell_arch_setup(void) | 53 | static void __init penwell_arch_setup(void) |
64 | { | 54 | { |
65 | x86_platform.calibrate_tsc = mfld_calibrate_tsc; | 55 | x86_platform.calibrate_tsc = mfld_calibrate_tsc; |
66 | pm_power_off = mfld_power_off; | ||
67 | } | 56 | } |
68 | 57 | ||
58 | static struct intel_mid_ops penwell_ops = { | ||
59 | .arch_setup = penwell_arch_setup, | ||
60 | }; | ||
61 | |||
69 | void *get_penwell_ops(void) | 62 | void *get_penwell_ops(void) |
70 | { | 63 | { |
71 | return &penwell_ops; | 64 | return &penwell_ops; |
diff --git a/block/bio.c b/block/bio.c index 5eec5e08417f..e75878f8b14a 100644 --- a/block/bio.c +++ b/block/bio.c | |||
@@ -376,10 +376,14 @@ static void punt_bios_to_rescuer(struct bio_set *bs) | |||
376 | bio_list_init(&punt); | 376 | bio_list_init(&punt); |
377 | bio_list_init(&nopunt); | 377 | bio_list_init(&nopunt); |
378 | 378 | ||
379 | while ((bio = bio_list_pop(current->bio_list))) | 379 | while ((bio = bio_list_pop(¤t->bio_list[0]))) |
380 | bio_list_add(bio->bi_pool == bs ? &punt : &nopunt, bio); | 380 | bio_list_add(bio->bi_pool == bs ? &punt : &nopunt, bio); |
381 | current->bio_list[0] = nopunt; | ||
381 | 382 | ||
382 | *current->bio_list = nopunt; | 383 | bio_list_init(&nopunt); |
384 | while ((bio = bio_list_pop(¤t->bio_list[1]))) | ||
385 | bio_list_add(bio->bi_pool == bs ? &punt : &nopunt, bio); | ||
386 | current->bio_list[1] = nopunt; | ||
383 | 387 | ||
384 | spin_lock(&bs->rescue_lock); | 388 | spin_lock(&bs->rescue_lock); |
385 | bio_list_merge(&bs->rescue_list, &punt); | 389 | bio_list_merge(&bs->rescue_list, &punt); |
@@ -466,7 +470,9 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) | |||
466 | * we retry with the original gfp_flags. | 470 | * we retry with the original gfp_flags. |
467 | */ | 471 | */ |
468 | 472 | ||
469 | if (current->bio_list && !bio_list_empty(current->bio_list)) | 473 | if (current->bio_list && |
474 | (!bio_list_empty(¤t->bio_list[0]) || | ||
475 | !bio_list_empty(¤t->bio_list[1]))) | ||
470 | gfp_mask &= ~__GFP_DIRECT_RECLAIM; | 476 | gfp_mask &= ~__GFP_DIRECT_RECLAIM; |
471 | 477 | ||
472 | p = mempool_alloc(bs->bio_pool, gfp_mask); | 478 | p = mempool_alloc(bs->bio_pool, gfp_mask); |
diff --git a/block/blk-core.c b/block/blk-core.c index 0eeb99ef654f..d772c221cc17 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -1973,7 +1973,14 @@ end_io: | |||
1973 | */ | 1973 | */ |
1974 | blk_qc_t generic_make_request(struct bio *bio) | 1974 | blk_qc_t generic_make_request(struct bio *bio) |
1975 | { | 1975 | { |
1976 | struct bio_list bio_list_on_stack; | 1976 | /* |
1977 | * bio_list_on_stack[0] contains bios submitted by the current | ||
1978 | * make_request_fn. | ||
1979 | * bio_list_on_stack[1] contains bios that were submitted before | ||
1980 | * the current make_request_fn, but that haven't been processed | ||
1981 | * yet. | ||
1982 | */ | ||
1983 | struct bio_list bio_list_on_stack[2]; | ||
1977 | blk_qc_t ret = BLK_QC_T_NONE; | 1984 | blk_qc_t ret = BLK_QC_T_NONE; |
1978 | 1985 | ||
1979 | if (!generic_make_request_checks(bio)) | 1986 | if (!generic_make_request_checks(bio)) |
@@ -1990,7 +1997,7 @@ blk_qc_t generic_make_request(struct bio *bio) | |||
1990 | * should be added at the tail | 1997 | * should be added at the tail |
1991 | */ | 1998 | */ |
1992 | if (current->bio_list) { | 1999 | if (current->bio_list) { |
1993 | bio_list_add(current->bio_list, bio); | 2000 | bio_list_add(¤t->bio_list[0], bio); |
1994 | goto out; | 2001 | goto out; |
1995 | } | 2002 | } |
1996 | 2003 | ||
@@ -2009,18 +2016,17 @@ blk_qc_t generic_make_request(struct bio *bio) | |||
2009 | * bio_list, and call into ->make_request() again. | 2016 | * bio_list, and call into ->make_request() again. |
2010 | */ | 2017 | */ |
2011 | BUG_ON(bio->bi_next); | 2018 | BUG_ON(bio->bi_next); |
2012 | bio_list_init(&bio_list_on_stack); | 2019 | bio_list_init(&bio_list_on_stack[0]); |
2013 | current->bio_list = &bio_list_on_stack; | 2020 | current->bio_list = bio_list_on_stack; |
2014 | do { | 2021 | do { |
2015 | struct request_queue *q = bdev_get_queue(bio->bi_bdev); | 2022 | struct request_queue *q = bdev_get_queue(bio->bi_bdev); |
2016 | 2023 | ||
2017 | if (likely(blk_queue_enter(q, false) == 0)) { | 2024 | if (likely(blk_queue_enter(q, false) == 0)) { |
2018 | struct bio_list hold; | ||
2019 | struct bio_list lower, same; | 2025 | struct bio_list lower, same; |
2020 | 2026 | ||
2021 | /* Create a fresh bio_list for all subordinate requests */ | 2027 | /* Create a fresh bio_list for all subordinate requests */ |
2022 | hold = bio_list_on_stack; | 2028 | bio_list_on_stack[1] = bio_list_on_stack[0]; |
2023 | bio_list_init(&bio_list_on_stack); | 2029 | bio_list_init(&bio_list_on_stack[0]); |
2024 | ret = q->make_request_fn(q, bio); | 2030 | ret = q->make_request_fn(q, bio); |
2025 | 2031 | ||
2026 | blk_queue_exit(q); | 2032 | blk_queue_exit(q); |
@@ -2030,19 +2036,19 @@ blk_qc_t generic_make_request(struct bio *bio) | |||
2030 | */ | 2036 | */ |
2031 | bio_list_init(&lower); | 2037 | bio_list_init(&lower); |
2032 | bio_list_init(&same); | 2038 | bio_list_init(&same); |
2033 | while ((bio = bio_list_pop(&bio_list_on_stack)) != NULL) | 2039 | while ((bio = bio_list_pop(&bio_list_on_stack[0])) != NULL) |
2034 | if (q == bdev_get_queue(bio->bi_bdev)) | 2040 | if (q == bdev_get_queue(bio->bi_bdev)) |
2035 | bio_list_add(&same, bio); | 2041 | bio_list_add(&same, bio); |
2036 | else | 2042 | else |
2037 | bio_list_add(&lower, bio); | 2043 | bio_list_add(&lower, bio); |
2038 | /* now assemble so we handle the lowest level first */ | 2044 | /* now assemble so we handle the lowest level first */ |
2039 | bio_list_merge(&bio_list_on_stack, &lower); | 2045 | bio_list_merge(&bio_list_on_stack[0], &lower); |
2040 | bio_list_merge(&bio_list_on_stack, &same); | 2046 | bio_list_merge(&bio_list_on_stack[0], &same); |
2041 | bio_list_merge(&bio_list_on_stack, &hold); | 2047 | bio_list_merge(&bio_list_on_stack[0], &bio_list_on_stack[1]); |
2042 | } else { | 2048 | } else { |
2043 | bio_io_error(bio); | 2049 | bio_io_error(bio); |
2044 | } | 2050 | } |
2045 | bio = bio_list_pop(current->bio_list); | 2051 | bio = bio_list_pop(&bio_list_on_stack[0]); |
2046 | } while (bio); | 2052 | } while (bio); |
2047 | current->bio_list = NULL; /* deactivate */ | 2053 | current->bio_list = NULL; /* deactivate */ |
2048 | 2054 | ||
diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c index e48bc2c72615..9d97bfc4d465 100644 --- a/block/blk-mq-tag.c +++ b/block/blk-mq-tag.c | |||
@@ -295,6 +295,9 @@ int blk_mq_reinit_tagset(struct blk_mq_tag_set *set) | |||
295 | for (i = 0; i < set->nr_hw_queues; i++) { | 295 | for (i = 0; i < set->nr_hw_queues; i++) { |
296 | struct blk_mq_tags *tags = set->tags[i]; | 296 | struct blk_mq_tags *tags = set->tags[i]; |
297 | 297 | ||
298 | if (!tags) | ||
299 | continue; | ||
300 | |||
298 | for (j = 0; j < tags->nr_tags; j++) { | 301 | for (j = 0; j < tags->nr_tags; j++) { |
299 | if (!tags->static_rqs[j]) | 302 | if (!tags->static_rqs[j]) |
300 | continue; | 303 | continue; |
diff --git a/block/blk-mq.c b/block/blk-mq.c index 159187a28d66..a4546f060e80 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
@@ -1434,7 +1434,8 @@ static blk_qc_t request_to_qc_t(struct blk_mq_hw_ctx *hctx, struct request *rq) | |||
1434 | return blk_tag_to_qc_t(rq->internal_tag, hctx->queue_num, true); | 1434 | return blk_tag_to_qc_t(rq->internal_tag, hctx->queue_num, true); |
1435 | } | 1435 | } |
1436 | 1436 | ||
1437 | static void blk_mq_try_issue_directly(struct request *rq, blk_qc_t *cookie) | 1437 | static void blk_mq_try_issue_directly(struct request *rq, blk_qc_t *cookie, |
1438 | bool may_sleep) | ||
1438 | { | 1439 | { |
1439 | struct request_queue *q = rq->q; | 1440 | struct request_queue *q = rq->q; |
1440 | struct blk_mq_queue_data bd = { | 1441 | struct blk_mq_queue_data bd = { |
@@ -1475,7 +1476,7 @@ static void blk_mq_try_issue_directly(struct request *rq, blk_qc_t *cookie) | |||
1475 | } | 1476 | } |
1476 | 1477 | ||
1477 | insert: | 1478 | insert: |
1478 | blk_mq_sched_insert_request(rq, false, true, true, false); | 1479 | blk_mq_sched_insert_request(rq, false, true, false, may_sleep); |
1479 | } | 1480 | } |
1480 | 1481 | ||
1481 | /* | 1482 | /* |
@@ -1569,11 +1570,11 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio) | |||
1569 | 1570 | ||
1570 | if (!(data.hctx->flags & BLK_MQ_F_BLOCKING)) { | 1571 | if (!(data.hctx->flags & BLK_MQ_F_BLOCKING)) { |
1571 | rcu_read_lock(); | 1572 | rcu_read_lock(); |
1572 | blk_mq_try_issue_directly(old_rq, &cookie); | 1573 | blk_mq_try_issue_directly(old_rq, &cookie, false); |
1573 | rcu_read_unlock(); | 1574 | rcu_read_unlock(); |
1574 | } else { | 1575 | } else { |
1575 | srcu_idx = srcu_read_lock(&data.hctx->queue_rq_srcu); | 1576 | srcu_idx = srcu_read_lock(&data.hctx->queue_rq_srcu); |
1576 | blk_mq_try_issue_directly(old_rq, &cookie); | 1577 | blk_mq_try_issue_directly(old_rq, &cookie, true); |
1577 | srcu_read_unlock(&data.hctx->queue_rq_srcu, srcu_idx); | 1578 | srcu_read_unlock(&data.hctx->queue_rq_srcu, srcu_idx); |
1578 | } | 1579 | } |
1579 | goto done; | 1580 | goto done; |
diff --git a/crypto/af_alg.c b/crypto/af_alg.c index f5e18c2a4852..690deca17c35 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c | |||
@@ -266,7 +266,7 @@ unlock: | |||
266 | return err; | 266 | return err; |
267 | } | 267 | } |
268 | 268 | ||
269 | int af_alg_accept(struct sock *sk, struct socket *newsock) | 269 | int af_alg_accept(struct sock *sk, struct socket *newsock, bool kern) |
270 | { | 270 | { |
271 | struct alg_sock *ask = alg_sk(sk); | 271 | struct alg_sock *ask = alg_sk(sk); |
272 | const struct af_alg_type *type; | 272 | const struct af_alg_type *type; |
@@ -281,7 +281,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock) | |||
281 | if (!type) | 281 | if (!type) |
282 | goto unlock; | 282 | goto unlock; |
283 | 283 | ||
284 | sk2 = sk_alloc(sock_net(sk), PF_ALG, GFP_KERNEL, &alg_proto, 0); | 284 | sk2 = sk_alloc(sock_net(sk), PF_ALG, GFP_KERNEL, &alg_proto, kern); |
285 | err = -ENOMEM; | 285 | err = -ENOMEM; |
286 | if (!sk2) | 286 | if (!sk2) |
287 | goto unlock; | 287 | goto unlock; |
@@ -323,9 +323,10 @@ unlock: | |||
323 | } | 323 | } |
324 | EXPORT_SYMBOL_GPL(af_alg_accept); | 324 | EXPORT_SYMBOL_GPL(af_alg_accept); |
325 | 325 | ||
326 | static int alg_accept(struct socket *sock, struct socket *newsock, int flags) | 326 | static int alg_accept(struct socket *sock, struct socket *newsock, int flags, |
327 | bool kern) | ||
327 | { | 328 | { |
328 | return af_alg_accept(sock->sk, newsock); | 329 | return af_alg_accept(sock->sk, newsock, kern); |
329 | } | 330 | } |
330 | 331 | ||
331 | static const struct proto_ops alg_proto_ops = { | 332 | static const struct proto_ops alg_proto_ops = { |
diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c index 54fc90e8339c..5e92bd275ef3 100644 --- a/crypto/algif_hash.c +++ b/crypto/algif_hash.c | |||
@@ -239,7 +239,8 @@ unlock: | |||
239 | return err ?: len; | 239 | return err ?: len; |
240 | } | 240 | } |
241 | 241 | ||
242 | static int hash_accept(struct socket *sock, struct socket *newsock, int flags) | 242 | static int hash_accept(struct socket *sock, struct socket *newsock, int flags, |
243 | bool kern) | ||
243 | { | 244 | { |
244 | struct sock *sk = sock->sk; | 245 | struct sock *sk = sock->sk; |
245 | struct alg_sock *ask = alg_sk(sk); | 246 | struct alg_sock *ask = alg_sk(sk); |
@@ -260,7 +261,7 @@ static int hash_accept(struct socket *sock, struct socket *newsock, int flags) | |||
260 | if (err) | 261 | if (err) |
261 | return err; | 262 | return err; |
262 | 263 | ||
263 | err = af_alg_accept(ask->parent, newsock); | 264 | err = af_alg_accept(ask->parent, newsock, kern); |
264 | if (err) | 265 | if (err) |
265 | return err; | 266 | return err; |
266 | 267 | ||
@@ -378,7 +379,7 @@ static int hash_recvmsg_nokey(struct socket *sock, struct msghdr *msg, | |||
378 | } | 379 | } |
379 | 380 | ||
380 | static int hash_accept_nokey(struct socket *sock, struct socket *newsock, | 381 | static int hash_accept_nokey(struct socket *sock, struct socket *newsock, |
381 | int flags) | 382 | int flags, bool kern) |
382 | { | 383 | { |
383 | int err; | 384 | int err; |
384 | 385 | ||
@@ -386,7 +387,7 @@ static int hash_accept_nokey(struct socket *sock, struct socket *newsock, | |||
386 | if (err) | 387 | if (err) |
387 | return err; | 388 | return err; |
388 | 389 | ||
389 | return hash_accept(sock, newsock, flags); | 390 | return hash_accept(sock, newsock, flags, kern); |
390 | } | 391 | } |
391 | 392 | ||
392 | static struct proto_ops algif_hash_ops_nokey = { | 393 | static struct proto_ops algif_hash_ops_nokey = { |
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 4467a8089ab8..0143135b3abe 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c | |||
@@ -182,11 +182,6 @@ int __weak arch_register_cpu(int cpu) | |||
182 | 182 | ||
183 | void __weak arch_unregister_cpu(int cpu) {} | 183 | void __weak arch_unregister_cpu(int cpu) {} |
184 | 184 | ||
185 | int __weak acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) | ||
186 | { | ||
187 | return -ENODEV; | ||
188 | } | ||
189 | |||
190 | static int acpi_processor_hotadd_init(struct acpi_processor *pr) | 185 | static int acpi_processor_hotadd_init(struct acpi_processor *pr) |
191 | { | 186 | { |
192 | unsigned long long sta; | 187 | unsigned long long sta; |
@@ -285,6 +280,13 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
285 | pr->acpi_id = value; | 280 | pr->acpi_id = value; |
286 | } | 281 | } |
287 | 282 | ||
283 | if (acpi_duplicate_processor_id(pr->acpi_id)) { | ||
284 | dev_err(&device->dev, | ||
285 | "Failed to get unique processor _UID (0x%x)\n", | ||
286 | pr->acpi_id); | ||
287 | return -ENODEV; | ||
288 | } | ||
289 | |||
288 | pr->phys_id = acpi_get_phys_id(pr->handle, device_declaration, | 290 | pr->phys_id = acpi_get_phys_id(pr->handle, device_declaration, |
289 | pr->acpi_id); | 291 | pr->acpi_id); |
290 | if (invalid_phys_cpuid(pr->phys_id)) | 292 | if (invalid_phys_cpuid(pr->phys_id)) |
@@ -585,7 +587,7 @@ static struct acpi_scan_handler processor_container_handler = { | |||
585 | static int nr_unique_ids __initdata; | 587 | static int nr_unique_ids __initdata; |
586 | 588 | ||
587 | /* The number of the duplicate processor IDs */ | 589 | /* The number of the duplicate processor IDs */ |
588 | static int nr_duplicate_ids __initdata; | 590 | static int nr_duplicate_ids; |
589 | 591 | ||
590 | /* Used to store the unique processor IDs */ | 592 | /* Used to store the unique processor IDs */ |
591 | static int unique_processor_ids[] __initdata = { | 593 | static int unique_processor_ids[] __initdata = { |
@@ -593,7 +595,7 @@ static int unique_processor_ids[] __initdata = { | |||
593 | }; | 595 | }; |
594 | 596 | ||
595 | /* Used to store the duplicate processor IDs */ | 597 | /* Used to store the duplicate processor IDs */ |
596 | static int duplicate_processor_ids[] __initdata = { | 598 | static int duplicate_processor_ids[] = { |
597 | [0 ... NR_CPUS - 1] = -1, | 599 | [0 ... NR_CPUS - 1] = -1, |
598 | }; | 600 | }; |
599 | 601 | ||
@@ -638,28 +640,53 @@ static acpi_status __init acpi_processor_ids_walk(acpi_handle handle, | |||
638 | void **rv) | 640 | void **rv) |
639 | { | 641 | { |
640 | acpi_status status; | 642 | acpi_status status; |
643 | acpi_object_type acpi_type; | ||
644 | unsigned long long uid; | ||
641 | union acpi_object object = { 0 }; | 645 | union acpi_object object = { 0 }; |
642 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; | 646 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; |
643 | 647 | ||
644 | status = acpi_evaluate_object(handle, NULL, NULL, &buffer); | 648 | status = acpi_get_type(handle, &acpi_type); |
645 | if (ACPI_FAILURE(status)) | 649 | if (ACPI_FAILURE(status)) |
646 | acpi_handle_info(handle, "Not get the processor object\n"); | 650 | return false; |
647 | else | 651 | |
648 | processor_validated_ids_update(object.processor.proc_id); | 652 | switch (acpi_type) { |
653 | case ACPI_TYPE_PROCESSOR: | ||
654 | status = acpi_evaluate_object(handle, NULL, NULL, &buffer); | ||
655 | if (ACPI_FAILURE(status)) | ||
656 | goto err; | ||
657 | uid = object.processor.proc_id; | ||
658 | break; | ||
659 | |||
660 | case ACPI_TYPE_DEVICE: | ||
661 | status = acpi_evaluate_integer(handle, "_UID", NULL, &uid); | ||
662 | if (ACPI_FAILURE(status)) | ||
663 | goto err; | ||
664 | break; | ||
665 | default: | ||
666 | goto err; | ||
667 | } | ||
668 | |||
669 | processor_validated_ids_update(uid); | ||
670 | return true; | ||
671 | |||
672 | err: | ||
673 | acpi_handle_info(handle, "Invalid processor object\n"); | ||
674 | return false; | ||
649 | 675 | ||
650 | return AE_OK; | ||
651 | } | 676 | } |
652 | 677 | ||
653 | static void __init acpi_processor_check_duplicates(void) | 678 | void __init acpi_processor_check_duplicates(void) |
654 | { | 679 | { |
655 | /* Search all processor nodes in ACPI namespace */ | 680 | /* check the correctness for all processors in ACPI namespace */ |
656 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, | 681 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, |
657 | ACPI_UINT32_MAX, | 682 | ACPI_UINT32_MAX, |
658 | acpi_processor_ids_walk, | 683 | acpi_processor_ids_walk, |
659 | NULL, NULL, NULL); | 684 | NULL, NULL, NULL); |
685 | acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, acpi_processor_ids_walk, | ||
686 | NULL, NULL); | ||
660 | } | 687 | } |
661 | 688 | ||
662 | bool __init acpi_processor_validate_proc_id(int proc_id) | 689 | bool acpi_duplicate_processor_id(int proc_id) |
663 | { | 690 | { |
664 | int i; | 691 | int i; |
665 | 692 | ||
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 80cb5eb75b63..34fbe027e73a 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -1249,7 +1249,6 @@ static int __init acpi_init(void) | |||
1249 | acpi_wakeup_device_init(); | 1249 | acpi_wakeup_device_init(); |
1250 | acpi_debugger_init(); | 1250 | acpi_debugger_init(); |
1251 | acpi_setup_sb_notify_handler(); | 1251 | acpi_setup_sb_notify_handler(); |
1252 | acpi_set_processor_mapping(); | ||
1253 | return 0; | 1252 | return 0; |
1254 | } | 1253 | } |
1255 | 1254 | ||
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 611a5585a902..b933061b6b60 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -32,12 +32,12 @@ static struct acpi_table_madt *get_madt_table(void) | |||
32 | } | 32 | } |
33 | 33 | ||
34 | static int map_lapic_id(struct acpi_subtable_header *entry, | 34 | static int map_lapic_id(struct acpi_subtable_header *entry, |
35 | u32 acpi_id, phys_cpuid_t *apic_id, bool ignore_disabled) | 35 | u32 acpi_id, phys_cpuid_t *apic_id) |
36 | { | 36 | { |
37 | struct acpi_madt_local_apic *lapic = | 37 | struct acpi_madt_local_apic *lapic = |
38 | container_of(entry, struct acpi_madt_local_apic, header); | 38 | container_of(entry, struct acpi_madt_local_apic, header); |
39 | 39 | ||
40 | if (ignore_disabled && !(lapic->lapic_flags & ACPI_MADT_ENABLED)) | 40 | if (!(lapic->lapic_flags & ACPI_MADT_ENABLED)) |
41 | return -ENODEV; | 41 | return -ENODEV; |
42 | 42 | ||
43 | if (lapic->processor_id != acpi_id) | 43 | if (lapic->processor_id != acpi_id) |
@@ -48,13 +48,12 @@ static int map_lapic_id(struct acpi_subtable_header *entry, | |||
48 | } | 48 | } |
49 | 49 | ||
50 | static int map_x2apic_id(struct acpi_subtable_header *entry, | 50 | static int map_x2apic_id(struct acpi_subtable_header *entry, |
51 | int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id, | 51 | int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id) |
52 | bool ignore_disabled) | ||
53 | { | 52 | { |
54 | struct acpi_madt_local_x2apic *apic = | 53 | struct acpi_madt_local_x2apic *apic = |
55 | container_of(entry, struct acpi_madt_local_x2apic, header); | 54 | container_of(entry, struct acpi_madt_local_x2apic, header); |
56 | 55 | ||
57 | if (ignore_disabled && !(apic->lapic_flags & ACPI_MADT_ENABLED)) | 56 | if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) |
58 | return -ENODEV; | 57 | return -ENODEV; |
59 | 58 | ||
60 | if (device_declaration && (apic->uid == acpi_id)) { | 59 | if (device_declaration && (apic->uid == acpi_id)) { |
@@ -66,13 +65,12 @@ static int map_x2apic_id(struct acpi_subtable_header *entry, | |||
66 | } | 65 | } |
67 | 66 | ||
68 | static int map_lsapic_id(struct acpi_subtable_header *entry, | 67 | static int map_lsapic_id(struct acpi_subtable_header *entry, |
69 | int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id, | 68 | int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id) |
70 | bool ignore_disabled) | ||
71 | { | 69 | { |
72 | struct acpi_madt_local_sapic *lsapic = | 70 | struct acpi_madt_local_sapic *lsapic = |
73 | container_of(entry, struct acpi_madt_local_sapic, header); | 71 | container_of(entry, struct acpi_madt_local_sapic, header); |
74 | 72 | ||
75 | if (ignore_disabled && !(lsapic->lapic_flags & ACPI_MADT_ENABLED)) | 73 | if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED)) |
76 | return -ENODEV; | 74 | return -ENODEV; |
77 | 75 | ||
78 | if (device_declaration) { | 76 | if (device_declaration) { |
@@ -89,13 +87,12 @@ static int map_lsapic_id(struct acpi_subtable_header *entry, | |||
89 | * Retrieve the ARM CPU physical identifier (MPIDR) | 87 | * Retrieve the ARM CPU physical identifier (MPIDR) |
90 | */ | 88 | */ |
91 | static int map_gicc_mpidr(struct acpi_subtable_header *entry, | 89 | static int map_gicc_mpidr(struct acpi_subtable_header *entry, |
92 | int device_declaration, u32 acpi_id, phys_cpuid_t *mpidr, | 90 | int device_declaration, u32 acpi_id, phys_cpuid_t *mpidr) |
93 | bool ignore_disabled) | ||
94 | { | 91 | { |
95 | struct acpi_madt_generic_interrupt *gicc = | 92 | struct acpi_madt_generic_interrupt *gicc = |
96 | container_of(entry, struct acpi_madt_generic_interrupt, header); | 93 | container_of(entry, struct acpi_madt_generic_interrupt, header); |
97 | 94 | ||
98 | if (ignore_disabled && !(gicc->flags & ACPI_MADT_ENABLED)) | 95 | if (!(gicc->flags & ACPI_MADT_ENABLED)) |
99 | return -ENODEV; | 96 | return -ENODEV; |
100 | 97 | ||
101 | /* device_declaration means Device object in DSDT, in the | 98 | /* device_declaration means Device object in DSDT, in the |
@@ -112,7 +109,7 @@ static int map_gicc_mpidr(struct acpi_subtable_header *entry, | |||
112 | } | 109 | } |
113 | 110 | ||
114 | static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt, | 111 | static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt, |
115 | int type, u32 acpi_id, bool ignore_disabled) | 112 | int type, u32 acpi_id) |
116 | { | 113 | { |
117 | unsigned long madt_end, entry; | 114 | unsigned long madt_end, entry; |
118 | phys_cpuid_t phys_id = PHYS_CPUID_INVALID; /* CPU hardware ID */ | 115 | phys_cpuid_t phys_id = PHYS_CPUID_INVALID; /* CPU hardware ID */ |
@@ -130,20 +127,16 @@ static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt, | |||
130 | struct acpi_subtable_header *header = | 127 | struct acpi_subtable_header *header = |
131 | (struct acpi_subtable_header *)entry; | 128 | (struct acpi_subtable_header *)entry; |
132 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { | 129 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { |
133 | if (!map_lapic_id(header, acpi_id, &phys_id, | 130 | if (!map_lapic_id(header, acpi_id, &phys_id)) |
134 | ignore_disabled)) | ||
135 | break; | 131 | break; |
136 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) { | 132 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) { |
137 | if (!map_x2apic_id(header, type, acpi_id, &phys_id, | 133 | if (!map_x2apic_id(header, type, acpi_id, &phys_id)) |
138 | ignore_disabled)) | ||
139 | break; | 134 | break; |
140 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { | 135 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { |
141 | if (!map_lsapic_id(header, type, acpi_id, &phys_id, | 136 | if (!map_lsapic_id(header, type, acpi_id, &phys_id)) |
142 | ignore_disabled)) | ||
143 | break; | 137 | break; |
144 | } else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) { | 138 | } else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) { |
145 | if (!map_gicc_mpidr(header, type, acpi_id, &phys_id, | 139 | if (!map_gicc_mpidr(header, type, acpi_id, &phys_id)) |
146 | ignore_disabled)) | ||
147 | break; | 140 | break; |
148 | } | 141 | } |
149 | entry += header->length; | 142 | entry += header->length; |
@@ -161,15 +154,14 @@ phys_cpuid_t __init acpi_map_madt_entry(u32 acpi_id) | |||
161 | if (!madt) | 154 | if (!madt) |
162 | return PHYS_CPUID_INVALID; | 155 | return PHYS_CPUID_INVALID; |
163 | 156 | ||
164 | rv = map_madt_entry(madt, 1, acpi_id, true); | 157 | rv = map_madt_entry(madt, 1, acpi_id); |
165 | 158 | ||
166 | acpi_put_table((struct acpi_table_header *)madt); | 159 | acpi_put_table((struct acpi_table_header *)madt); |
167 | 160 | ||
168 | return rv; | 161 | return rv; |
169 | } | 162 | } |
170 | 163 | ||
171 | static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id, | 164 | static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id) |
172 | bool ignore_disabled) | ||
173 | { | 165 | { |
174 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 166 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
175 | union acpi_object *obj; | 167 | union acpi_object *obj; |
@@ -190,38 +182,30 @@ static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id, | |||
190 | 182 | ||
191 | header = (struct acpi_subtable_header *)obj->buffer.pointer; | 183 | header = (struct acpi_subtable_header *)obj->buffer.pointer; |
192 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) | 184 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) |
193 | map_lapic_id(header, acpi_id, &phys_id, ignore_disabled); | 185 | map_lapic_id(header, acpi_id, &phys_id); |
194 | else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) | 186 | else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) |
195 | map_lsapic_id(header, type, acpi_id, &phys_id, ignore_disabled); | 187 | map_lsapic_id(header, type, acpi_id, &phys_id); |
196 | else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) | 188 | else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) |
197 | map_x2apic_id(header, type, acpi_id, &phys_id, ignore_disabled); | 189 | map_x2apic_id(header, type, acpi_id, &phys_id); |
198 | else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) | 190 | else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) |
199 | map_gicc_mpidr(header, type, acpi_id, &phys_id, | 191 | map_gicc_mpidr(header, type, acpi_id, &phys_id); |
200 | ignore_disabled); | ||
201 | 192 | ||
202 | exit: | 193 | exit: |
203 | kfree(buffer.pointer); | 194 | kfree(buffer.pointer); |
204 | return phys_id; | 195 | return phys_id; |
205 | } | 196 | } |
206 | 197 | ||
207 | static phys_cpuid_t __acpi_get_phys_id(acpi_handle handle, int type, | 198 | phys_cpuid_t acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id) |
208 | u32 acpi_id, bool ignore_disabled) | ||
209 | { | 199 | { |
210 | phys_cpuid_t phys_id; | 200 | phys_cpuid_t phys_id; |
211 | 201 | ||
212 | phys_id = map_mat_entry(handle, type, acpi_id, ignore_disabled); | 202 | phys_id = map_mat_entry(handle, type, acpi_id); |
213 | if (invalid_phys_cpuid(phys_id)) | 203 | if (invalid_phys_cpuid(phys_id)) |
214 | phys_id = map_madt_entry(get_madt_table(), type, acpi_id, | 204 | phys_id = map_madt_entry(get_madt_table(), type, acpi_id); |
215 | ignore_disabled); | ||
216 | 205 | ||
217 | return phys_id; | 206 | return phys_id; |
218 | } | 207 | } |
219 | 208 | ||
220 | phys_cpuid_t acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id) | ||
221 | { | ||
222 | return __acpi_get_phys_id(handle, type, acpi_id, true); | ||
223 | } | ||
224 | |||
225 | int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id) | 209 | int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id) |
226 | { | 210 | { |
227 | #ifdef CONFIG_SMP | 211 | #ifdef CONFIG_SMP |
@@ -278,79 +262,6 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) | |||
278 | } | 262 | } |
279 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); | 263 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); |
280 | 264 | ||
281 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | ||
282 | static bool __init | ||
283 | map_processor(acpi_handle handle, phys_cpuid_t *phys_id, int *cpuid) | ||
284 | { | ||
285 | int type, id; | ||
286 | u32 acpi_id; | ||
287 | acpi_status status; | ||
288 | acpi_object_type acpi_type; | ||
289 | unsigned long long tmp; | ||
290 | union acpi_object object = { 0 }; | ||
291 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; | ||
292 | |||
293 | status = acpi_get_type(handle, &acpi_type); | ||
294 | if (ACPI_FAILURE(status)) | ||
295 | return false; | ||
296 | |||
297 | switch (acpi_type) { | ||
298 | case ACPI_TYPE_PROCESSOR: | ||
299 | status = acpi_evaluate_object(handle, NULL, NULL, &buffer); | ||
300 | if (ACPI_FAILURE(status)) | ||
301 | return false; | ||
302 | acpi_id = object.processor.proc_id; | ||
303 | |||
304 | /* validate the acpi_id */ | ||
305 | if(acpi_processor_validate_proc_id(acpi_id)) | ||
306 | return false; | ||
307 | break; | ||
308 | case ACPI_TYPE_DEVICE: | ||
309 | status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp); | ||
310 | if (ACPI_FAILURE(status)) | ||
311 | return false; | ||
312 | acpi_id = tmp; | ||
313 | break; | ||
314 | default: | ||
315 | return false; | ||
316 | } | ||
317 | |||
318 | type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; | ||
319 | |||
320 | *phys_id = __acpi_get_phys_id(handle, type, acpi_id, false); | ||
321 | id = acpi_map_cpuid(*phys_id, acpi_id); | ||
322 | |||
323 | if (id < 0) | ||
324 | return false; | ||
325 | *cpuid = id; | ||
326 | return true; | ||
327 | } | ||
328 | |||
329 | static acpi_status __init | ||
330 | set_processor_node_mapping(acpi_handle handle, u32 lvl, void *context, | ||
331 | void **rv) | ||
332 | { | ||
333 | phys_cpuid_t phys_id; | ||
334 | int cpu_id; | ||
335 | |||
336 | if (!map_processor(handle, &phys_id, &cpu_id)) | ||
337 | return AE_ERROR; | ||
338 | |||
339 | acpi_map_cpu2node(handle, cpu_id, phys_id); | ||
340 | return AE_OK; | ||
341 | } | ||
342 | |||
343 | void __init acpi_set_processor_mapping(void) | ||
344 | { | ||
345 | /* Set persistent cpu <-> node mapping for all processors. */ | ||
346 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, | ||
347 | ACPI_UINT32_MAX, set_processor_node_mapping, | ||
348 | NULL, NULL, NULL); | ||
349 | } | ||
350 | #else | ||
351 | void __init acpi_set_processor_mapping(void) {} | ||
352 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ | ||
353 | |||
354 | #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC | 265 | #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC |
355 | static int get_ioapic_id(struct acpi_subtable_header *entry, u32 gsi_base, | 266 | static int get_ioapic_id(struct acpi_subtable_header *entry, u32 gsi_base, |
356 | u64 *phys_addr, int *ioapic_id) | 267 | u64 *phys_addr, int *ioapic_id) |
diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 85d833289f28..4c96f3ac4976 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c | |||
@@ -177,7 +177,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) | |||
177 | case AHCI_LS1043A: | 177 | case AHCI_LS1043A: |
178 | if (!qpriv->ecc_addr) | 178 | if (!qpriv->ecc_addr) |
179 | return -EINVAL; | 179 | return -EINVAL; |
180 | writel(ECC_DIS_ARMV8_CH2, qpriv->ecc_addr); | 180 | writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2, |
181 | qpriv->ecc_addr); | ||
181 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); | 182 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); |
182 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); | 183 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); |
183 | if (qpriv->is_dmacoherent) | 184 | if (qpriv->is_dmacoherent) |
@@ -194,7 +195,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) | |||
194 | case AHCI_LS1046A: | 195 | case AHCI_LS1046A: |
195 | if (!qpriv->ecc_addr) | 196 | if (!qpriv->ecc_addr) |
196 | return -EINVAL; | 197 | return -EINVAL; |
197 | writel(ECC_DIS_ARMV8_CH2, qpriv->ecc_addr); | 198 | writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2, |
199 | qpriv->ecc_addr); | ||
198 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); | 200 | writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); |
199 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); | 201 | writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); |
200 | if (qpriv->is_dmacoherent) | 202 | if (qpriv->is_dmacoherent) |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 2bd92dca3e62..274d6d7193d7 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -1482,7 +1482,6 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) | |||
1482 | break; | 1482 | break; |
1483 | 1483 | ||
1484 | default: | 1484 | default: |
1485 | WARN_ON_ONCE(1); | ||
1486 | return AC_ERR_SYSTEM; | 1485 | return AC_ERR_SYSTEM; |
1487 | } | 1486 | } |
1488 | 1487 | ||
diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c index 46698232e6bf..19e6e539a061 100644 --- a/drivers/ata/libata-transport.c +++ b/drivers/ata/libata-transport.c | |||
@@ -224,7 +224,6 @@ static DECLARE_TRANSPORT_CLASS(ata_port_class, | |||
224 | 224 | ||
225 | static void ata_tport_release(struct device *dev) | 225 | static void ata_tport_release(struct device *dev) |
226 | { | 226 | { |
227 | put_device(dev->parent); | ||
228 | } | 227 | } |
229 | 228 | ||
230 | /** | 229 | /** |
@@ -284,7 +283,7 @@ int ata_tport_add(struct device *parent, | |||
284 | device_initialize(dev); | 283 | device_initialize(dev); |
285 | dev->type = &ata_port_type; | 284 | dev->type = &ata_port_type; |
286 | 285 | ||
287 | dev->parent = get_device(parent); | 286 | dev->parent = parent; |
288 | dev->release = ata_tport_release; | 287 | dev->release = ata_tport_release; |
289 | dev_set_name(dev, "ata%d", ap->print_id); | 288 | dev_set_name(dev, "ata%d", ap->print_id); |
290 | transport_setup_device(dev); | 289 | transport_setup_device(dev); |
@@ -348,7 +347,6 @@ static DECLARE_TRANSPORT_CLASS(ata_link_class, | |||
348 | 347 | ||
349 | static void ata_tlink_release(struct device *dev) | 348 | static void ata_tlink_release(struct device *dev) |
350 | { | 349 | { |
351 | put_device(dev->parent); | ||
352 | } | 350 | } |
353 | 351 | ||
354 | /** | 352 | /** |
@@ -410,7 +408,7 @@ int ata_tlink_add(struct ata_link *link) | |||
410 | int error; | 408 | int error; |
411 | 409 | ||
412 | device_initialize(dev); | 410 | device_initialize(dev); |
413 | dev->parent = get_device(&ap->tdev); | 411 | dev->parent = &ap->tdev; |
414 | dev->release = ata_tlink_release; | 412 | dev->release = ata_tlink_release; |
415 | if (ata_is_host_link(link)) | 413 | if (ata_is_host_link(link)) |
416 | dev_set_name(dev, "link%d", ap->print_id); | 414 | dev_set_name(dev, "link%d", ap->print_id); |
@@ -589,7 +587,6 @@ static DECLARE_TRANSPORT_CLASS(ata_dev_class, | |||
589 | 587 | ||
590 | static void ata_tdev_release(struct device *dev) | 588 | static void ata_tdev_release(struct device *dev) |
591 | { | 589 | { |
592 | put_device(dev->parent); | ||
593 | } | 590 | } |
594 | 591 | ||
595 | /** | 592 | /** |
@@ -662,7 +659,7 @@ static int ata_tdev_add(struct ata_device *ata_dev) | |||
662 | int error; | 659 | int error; |
663 | 660 | ||
664 | device_initialize(dev); | 661 | device_initialize(dev); |
665 | dev->parent = get_device(&link->tdev); | 662 | dev->parent = &link->tdev; |
666 | dev->release = ata_tdev_release; | 663 | dev->release = ata_tdev_release; |
667 | if (ata_is_host_link(link)) | 664 | if (ata_is_host_link(link)) |
668 | dev_set_name(dev, "dev%d.%d", ap->print_id,ata_dev->devno); | 665 | dev_set_name(dev, "dev%d.%d", ap->print_id,ata_dev->devno); |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 684bda4d14a1..6bb60fb6a30b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -639,11 +639,6 @@ int lock_device_hotplug_sysfs(void) | |||
639 | return restart_syscall(); | 639 | return restart_syscall(); |
640 | } | 640 | } |
641 | 641 | ||
642 | void assert_held_device_hotplug(void) | ||
643 | { | ||
644 | lockdep_assert_held(&device_hotplug_lock); | ||
645 | } | ||
646 | |||
647 | #ifdef CONFIG_BLOCK | 642 | #ifdef CONFIG_BLOCK |
648 | static inline int device_is_not_partition(struct device *dev) | 643 | static inline int device_is_not_partition(struct device *dev) |
649 | { | 644 | { |
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c index 3ad86fdf954e..b1ad12552b56 100644 --- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c | |||
@@ -397,9 +397,8 @@ static int of_get_omap_rng_device_details(struct omap_rng_dev *priv, | |||
397 | irq, err); | 397 | irq, err); |
398 | return err; | 398 | return err; |
399 | } | 399 | } |
400 | omap_rng_write(priv, RNG_INTMASK_REG, RNG_SHUTDOWN_OFLO_MASK); | ||
401 | 400 | ||
402 | priv->clk = of_clk_get(pdev->dev.of_node, 0); | 401 | priv->clk = devm_clk_get(&pdev->dev, NULL); |
403 | if (IS_ERR(priv->clk) && PTR_ERR(priv->clk) == -EPROBE_DEFER) | 402 | if (IS_ERR(priv->clk) && PTR_ERR(priv->clk) == -EPROBE_DEFER) |
404 | return -EPROBE_DEFER; | 403 | return -EPROBE_DEFER; |
405 | if (!IS_ERR(priv->clk)) { | 404 | if (!IS_ERR(priv->clk)) { |
@@ -408,6 +407,19 @@ static int of_get_omap_rng_device_details(struct omap_rng_dev *priv, | |||
408 | dev_err(&pdev->dev, "unable to enable the clk, " | 407 | dev_err(&pdev->dev, "unable to enable the clk, " |
409 | "err = %d\n", err); | 408 | "err = %d\n", err); |
410 | } | 409 | } |
410 | |||
411 | /* | ||
412 | * On OMAP4, enabling the shutdown_oflo interrupt is | ||
413 | * done in the interrupt mask register. There is no | ||
414 | * such register on EIP76, and it's enabled by the | ||
415 | * same bit in the control register | ||
416 | */ | ||
417 | if (priv->pdata->regs[RNG_INTMASK_REG]) | ||
418 | omap_rng_write(priv, RNG_INTMASK_REG, | ||
419 | RNG_SHUTDOWN_OFLO_MASK); | ||
420 | else | ||
421 | omap_rng_write(priv, RNG_CONTROL_REG, | ||
422 | RNG_SHUTDOWN_OFLO_MASK); | ||
411 | } | 423 | } |
412 | return 0; | 424 | return 0; |
413 | } | 425 | } |
diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c index 745844ee973e..d4ca9962a759 100644 --- a/drivers/clocksource/tcb_clksrc.c +++ b/drivers/clocksource/tcb_clksrc.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/io.h> | 10 | #include <linux/io.h> |
11 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
12 | #include <linux/atmel_tc.h> | 12 | #include <linux/atmel_tc.h> |
13 | #include <linux/sched_clock.h> | ||
14 | 13 | ||
15 | 14 | ||
16 | /* | 15 | /* |
@@ -57,14 +56,9 @@ static u64 tc_get_cycles(struct clocksource *cs) | |||
57 | return (upper << 16) | lower; | 56 | return (upper << 16) | lower; |
58 | } | 57 | } |
59 | 58 | ||
60 | static u32 tc_get_cv32(void) | ||
61 | { | ||
62 | return __raw_readl(tcaddr + ATMEL_TC_REG(0, CV)); | ||
63 | } | ||
64 | |||
65 | static u64 tc_get_cycles32(struct clocksource *cs) | 59 | static u64 tc_get_cycles32(struct clocksource *cs) |
66 | { | 60 | { |
67 | return tc_get_cv32(); | 61 | return __raw_readl(tcaddr + ATMEL_TC_REG(0, CV)); |
68 | } | 62 | } |
69 | 63 | ||
70 | static struct clocksource clksrc = { | 64 | static struct clocksource clksrc = { |
@@ -75,11 +69,6 @@ static struct clocksource clksrc = { | |||
75 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 69 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
76 | }; | 70 | }; |
77 | 71 | ||
78 | static u64 notrace tc_read_sched_clock(void) | ||
79 | { | ||
80 | return tc_get_cv32(); | ||
81 | } | ||
82 | |||
83 | #ifdef CONFIG_GENERIC_CLOCKEVENTS | 72 | #ifdef CONFIG_GENERIC_CLOCKEVENTS |
84 | 73 | ||
85 | struct tc_clkevt_device { | 74 | struct tc_clkevt_device { |
@@ -350,9 +339,6 @@ static int __init tcb_clksrc_init(void) | |||
350 | clksrc.read = tc_get_cycles32; | 339 | clksrc.read = tc_get_cycles32; |
351 | /* setup ony channel 0 */ | 340 | /* setup ony channel 0 */ |
352 | tcb_setup_single_chan(tc, best_divisor_idx); | 341 | tcb_setup_single_chan(tc, best_divisor_idx); |
353 | |||
354 | /* register sched_clock on chips with single 32 bit counter */ | ||
355 | sched_clock_register(tc_read_sched_clock, 32, divided_rate); | ||
356 | } else { | 342 | } else { |
357 | /* tclib will give us three clocks no matter what the | 343 | /* tclib will give us three clocks no matter what the |
358 | * underlying platform supports. | 344 | * underlying platform supports. |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 38b9fdf854a4..b8ff617d449d 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -680,9 +680,11 @@ static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy, | |||
680 | char *buf) | 680 | char *buf) |
681 | { | 681 | { |
682 | unsigned int cur_freq = __cpufreq_get(policy); | 682 | unsigned int cur_freq = __cpufreq_get(policy); |
683 | if (!cur_freq) | 683 | |
684 | return sprintf(buf, "<unknown>"); | 684 | if (cur_freq) |
685 | return sprintf(buf, "%u\n", cur_freq); | 685 | return sprintf(buf, "%u\n", cur_freq); |
686 | |||
687 | return sprintf(buf, "<unknown>\n"); | ||
686 | } | 688 | } |
687 | 689 | ||
688 | /** | 690 | /** |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 3d37219a0dd7..08e134ffba68 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -84,6 +84,11 @@ static inline u64 div_ext_fp(u64 x, u64 y) | |||
84 | return div64_u64(x << EXT_FRAC_BITS, y); | 84 | return div64_u64(x << EXT_FRAC_BITS, y); |
85 | } | 85 | } |
86 | 86 | ||
87 | static inline int32_t percent_ext_fp(int percent) | ||
88 | { | ||
89 | return div_ext_fp(percent, 100); | ||
90 | } | ||
91 | |||
87 | /** | 92 | /** |
88 | * struct sample - Store performance sample | 93 | * struct sample - Store performance sample |
89 | * @core_avg_perf: Ratio of APERF/MPERF which is the actual average | 94 | * @core_avg_perf: Ratio of APERF/MPERF which is the actual average |
@@ -845,12 +850,11 @@ static struct freq_attr *hwp_cpufreq_attrs[] = { | |||
845 | 850 | ||
846 | static void intel_pstate_hwp_set(struct cpufreq_policy *policy) | 851 | static void intel_pstate_hwp_set(struct cpufreq_policy *policy) |
847 | { | 852 | { |
848 | int min, hw_min, max, hw_max, cpu, range, adj_range; | 853 | int min, hw_min, max, hw_max, cpu; |
849 | struct perf_limits *perf_limits = limits; | 854 | struct perf_limits *perf_limits = limits; |
850 | u64 value, cap; | 855 | u64 value, cap; |
851 | 856 | ||
852 | for_each_cpu(cpu, policy->cpus) { | 857 | for_each_cpu(cpu, policy->cpus) { |
853 | int max_perf_pct, min_perf_pct; | ||
854 | struct cpudata *cpu_data = all_cpu_data[cpu]; | 858 | struct cpudata *cpu_data = all_cpu_data[cpu]; |
855 | s16 epp; | 859 | s16 epp; |
856 | 860 | ||
@@ -863,20 +867,15 @@ static void intel_pstate_hwp_set(struct cpufreq_policy *policy) | |||
863 | hw_max = HWP_GUARANTEED_PERF(cap); | 867 | hw_max = HWP_GUARANTEED_PERF(cap); |
864 | else | 868 | else |
865 | hw_max = HWP_HIGHEST_PERF(cap); | 869 | hw_max = HWP_HIGHEST_PERF(cap); |
866 | range = hw_max - hw_min; | ||
867 | 870 | ||
868 | max_perf_pct = perf_limits->max_perf_pct; | 871 | min = fp_ext_toint(hw_max * perf_limits->min_perf); |
869 | min_perf_pct = perf_limits->min_perf_pct; | ||
870 | 872 | ||
871 | rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value); | 873 | rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value); |
872 | adj_range = min_perf_pct * range / 100; | 874 | |
873 | min = hw_min + adj_range; | ||
874 | value &= ~HWP_MIN_PERF(~0L); | 875 | value &= ~HWP_MIN_PERF(~0L); |
875 | value |= HWP_MIN_PERF(min); | 876 | value |= HWP_MIN_PERF(min); |
876 | 877 | ||
877 | adj_range = max_perf_pct * range / 100; | 878 | max = fp_ext_toint(hw_max * perf_limits->max_perf); |
878 | max = hw_min + adj_range; | ||
879 | |||
880 | value &= ~HWP_MAX_PERF(~0L); | 879 | value &= ~HWP_MAX_PERF(~0L); |
881 | value |= HWP_MAX_PERF(max); | 880 | value |= HWP_MAX_PERF(max); |
882 | 881 | ||
@@ -989,6 +988,7 @@ static void intel_pstate_update_policies(void) | |||
989 | static int pid_param_set(void *data, u64 val) | 988 | static int pid_param_set(void *data, u64 val) |
990 | { | 989 | { |
991 | *(u32 *)data = val; | 990 | *(u32 *)data = val; |
991 | pid_params.sample_rate_ns = pid_params.sample_rate_ms * NSEC_PER_MSEC; | ||
992 | intel_pstate_reset_all_pid(); | 992 | intel_pstate_reset_all_pid(); |
993 | return 0; | 993 | return 0; |
994 | } | 994 | } |
@@ -1225,7 +1225,7 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b, | |||
1225 | limits->max_perf_pct); | 1225 | limits->max_perf_pct); |
1226 | limits->max_perf_pct = max(limits->min_perf_pct, | 1226 | limits->max_perf_pct = max(limits->min_perf_pct, |
1227 | limits->max_perf_pct); | 1227 | limits->max_perf_pct); |
1228 | limits->max_perf = div_ext_fp(limits->max_perf_pct, 100); | 1228 | limits->max_perf = percent_ext_fp(limits->max_perf_pct); |
1229 | 1229 | ||
1230 | intel_pstate_update_policies(); | 1230 | intel_pstate_update_policies(); |
1231 | 1231 | ||
@@ -1262,7 +1262,7 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b, | |||
1262 | limits->min_perf_pct); | 1262 | limits->min_perf_pct); |
1263 | limits->min_perf_pct = min(limits->max_perf_pct, | 1263 | limits->min_perf_pct = min(limits->max_perf_pct, |
1264 | limits->min_perf_pct); | 1264 | limits->min_perf_pct); |
1265 | limits->min_perf = div_ext_fp(limits->min_perf_pct, 100); | 1265 | limits->min_perf = percent_ext_fp(limits->min_perf_pct); |
1266 | 1266 | ||
1267 | intel_pstate_update_policies(); | 1267 | intel_pstate_update_policies(); |
1268 | 1268 | ||
@@ -2080,36 +2080,34 @@ static void intel_pstate_clear_update_util_hook(unsigned int cpu) | |||
2080 | static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy, | 2080 | static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy, |
2081 | struct perf_limits *limits) | 2081 | struct perf_limits *limits) |
2082 | { | 2082 | { |
2083 | int32_t max_policy_perf, min_policy_perf; | ||
2083 | 2084 | ||
2084 | limits->max_policy_pct = DIV_ROUND_UP(policy->max * 100, | 2085 | max_policy_perf = div_ext_fp(policy->max, policy->cpuinfo.max_freq); |
2085 | policy->cpuinfo.max_freq); | 2086 | max_policy_perf = clamp_t(int32_t, max_policy_perf, 0, int_ext_tofp(1)); |
2086 | limits->max_policy_pct = clamp_t(int, limits->max_policy_pct, 0, 100); | ||
2087 | if (policy->max == policy->min) { | 2087 | if (policy->max == policy->min) { |
2088 | limits->min_policy_pct = limits->max_policy_pct; | 2088 | min_policy_perf = max_policy_perf; |
2089 | } else { | 2089 | } else { |
2090 | limits->min_policy_pct = DIV_ROUND_UP(policy->min * 100, | 2090 | min_policy_perf = div_ext_fp(policy->min, |
2091 | policy->cpuinfo.max_freq); | 2091 | policy->cpuinfo.max_freq); |
2092 | limits->min_policy_pct = clamp_t(int, limits->min_policy_pct, | 2092 | min_policy_perf = clamp_t(int32_t, min_policy_perf, |
2093 | 0, 100); | 2093 | 0, max_policy_perf); |
2094 | } | 2094 | } |
2095 | 2095 | ||
2096 | /* Normalize user input to [min_policy_pct, max_policy_pct] */ | 2096 | /* Normalize user input to [min_perf, max_perf] */ |
2097 | limits->min_perf_pct = max(limits->min_policy_pct, | 2097 | limits->min_perf = max(min_policy_perf, |
2098 | limits->min_sysfs_pct); | 2098 | percent_ext_fp(limits->min_sysfs_pct)); |
2099 | limits->min_perf_pct = min(limits->max_policy_pct, | 2099 | limits->min_perf = min(limits->min_perf, max_policy_perf); |
2100 | limits->min_perf_pct); | 2100 | limits->max_perf = min(max_policy_perf, |
2101 | limits->max_perf_pct = min(limits->max_policy_pct, | 2101 | percent_ext_fp(limits->max_sysfs_pct)); |
2102 | limits->max_sysfs_pct); | 2102 | limits->max_perf = max(min_policy_perf, limits->max_perf); |
2103 | limits->max_perf_pct = max(limits->min_policy_pct, | ||
2104 | limits->max_perf_pct); | ||
2105 | 2103 | ||
2106 | /* Make sure min_perf_pct <= max_perf_pct */ | 2104 | /* Make sure min_perf <= max_perf */ |
2107 | limits->min_perf_pct = min(limits->max_perf_pct, limits->min_perf_pct); | 2105 | limits->min_perf = min(limits->min_perf, limits->max_perf); |
2108 | 2106 | ||
2109 | limits->min_perf = div_ext_fp(limits->min_perf_pct, 100); | ||
2110 | limits->max_perf = div_ext_fp(limits->max_perf_pct, 100); | ||
2111 | limits->max_perf = round_up(limits->max_perf, EXT_FRAC_BITS); | 2107 | limits->max_perf = round_up(limits->max_perf, EXT_FRAC_BITS); |
2112 | limits->min_perf = round_up(limits->min_perf, EXT_FRAC_BITS); | 2108 | limits->min_perf = round_up(limits->min_perf, EXT_FRAC_BITS); |
2109 | limits->max_perf_pct = fp_ext_toint(limits->max_perf * 100); | ||
2110 | limits->min_perf_pct = fp_ext_toint(limits->min_perf * 100); | ||
2113 | 2111 | ||
2114 | pr_debug("cpu:%d max_perf_pct:%d min_perf_pct:%d\n", policy->cpu, | 2112 | pr_debug("cpu:%d max_perf_pct:%d min_perf_pct:%d\n", policy->cpu, |
2115 | limits->max_perf_pct, limits->min_perf_pct); | 2113 | limits->max_perf_pct, limits->min_perf_pct); |
diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c index dce1af0ce85c..1b9da3dc799b 100644 --- a/drivers/crypto/s5p-sss.c +++ b/drivers/crypto/s5p-sss.c | |||
@@ -270,7 +270,7 @@ static void s5p_sg_copy_buf(void *buf, struct scatterlist *sg, | |||
270 | scatterwalk_done(&walk, out, 0); | 270 | scatterwalk_done(&walk, out, 0); |
271 | } | 271 | } |
272 | 272 | ||
273 | static void s5p_aes_complete(struct s5p_aes_dev *dev, int err) | 273 | static void s5p_sg_done(struct s5p_aes_dev *dev) |
274 | { | 274 | { |
275 | if (dev->sg_dst_cpy) { | 275 | if (dev->sg_dst_cpy) { |
276 | dev_dbg(dev->dev, | 276 | dev_dbg(dev->dev, |
@@ -281,8 +281,11 @@ static void s5p_aes_complete(struct s5p_aes_dev *dev, int err) | |||
281 | } | 281 | } |
282 | s5p_free_sg_cpy(dev, &dev->sg_src_cpy); | 282 | s5p_free_sg_cpy(dev, &dev->sg_src_cpy); |
283 | s5p_free_sg_cpy(dev, &dev->sg_dst_cpy); | 283 | s5p_free_sg_cpy(dev, &dev->sg_dst_cpy); |
284 | } | ||
284 | 285 | ||
285 | /* holding a lock outside */ | 286 | /* Calls the completion. Cannot be called with dev->lock hold. */ |
287 | static void s5p_aes_complete(struct s5p_aes_dev *dev, int err) | ||
288 | { | ||
286 | dev->req->base.complete(&dev->req->base, err); | 289 | dev->req->base.complete(&dev->req->base, err); |
287 | dev->busy = false; | 290 | dev->busy = false; |
288 | } | 291 | } |
@@ -368,51 +371,44 @@ exit: | |||
368 | } | 371 | } |
369 | 372 | ||
370 | /* | 373 | /* |
371 | * Returns true if new transmitting (output) data is ready and its | 374 | * Returns -ERRNO on error (mapping of new data failed). |
372 | * address+length have to be written to device (by calling | 375 | * On success returns: |
373 | * s5p_set_dma_outdata()). False otherwise. | 376 | * - 0 if there is no more data, |
377 | * - 1 if new transmitting (output) data is ready and its address+length | ||
378 | * have to be written to device (by calling s5p_set_dma_outdata()). | ||
374 | */ | 379 | */ |
375 | static bool s5p_aes_tx(struct s5p_aes_dev *dev) | 380 | static int s5p_aes_tx(struct s5p_aes_dev *dev) |
376 | { | 381 | { |
377 | int err = 0; | 382 | int ret = 0; |
378 | bool ret = false; | ||
379 | 383 | ||
380 | s5p_unset_outdata(dev); | 384 | s5p_unset_outdata(dev); |
381 | 385 | ||
382 | if (!sg_is_last(dev->sg_dst)) { | 386 | if (!sg_is_last(dev->sg_dst)) { |
383 | err = s5p_set_outdata(dev, sg_next(dev->sg_dst)); | 387 | ret = s5p_set_outdata(dev, sg_next(dev->sg_dst)); |
384 | if (err) | 388 | if (!ret) |
385 | s5p_aes_complete(dev, err); | 389 | ret = 1; |
386 | else | ||
387 | ret = true; | ||
388 | } else { | ||
389 | s5p_aes_complete(dev, err); | ||
390 | |||
391 | dev->busy = true; | ||
392 | tasklet_schedule(&dev->tasklet); | ||
393 | } | 390 | } |
394 | 391 | ||
395 | return ret; | 392 | return ret; |
396 | } | 393 | } |
397 | 394 | ||
398 | /* | 395 | /* |
399 | * Returns true if new receiving (input) data is ready and its | 396 | * Returns -ERRNO on error (mapping of new data failed). |
400 | * address+length have to be written to device (by calling | 397 | * On success returns: |
401 | * s5p_set_dma_indata()). False otherwise. | 398 | * - 0 if there is no more data, |
399 | * - 1 if new receiving (input) data is ready and its address+length | ||
400 | * have to be written to device (by calling s5p_set_dma_indata()). | ||
402 | */ | 401 | */ |
403 | static bool s5p_aes_rx(struct s5p_aes_dev *dev) | 402 | static int s5p_aes_rx(struct s5p_aes_dev *dev/*, bool *set_dma*/) |
404 | { | 403 | { |
405 | int err; | 404 | int ret = 0; |
406 | bool ret = false; | ||
407 | 405 | ||
408 | s5p_unset_indata(dev); | 406 | s5p_unset_indata(dev); |
409 | 407 | ||
410 | if (!sg_is_last(dev->sg_src)) { | 408 | if (!sg_is_last(dev->sg_src)) { |
411 | err = s5p_set_indata(dev, sg_next(dev->sg_src)); | 409 | ret = s5p_set_indata(dev, sg_next(dev->sg_src)); |
412 | if (err) | 410 | if (!ret) |
413 | s5p_aes_complete(dev, err); | 411 | ret = 1; |
414 | else | ||
415 | ret = true; | ||
416 | } | 412 | } |
417 | 413 | ||
418 | return ret; | 414 | return ret; |
@@ -422,33 +418,73 @@ static irqreturn_t s5p_aes_interrupt(int irq, void *dev_id) | |||
422 | { | 418 | { |
423 | struct platform_device *pdev = dev_id; | 419 | struct platform_device *pdev = dev_id; |
424 | struct s5p_aes_dev *dev = platform_get_drvdata(pdev); | 420 | struct s5p_aes_dev *dev = platform_get_drvdata(pdev); |
425 | bool set_dma_tx = false; | 421 | int err_dma_tx = 0; |
426 | bool set_dma_rx = false; | 422 | int err_dma_rx = 0; |
423 | bool tx_end = false; | ||
427 | unsigned long flags; | 424 | unsigned long flags; |
428 | uint32_t status; | 425 | uint32_t status; |
426 | int err; | ||
429 | 427 | ||
430 | spin_lock_irqsave(&dev->lock, flags); | 428 | spin_lock_irqsave(&dev->lock, flags); |
431 | 429 | ||
430 | /* | ||
431 | * Handle rx or tx interrupt. If there is still data (scatterlist did not | ||
432 | * reach end), then map next scatterlist entry. | ||
433 | * In case of such mapping error, s5p_aes_complete() should be called. | ||
434 | * | ||
435 | * If there is no more data in tx scatter list, call s5p_aes_complete() | ||
436 | * and schedule new tasklet. | ||
437 | */ | ||
432 | status = SSS_READ(dev, FCINTSTAT); | 438 | status = SSS_READ(dev, FCINTSTAT); |
433 | if (status & SSS_FCINTSTAT_BRDMAINT) | 439 | if (status & SSS_FCINTSTAT_BRDMAINT) |
434 | set_dma_rx = s5p_aes_rx(dev); | 440 | err_dma_rx = s5p_aes_rx(dev); |
435 | if (status & SSS_FCINTSTAT_BTDMAINT) | 441 | |
436 | set_dma_tx = s5p_aes_tx(dev); | 442 | if (status & SSS_FCINTSTAT_BTDMAINT) { |
443 | if (sg_is_last(dev->sg_dst)) | ||
444 | tx_end = true; | ||
445 | err_dma_tx = s5p_aes_tx(dev); | ||
446 | } | ||
437 | 447 | ||
438 | SSS_WRITE(dev, FCINTPEND, status); | 448 | SSS_WRITE(dev, FCINTPEND, status); |
439 | 449 | ||
440 | /* | 450 | if (err_dma_rx < 0) { |
441 | * Writing length of DMA block (either receiving or transmitting) | 451 | err = err_dma_rx; |
442 | * will start the operation immediately, so this should be done | 452 | goto error; |
443 | * at the end (even after clearing pending interrupts to not miss the | 453 | } |
444 | * interrupt). | 454 | if (err_dma_tx < 0) { |
445 | */ | 455 | err = err_dma_tx; |
446 | if (set_dma_tx) | 456 | goto error; |
447 | s5p_set_dma_outdata(dev, dev->sg_dst); | 457 | } |
448 | if (set_dma_rx) | 458 | |
449 | s5p_set_dma_indata(dev, dev->sg_src); | 459 | if (tx_end) { |
460 | s5p_sg_done(dev); | ||
461 | |||
462 | spin_unlock_irqrestore(&dev->lock, flags); | ||
463 | |||
464 | s5p_aes_complete(dev, 0); | ||
465 | dev->busy = true; | ||
466 | tasklet_schedule(&dev->tasklet); | ||
467 | } else { | ||
468 | /* | ||
469 | * Writing length of DMA block (either receiving or | ||
470 | * transmitting) will start the operation immediately, so this | ||
471 | * should be done at the end (even after clearing pending | ||
472 | * interrupts to not miss the interrupt). | ||
473 | */ | ||
474 | if (err_dma_tx == 1) | ||
475 | s5p_set_dma_outdata(dev, dev->sg_dst); | ||
476 | if (err_dma_rx == 1) | ||
477 | s5p_set_dma_indata(dev, dev->sg_src); | ||
450 | 478 | ||
479 | spin_unlock_irqrestore(&dev->lock, flags); | ||
480 | } | ||
481 | |||
482 | return IRQ_HANDLED; | ||
483 | |||
484 | error: | ||
485 | s5p_sg_done(dev); | ||
451 | spin_unlock_irqrestore(&dev->lock, flags); | 486 | spin_unlock_irqrestore(&dev->lock, flags); |
487 | s5p_aes_complete(dev, err); | ||
452 | 488 | ||
453 | return IRQ_HANDLED; | 489 | return IRQ_HANDLED; |
454 | } | 490 | } |
@@ -597,8 +633,9 @@ outdata_error: | |||
597 | s5p_unset_indata(dev); | 633 | s5p_unset_indata(dev); |
598 | 634 | ||
599 | indata_error: | 635 | indata_error: |
600 | s5p_aes_complete(dev, err); | 636 | s5p_sg_done(dev); |
601 | spin_unlock_irqrestore(&dev->lock, flags); | 637 | spin_unlock_irqrestore(&dev->lock, flags); |
638 | s5p_aes_complete(dev, err); | ||
602 | } | 639 | } |
603 | 640 | ||
604 | static void s5p_tasklet_cb(unsigned long data) | 641 | static void s5p_tasklet_cb(unsigned long data) |
@@ -805,8 +842,9 @@ static int s5p_aes_probe(struct platform_device *pdev) | |||
805 | dev_warn(dev, "feed control interrupt is not available.\n"); | 842 | dev_warn(dev, "feed control interrupt is not available.\n"); |
806 | goto err_irq; | 843 | goto err_irq; |
807 | } | 844 | } |
808 | err = devm_request_irq(dev, pdata->irq_fc, s5p_aes_interrupt, | 845 | err = devm_request_threaded_irq(dev, pdata->irq_fc, NULL, |
809 | IRQF_SHARED, pdev->name, pdev); | 846 | s5p_aes_interrupt, IRQF_ONESHOT, |
847 | pdev->name, pdev); | ||
810 | if (err < 0) { | 848 | if (err < 0) { |
811 | dev_warn(dev, "feed control interrupt is not available.\n"); | 849 | dev_warn(dev, "feed control interrupt is not available.\n"); |
812 | goto err_irq; | 850 | goto err_irq; |
diff --git a/drivers/dax/dax.c b/drivers/dax/dax.c index 8d9829ff2a78..80c6db279ae1 100644 --- a/drivers/dax/dax.c +++ b/drivers/dax/dax.c | |||
@@ -427,6 +427,7 @@ static int __dax_dev_pte_fault(struct dax_dev *dax_dev, struct vm_fault *vmf) | |||
427 | int rc = VM_FAULT_SIGBUS; | 427 | int rc = VM_FAULT_SIGBUS; |
428 | phys_addr_t phys; | 428 | phys_addr_t phys; |
429 | pfn_t pfn; | 429 | pfn_t pfn; |
430 | unsigned int fault_size = PAGE_SIZE; | ||
430 | 431 | ||
431 | if (check_vma(dax_dev, vmf->vma, __func__)) | 432 | if (check_vma(dax_dev, vmf->vma, __func__)) |
432 | return VM_FAULT_SIGBUS; | 433 | return VM_FAULT_SIGBUS; |
@@ -437,9 +438,12 @@ static int __dax_dev_pte_fault(struct dax_dev *dax_dev, struct vm_fault *vmf) | |||
437 | return VM_FAULT_SIGBUS; | 438 | return VM_FAULT_SIGBUS; |
438 | } | 439 | } |
439 | 440 | ||
441 | if (fault_size != dax_region->align) | ||
442 | return VM_FAULT_SIGBUS; | ||
443 | |||
440 | phys = pgoff_to_phys(dax_dev, vmf->pgoff, PAGE_SIZE); | 444 | phys = pgoff_to_phys(dax_dev, vmf->pgoff, PAGE_SIZE); |
441 | if (phys == -1) { | 445 | if (phys == -1) { |
442 | dev_dbg(dev, "%s: phys_to_pgoff(%#lx) failed\n", __func__, | 446 | dev_dbg(dev, "%s: pgoff_to_phys(%#lx) failed\n", __func__, |
443 | vmf->pgoff); | 447 | vmf->pgoff); |
444 | return VM_FAULT_SIGBUS; | 448 | return VM_FAULT_SIGBUS; |
445 | } | 449 | } |
@@ -464,6 +468,7 @@ static int __dax_dev_pmd_fault(struct dax_dev *dax_dev, struct vm_fault *vmf) | |||
464 | phys_addr_t phys; | 468 | phys_addr_t phys; |
465 | pgoff_t pgoff; | 469 | pgoff_t pgoff; |
466 | pfn_t pfn; | 470 | pfn_t pfn; |
471 | unsigned int fault_size = PMD_SIZE; | ||
467 | 472 | ||
468 | if (check_vma(dax_dev, vmf->vma, __func__)) | 473 | if (check_vma(dax_dev, vmf->vma, __func__)) |
469 | return VM_FAULT_SIGBUS; | 474 | return VM_FAULT_SIGBUS; |
@@ -480,10 +485,20 @@ static int __dax_dev_pmd_fault(struct dax_dev *dax_dev, struct vm_fault *vmf) | |||
480 | return VM_FAULT_SIGBUS; | 485 | return VM_FAULT_SIGBUS; |
481 | } | 486 | } |
482 | 487 | ||
488 | if (fault_size < dax_region->align) | ||
489 | return VM_FAULT_SIGBUS; | ||
490 | else if (fault_size > dax_region->align) | ||
491 | return VM_FAULT_FALLBACK; | ||
492 | |||
493 | /* if we are outside of the VMA */ | ||
494 | if (pmd_addr < vmf->vma->vm_start || | ||
495 | (pmd_addr + PMD_SIZE) > vmf->vma->vm_end) | ||
496 | return VM_FAULT_SIGBUS; | ||
497 | |||
483 | pgoff = linear_page_index(vmf->vma, pmd_addr); | 498 | pgoff = linear_page_index(vmf->vma, pmd_addr); |
484 | phys = pgoff_to_phys(dax_dev, pgoff, PMD_SIZE); | 499 | phys = pgoff_to_phys(dax_dev, pgoff, PMD_SIZE); |
485 | if (phys == -1) { | 500 | if (phys == -1) { |
486 | dev_dbg(dev, "%s: phys_to_pgoff(%#lx) failed\n", __func__, | 501 | dev_dbg(dev, "%s: pgoff_to_phys(%#lx) failed\n", __func__, |
487 | pgoff); | 502 | pgoff); |
488 | return VM_FAULT_SIGBUS; | 503 | return VM_FAULT_SIGBUS; |
489 | } | 504 | } |
@@ -503,6 +518,8 @@ static int __dax_dev_pud_fault(struct dax_dev *dax_dev, struct vm_fault *vmf) | |||
503 | phys_addr_t phys; | 518 | phys_addr_t phys; |
504 | pgoff_t pgoff; | 519 | pgoff_t pgoff; |
505 | pfn_t pfn; | 520 | pfn_t pfn; |
521 | unsigned int fault_size = PUD_SIZE; | ||
522 | |||
506 | 523 | ||
507 | if (check_vma(dax_dev, vmf->vma, __func__)) | 524 | if (check_vma(dax_dev, vmf->vma, __func__)) |
508 | return VM_FAULT_SIGBUS; | 525 | return VM_FAULT_SIGBUS; |
@@ -519,10 +536,20 @@ static int __dax_dev_pud_fault(struct dax_dev *dax_dev, struct vm_fault *vmf) | |||
519 | return VM_FAULT_SIGBUS; | 536 | return VM_FAULT_SIGBUS; |
520 | } | 537 | } |
521 | 538 | ||
539 | if (fault_size < dax_region->align) | ||
540 | return VM_FAULT_SIGBUS; | ||
541 | else if (fault_size > dax_region->align) | ||
542 | return VM_FAULT_FALLBACK; | ||
543 | |||
544 | /* if we are outside of the VMA */ | ||
545 | if (pud_addr < vmf->vma->vm_start || | ||
546 | (pud_addr + PUD_SIZE) > vmf->vma->vm_end) | ||
547 | return VM_FAULT_SIGBUS; | ||
548 | |||
522 | pgoff = linear_page_index(vmf->vma, pud_addr); | 549 | pgoff = linear_page_index(vmf->vma, pud_addr); |
523 | phys = pgoff_to_phys(dax_dev, pgoff, PUD_SIZE); | 550 | phys = pgoff_to_phys(dax_dev, pgoff, PUD_SIZE); |
524 | if (phys == -1) { | 551 | if (phys == -1) { |
525 | dev_dbg(dev, "%s: phys_to_pgoff(%#lx) failed\n", __func__, | 552 | dev_dbg(dev, "%s: pgoff_to_phys(%#lx) failed\n", __func__, |
526 | pgoff); | 553 | pgoff); |
527 | return VM_FAULT_SIGBUS; | 554 | return VM_FAULT_SIGBUS; |
528 | } | 555 | } |
diff --git a/drivers/gpu/drm/amd/acp/Makefile b/drivers/gpu/drm/amd/acp/Makefile index 8363cb57915b..8a08e81ee90d 100644 --- a/drivers/gpu/drm/amd/acp/Makefile +++ b/drivers/gpu/drm/amd/acp/Makefile | |||
@@ -3,6 +3,4 @@ | |||
3 | # of AMDSOC/AMDGPU drm driver. | 3 | # of AMDSOC/AMDGPU drm driver. |
4 | # It provides the HW control for ACP related functionalities. | 4 | # It provides the HW control for ACP related functionalities. |
5 | 5 | ||
6 | subdir-ccflags-y += -I$(AMDACPPATH)/ -I$(AMDACPPATH)/include | ||
7 | |||
8 | AMD_ACP_FILES := $(AMDACPPATH)/acp_hw.o | 6 | AMD_ACP_FILES := $(AMDACPPATH)/acp_hw.o |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index d2d0f60ff36d..99424cb8020b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -240,6 +240,8 @@ free_partial_kdata: | |||
240 | for (; i >= 0; i--) | 240 | for (; i >= 0; i--) |
241 | drm_free_large(p->chunks[i].kdata); | 241 | drm_free_large(p->chunks[i].kdata); |
242 | kfree(p->chunks); | 242 | kfree(p->chunks); |
243 | p->chunks = NULL; | ||
244 | p->nchunks = 0; | ||
243 | put_ctx: | 245 | put_ctx: |
244 | amdgpu_ctx_put(p->ctx); | 246 | amdgpu_ctx_put(p->ctx); |
245 | free_chunk: | 247 | free_chunk: |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 4120b351a8e5..a3a105ec99e2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | |||
@@ -2590,7 +2590,7 @@ static ssize_t amdgpu_debugfs_regs_read(struct file *f, char __user *buf, | |||
2590 | use_bank = 0; | 2590 | use_bank = 0; |
2591 | } | 2591 | } |
2592 | 2592 | ||
2593 | *pos &= 0x3FFFF; | 2593 | *pos &= (1UL << 22) - 1; |
2594 | 2594 | ||
2595 | if (use_bank) { | 2595 | if (use_bank) { |
2596 | if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) || | 2596 | if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) || |
@@ -2666,7 +2666,7 @@ static ssize_t amdgpu_debugfs_regs_write(struct file *f, const char __user *buf, | |||
2666 | use_bank = 0; | 2666 | use_bank = 0; |
2667 | } | 2667 | } |
2668 | 2668 | ||
2669 | *pos &= 0x3FFFF; | 2669 | *pos &= (1UL << 22) - 1; |
2670 | 2670 | ||
2671 | if (use_bank) { | 2671 | if (use_bank) { |
2672 | if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) || | 2672 | if ((sh_bank != 0xFFFFFFFF && sh_bank >= adev->gfx.config.max_sh_per_se) || |
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index f55e45b52fbc..33b504bafb88 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c | |||
@@ -3464,6 +3464,12 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev, | |||
3464 | (adev->pdev->device == 0x6667)) { | 3464 | (adev->pdev->device == 0x6667)) { |
3465 | max_sclk = 75000; | 3465 | max_sclk = 75000; |
3466 | } | 3466 | } |
3467 | } else if (adev->asic_type == CHIP_OLAND) { | ||
3468 | if ((adev->pdev->device == 0x6604) && | ||
3469 | (adev->pdev->subsystem_vendor == 0x1028) && | ||
3470 | (adev->pdev->subsystem_device == 0x066F)) { | ||
3471 | max_sclk = 75000; | ||
3472 | } | ||
3467 | } | 3473 | } |
3468 | 3474 | ||
3469 | if (rps->vce_active) { | 3475 | if (rps->vce_active) { |
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 50bdb24ef8d6..4a785d6acfb9 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c | |||
@@ -1051,7 +1051,7 @@ static int vi_common_early_init(void *handle) | |||
1051 | /* rev0 hardware requires workarounds to support PG */ | 1051 | /* rev0 hardware requires workarounds to support PG */ |
1052 | adev->pg_flags = 0; | 1052 | adev->pg_flags = 0; |
1053 | if (adev->rev_id != 0x00) { | 1053 | if (adev->rev_id != 0x00) { |
1054 | adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG | | 1054 | adev->pg_flags |= |
1055 | AMD_PG_SUPPORT_GFX_SMG | | 1055 | AMD_PG_SUPPORT_GFX_SMG | |
1056 | AMD_PG_SUPPORT_GFX_PIPELINE | | 1056 | AMD_PG_SUPPORT_GFX_PIPELINE | |
1057 | AMD_PG_SUPPORT_CP | | 1057 | AMD_PG_SUPPORT_CP | |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c index 8cf71f3c6d0e..261b828ad590 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_clockpowergating.c | |||
@@ -178,7 +178,7 @@ int smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate) | |||
178 | if (bgate) { | 178 | if (bgate) { |
179 | cgs_set_powergating_state(hwmgr->device, | 179 | cgs_set_powergating_state(hwmgr->device, |
180 | AMD_IP_BLOCK_TYPE_VCE, | 180 | AMD_IP_BLOCK_TYPE_VCE, |
181 | AMD_PG_STATE_UNGATE); | 181 | AMD_PG_STATE_GATE); |
182 | cgs_set_clockgating_state(hwmgr->device, | 182 | cgs_set_clockgating_state(hwmgr->device, |
183 | AMD_IP_BLOCK_TYPE_VCE, | 183 | AMD_IP_BLOCK_TYPE_VCE, |
184 | AMD_CG_STATE_GATE); | 184 | AMD_CG_STATE_GATE); |
diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c index 08e6a71f5d05..294b53697334 100644 --- a/drivers/gpu/drm/arm/malidp_crtc.c +++ b/drivers/gpu/drm/arm/malidp_crtc.c | |||
@@ -63,8 +63,7 @@ static void malidp_crtc_enable(struct drm_crtc *crtc) | |||
63 | 63 | ||
64 | clk_prepare_enable(hwdev->pxlclk); | 64 | clk_prepare_enable(hwdev->pxlclk); |
65 | 65 | ||
66 | /* mclk needs to be set to the same or higher rate than pxlclk */ | 66 | /* We rely on firmware to set mclk to a sensible level. */ |
67 | clk_set_rate(hwdev->mclk, crtc->state->adjusted_mode.crtc_clock * 1000); | ||
68 | clk_set_rate(hwdev->pxlclk, crtc->state->adjusted_mode.crtc_clock * 1000); | 67 | clk_set_rate(hwdev->pxlclk, crtc->state->adjusted_mode.crtc_clock * 1000); |
69 | 68 | ||
70 | hwdev->modeset(hwdev, &vm); | 69 | hwdev->modeset(hwdev, &vm); |
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c index 488aedf5b58d..9f5513006eee 100644 --- a/drivers/gpu/drm/arm/malidp_hw.c +++ b/drivers/gpu/drm/arm/malidp_hw.c | |||
@@ -83,7 +83,7 @@ static const struct malidp_layer malidp550_layers[] = { | |||
83 | { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, MALIDP_DE_LV_STRIDE0 }, | 83 | { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, MALIDP_DE_LV_STRIDE0 }, |
84 | { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, MALIDP_DE_LG_STRIDE }, | 84 | { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, MALIDP_DE_LG_STRIDE }, |
85 | { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, MALIDP_DE_LV_STRIDE0 }, | 85 | { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, MALIDP_DE_LV_STRIDE0 }, |
86 | { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, 0 }, | 86 | { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, MALIDP550_DE_LS_R1_STRIDE }, |
87 | }; | 87 | }; |
88 | 88 | ||
89 | #define MALIDP_DE_DEFAULT_PREFETCH_START 5 | 89 | #define MALIDP_DE_DEFAULT_PREFETCH_START 5 |
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index 414aada10fe5..d5aec082294c 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #define LAYER_V_VAL(x) (((x) & 0x1fff) << 16) | 37 | #define LAYER_V_VAL(x) (((x) & 0x1fff) << 16) |
38 | #define MALIDP_LAYER_COMP_SIZE 0x010 | 38 | #define MALIDP_LAYER_COMP_SIZE 0x010 |
39 | #define MALIDP_LAYER_OFFSET 0x014 | 39 | #define MALIDP_LAYER_OFFSET 0x014 |
40 | #define MALIDP550_LS_ENABLE 0x01c | ||
41 | #define MALIDP550_LS_R1_IN_SIZE 0x020 | ||
40 | 42 | ||
41 | /* | 43 | /* |
42 | * This 4-entry look-up-table is used to determine the full 8-bit alpha value | 44 | * This 4-entry look-up-table is used to determine the full 8-bit alpha value |
@@ -242,6 +244,11 @@ static void malidp_de_plane_update(struct drm_plane *plane, | |||
242 | LAYER_V_VAL(plane->state->crtc_y), | 244 | LAYER_V_VAL(plane->state->crtc_y), |
243 | mp->layer->base + MALIDP_LAYER_OFFSET); | 245 | mp->layer->base + MALIDP_LAYER_OFFSET); |
244 | 246 | ||
247 | if (mp->layer->id == DE_SMART) | ||
248 | malidp_hw_write(mp->hwdev, | ||
249 | LAYER_H_VAL(src_w) | LAYER_V_VAL(src_h), | ||
250 | mp->layer->base + MALIDP550_LS_R1_IN_SIZE); | ||
251 | |||
245 | /* first clear the rotation bits */ | 252 | /* first clear the rotation bits */ |
246 | val = malidp_hw_read(mp->hwdev, mp->layer->base + MALIDP_LAYER_CONTROL); | 253 | val = malidp_hw_read(mp->hwdev, mp->layer->base + MALIDP_LAYER_CONTROL); |
247 | val &= ~LAYER_ROT_MASK; | 254 | val &= ~LAYER_ROT_MASK; |
@@ -330,9 +337,16 @@ int malidp_de_planes_init(struct drm_device *drm) | |||
330 | plane->hwdev = malidp->dev; | 337 | plane->hwdev = malidp->dev; |
331 | plane->layer = &map->layers[i]; | 338 | plane->layer = &map->layers[i]; |
332 | 339 | ||
333 | /* Skip the features which the SMART layer doesn't have */ | 340 | if (id == DE_SMART) { |
334 | if (id == DE_SMART) | 341 | /* |
342 | * Enable the first rectangle in the SMART layer to be | ||
343 | * able to use it as a drm plane. | ||
344 | */ | ||
345 | malidp_hw_write(malidp->dev, 1, | ||
346 | plane->layer->base + MALIDP550_LS_ENABLE); | ||
347 | /* Skip the features which the SMART layer doesn't have. */ | ||
335 | continue; | 348 | continue; |
349 | } | ||
336 | 350 | ||
337 | drm_plane_create_rotation_property(&plane->base, DRM_ROTATE_0, flags); | 351 | drm_plane_create_rotation_property(&plane->base, DRM_ROTATE_0, flags); |
338 | malidp_hw_write(malidp->dev, MALIDP_ALPHA_LUT, | 352 | malidp_hw_write(malidp->dev, MALIDP_ALPHA_LUT, |
diff --git a/drivers/gpu/drm/arm/malidp_regs.h b/drivers/gpu/drm/arm/malidp_regs.h index aff6d4a84e99..b816067a65c5 100644 --- a/drivers/gpu/drm/arm/malidp_regs.h +++ b/drivers/gpu/drm/arm/malidp_regs.h | |||
@@ -84,6 +84,7 @@ | |||
84 | /* Stride register offsets relative to Lx_BASE */ | 84 | /* Stride register offsets relative to Lx_BASE */ |
85 | #define MALIDP_DE_LG_STRIDE 0x18 | 85 | #define MALIDP_DE_LG_STRIDE 0x18 |
86 | #define MALIDP_DE_LV_STRIDE0 0x18 | 86 | #define MALIDP_DE_LV_STRIDE0 0x18 |
87 | #define MALIDP550_DE_LS_R1_STRIDE 0x28 | ||
87 | 88 | ||
88 | /* macros to set values into registers */ | 89 | /* macros to set values into registers */ |
89 | #define MALIDP_DE_H_FRONTPORCH(x) (((x) & 0xfff) << 0) | 90 | #define MALIDP_DE_H_FRONTPORCH(x) (((x) & 0xfff) << 0) |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0a4b42d31391..7febe6eecf72 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -293,6 +293,7 @@ enum plane_id { | |||
293 | PLANE_PRIMARY, | 293 | PLANE_PRIMARY, |
294 | PLANE_SPRITE0, | 294 | PLANE_SPRITE0, |
295 | PLANE_SPRITE1, | 295 | PLANE_SPRITE1, |
296 | PLANE_SPRITE2, | ||
296 | PLANE_CURSOR, | 297 | PLANE_CURSOR, |
297 | I915_MAX_PLANES, | 298 | I915_MAX_PLANES, |
298 | }; | 299 | }; |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6908123162d1..10777da73039 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1434,6 +1434,12 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
1434 | 1434 | ||
1435 | trace_i915_gem_object_pwrite(obj, args->offset, args->size); | 1435 | trace_i915_gem_object_pwrite(obj, args->offset, args->size); |
1436 | 1436 | ||
1437 | ret = -ENODEV; | ||
1438 | if (obj->ops->pwrite) | ||
1439 | ret = obj->ops->pwrite(obj, args); | ||
1440 | if (ret != -ENODEV) | ||
1441 | goto err; | ||
1442 | |||
1437 | ret = i915_gem_object_wait(obj, | 1443 | ret = i915_gem_object_wait(obj, |
1438 | I915_WAIT_INTERRUPTIBLE | | 1444 | I915_WAIT_INTERRUPTIBLE | |
1439 | I915_WAIT_ALL, | 1445 | I915_WAIT_ALL, |
@@ -2119,6 +2125,7 @@ i915_gem_object_truncate(struct drm_i915_gem_object *obj) | |||
2119 | */ | 2125 | */ |
2120 | shmem_truncate_range(file_inode(obj->base.filp), 0, (loff_t)-1); | 2126 | shmem_truncate_range(file_inode(obj->base.filp), 0, (loff_t)-1); |
2121 | obj->mm.madv = __I915_MADV_PURGED; | 2127 | obj->mm.madv = __I915_MADV_PURGED; |
2128 | obj->mm.pages = ERR_PTR(-EFAULT); | ||
2122 | } | 2129 | } |
2123 | 2130 | ||
2124 | /* Try to discard unwanted pages */ | 2131 | /* Try to discard unwanted pages */ |
@@ -2218,7 +2225,9 @@ void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj, | |||
2218 | 2225 | ||
2219 | __i915_gem_object_reset_page_iter(obj); | 2226 | __i915_gem_object_reset_page_iter(obj); |
2220 | 2227 | ||
2221 | obj->ops->put_pages(obj, pages); | 2228 | if (!IS_ERR(pages)) |
2229 | obj->ops->put_pages(obj, pages); | ||
2230 | |||
2222 | unlock: | 2231 | unlock: |
2223 | mutex_unlock(&obj->mm.lock); | 2232 | mutex_unlock(&obj->mm.lock); |
2224 | } | 2233 | } |
@@ -2437,7 +2446,7 @@ int __i915_gem_object_get_pages(struct drm_i915_gem_object *obj) | |||
2437 | if (err) | 2446 | if (err) |
2438 | return err; | 2447 | return err; |
2439 | 2448 | ||
2440 | if (unlikely(!obj->mm.pages)) { | 2449 | if (unlikely(IS_ERR_OR_NULL(obj->mm.pages))) { |
2441 | err = ____i915_gem_object_get_pages(obj); | 2450 | err = ____i915_gem_object_get_pages(obj); |
2442 | if (err) | 2451 | if (err) |
2443 | goto unlock; | 2452 | goto unlock; |
@@ -2515,7 +2524,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, | |||
2515 | 2524 | ||
2516 | pinned = true; | 2525 | pinned = true; |
2517 | if (!atomic_inc_not_zero(&obj->mm.pages_pin_count)) { | 2526 | if (!atomic_inc_not_zero(&obj->mm.pages_pin_count)) { |
2518 | if (unlikely(!obj->mm.pages)) { | 2527 | if (unlikely(IS_ERR_OR_NULL(obj->mm.pages))) { |
2519 | ret = ____i915_gem_object_get_pages(obj); | 2528 | ret = ____i915_gem_object_get_pages(obj); |
2520 | if (ret) | 2529 | if (ret) |
2521 | goto err_unlock; | 2530 | goto err_unlock; |
@@ -2563,6 +2572,75 @@ err_unlock: | |||
2563 | goto out_unlock; | 2572 | goto out_unlock; |
2564 | } | 2573 | } |
2565 | 2574 | ||
2575 | static int | ||
2576 | i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj, | ||
2577 | const struct drm_i915_gem_pwrite *arg) | ||
2578 | { | ||
2579 | struct address_space *mapping = obj->base.filp->f_mapping; | ||
2580 | char __user *user_data = u64_to_user_ptr(arg->data_ptr); | ||
2581 | u64 remain, offset; | ||
2582 | unsigned int pg; | ||
2583 | |||
2584 | /* Before we instantiate/pin the backing store for our use, we | ||
2585 | * can prepopulate the shmemfs filp efficiently using a write into | ||
2586 | * the pagecache. We avoid the penalty of instantiating all the | ||
2587 | * pages, important if the user is just writing to a few and never | ||
2588 | * uses the object on the GPU, and using a direct write into shmemfs | ||
2589 | * allows it to avoid the cost of retrieving a page (either swapin | ||
2590 | * or clearing-before-use) before it is overwritten. | ||
2591 | */ | ||
2592 | if (READ_ONCE(obj->mm.pages)) | ||
2593 | return -ENODEV; | ||
2594 | |||
2595 | /* Before the pages are instantiated the object is treated as being | ||
2596 | * in the CPU domain. The pages will be clflushed as required before | ||
2597 | * use, and we can freely write into the pages directly. If userspace | ||
2598 | * races pwrite with any other operation; corruption will ensue - | ||
2599 | * that is userspace's prerogative! | ||
2600 | */ | ||
2601 | |||
2602 | remain = arg->size; | ||
2603 | offset = arg->offset; | ||
2604 | pg = offset_in_page(offset); | ||
2605 | |||
2606 | do { | ||
2607 | unsigned int len, unwritten; | ||
2608 | struct page *page; | ||
2609 | void *data, *vaddr; | ||
2610 | int err; | ||
2611 | |||
2612 | len = PAGE_SIZE - pg; | ||
2613 | if (len > remain) | ||
2614 | len = remain; | ||
2615 | |||
2616 | err = pagecache_write_begin(obj->base.filp, mapping, | ||
2617 | offset, len, 0, | ||
2618 | &page, &data); | ||
2619 | if (err < 0) | ||
2620 | return err; | ||
2621 | |||
2622 | vaddr = kmap(page); | ||
2623 | unwritten = copy_from_user(vaddr + pg, user_data, len); | ||
2624 | kunmap(page); | ||
2625 | |||
2626 | err = pagecache_write_end(obj->base.filp, mapping, | ||
2627 | offset, len, len - unwritten, | ||
2628 | page, data); | ||
2629 | if (err < 0) | ||
2630 | return err; | ||
2631 | |||
2632 | if (unwritten) | ||
2633 | return -EFAULT; | ||
2634 | |||
2635 | remain -= len; | ||
2636 | user_data += len; | ||
2637 | offset += len; | ||
2638 | pg = 0; | ||
2639 | } while (remain); | ||
2640 | |||
2641 | return 0; | ||
2642 | } | ||
2643 | |||
2566 | static bool ban_context(const struct i915_gem_context *ctx) | 2644 | static bool ban_context(const struct i915_gem_context *ctx) |
2567 | { | 2645 | { |
2568 | return (i915_gem_context_is_bannable(ctx) && | 2646 | return (i915_gem_context_is_bannable(ctx) && |
@@ -3029,6 +3107,16 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) | |||
3029 | args->timeout_ns -= ktime_to_ns(ktime_sub(ktime_get(), start)); | 3107 | args->timeout_ns -= ktime_to_ns(ktime_sub(ktime_get(), start)); |
3030 | if (args->timeout_ns < 0) | 3108 | if (args->timeout_ns < 0) |
3031 | args->timeout_ns = 0; | 3109 | args->timeout_ns = 0; |
3110 | |||
3111 | /* | ||
3112 | * Apparently ktime isn't accurate enough and occasionally has a | ||
3113 | * bit of mismatch in the jiffies<->nsecs<->ktime loop. So patch | ||
3114 | * things up to make the test happy. We allow up to 1 jiffy. | ||
3115 | * | ||
3116 | * This is a regression from the timespec->ktime conversion. | ||
3117 | */ | ||
3118 | if (ret == -ETIME && !nsecs_to_jiffies(args->timeout_ns)) | ||
3119 | args->timeout_ns = 0; | ||
3032 | } | 3120 | } |
3033 | 3121 | ||
3034 | i915_gem_object_put(obj); | 3122 | i915_gem_object_put(obj); |
@@ -3974,8 +4062,11 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, | |||
3974 | static const struct drm_i915_gem_object_ops i915_gem_object_ops = { | 4062 | static const struct drm_i915_gem_object_ops i915_gem_object_ops = { |
3975 | .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE | | 4063 | .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE | |
3976 | I915_GEM_OBJECT_IS_SHRINKABLE, | 4064 | I915_GEM_OBJECT_IS_SHRINKABLE, |
4065 | |||
3977 | .get_pages = i915_gem_object_get_pages_gtt, | 4066 | .get_pages = i915_gem_object_get_pages_gtt, |
3978 | .put_pages = i915_gem_object_put_pages_gtt, | 4067 | .put_pages = i915_gem_object_put_pages_gtt, |
4068 | |||
4069 | .pwrite = i915_gem_object_pwrite_gtt, | ||
3979 | }; | 4070 | }; |
3980 | 4071 | ||
3981 | struct drm_i915_gem_object * | 4072 | struct drm_i915_gem_object * |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index c181b1bb3d2c..3be2503aa042 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -293,12 +293,12 @@ int i915_gem_evict_for_node(struct i915_address_space *vm, | |||
293 | * those as well to make room for our guard pages. | 293 | * those as well to make room for our guard pages. |
294 | */ | 294 | */ |
295 | if (check_color) { | 295 | if (check_color) { |
296 | if (vma->node.start + vma->node.size == node->start) { | 296 | if (node->start + node->size == target->start) { |
297 | if (vma->node.color == node->color) | 297 | if (node->color == target->color) |
298 | continue; | 298 | continue; |
299 | } | 299 | } |
300 | if (vma->node.start == node->start + node->size) { | 300 | if (node->start == target->start + target->size) { |
301 | if (vma->node.color == node->color) | 301 | if (node->color == target->color) |
302 | continue; | 302 | continue; |
303 | } | 303 | } |
304 | } | 304 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h index bf90b07163d1..76b80a0be797 100644 --- a/drivers/gpu/drm/i915/i915_gem_object.h +++ b/drivers/gpu/drm/i915/i915_gem_object.h | |||
@@ -54,6 +54,9 @@ struct drm_i915_gem_object_ops { | |||
54 | struct sg_table *(*get_pages)(struct drm_i915_gem_object *); | 54 | struct sg_table *(*get_pages)(struct drm_i915_gem_object *); |
55 | void (*put_pages)(struct drm_i915_gem_object *, struct sg_table *); | 55 | void (*put_pages)(struct drm_i915_gem_object *, struct sg_table *); |
56 | 56 | ||
57 | int (*pwrite)(struct drm_i915_gem_object *, | ||
58 | const struct drm_i915_gem_pwrite *); | ||
59 | |||
57 | int (*dmabuf_export)(struct drm_i915_gem_object *); | 60 | int (*dmabuf_export)(struct drm_i915_gem_object *); |
58 | void (*release)(struct drm_i915_gem_object *); | 61 | void (*release)(struct drm_i915_gem_object *); |
59 | }; | 62 | }; |
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 155906e84812..df20e9bc1c0f 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c | |||
@@ -512,10 +512,36 @@ err_unpin: | |||
512 | return ret; | 512 | return ret; |
513 | } | 513 | } |
514 | 514 | ||
515 | static void | ||
516 | i915_vma_remove(struct i915_vma *vma) | ||
517 | { | ||
518 | struct drm_i915_gem_object *obj = vma->obj; | ||
519 | |||
520 | GEM_BUG_ON(!drm_mm_node_allocated(&vma->node)); | ||
521 | GEM_BUG_ON(vma->flags & (I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND)); | ||
522 | |||
523 | drm_mm_remove_node(&vma->node); | ||
524 | list_move_tail(&vma->vm_link, &vma->vm->unbound_list); | ||
525 | |||
526 | /* Since the unbound list is global, only move to that list if | ||
527 | * no more VMAs exist. | ||
528 | */ | ||
529 | if (--obj->bind_count == 0) | ||
530 | list_move_tail(&obj->global_link, | ||
531 | &to_i915(obj->base.dev)->mm.unbound_list); | ||
532 | |||
533 | /* And finally now the object is completely decoupled from this vma, | ||
534 | * we can drop its hold on the backing storage and allow it to be | ||
535 | * reaped by the shrinker. | ||
536 | */ | ||
537 | i915_gem_object_unpin_pages(obj); | ||
538 | GEM_BUG_ON(atomic_read(&obj->mm.pages_pin_count) < obj->bind_count); | ||
539 | } | ||
540 | |||
515 | int __i915_vma_do_pin(struct i915_vma *vma, | 541 | int __i915_vma_do_pin(struct i915_vma *vma, |
516 | u64 size, u64 alignment, u64 flags) | 542 | u64 size, u64 alignment, u64 flags) |
517 | { | 543 | { |
518 | unsigned int bound = vma->flags; | 544 | const unsigned int bound = vma->flags; |
519 | int ret; | 545 | int ret; |
520 | 546 | ||
521 | lockdep_assert_held(&vma->vm->i915->drm.struct_mutex); | 547 | lockdep_assert_held(&vma->vm->i915->drm.struct_mutex); |
@@ -524,18 +550,18 @@ int __i915_vma_do_pin(struct i915_vma *vma, | |||
524 | 550 | ||
525 | if (WARN_ON(bound & I915_VMA_PIN_OVERFLOW)) { | 551 | if (WARN_ON(bound & I915_VMA_PIN_OVERFLOW)) { |
526 | ret = -EBUSY; | 552 | ret = -EBUSY; |
527 | goto err; | 553 | goto err_unpin; |
528 | } | 554 | } |
529 | 555 | ||
530 | if ((bound & I915_VMA_BIND_MASK) == 0) { | 556 | if ((bound & I915_VMA_BIND_MASK) == 0) { |
531 | ret = i915_vma_insert(vma, size, alignment, flags); | 557 | ret = i915_vma_insert(vma, size, alignment, flags); |
532 | if (ret) | 558 | if (ret) |
533 | goto err; | 559 | goto err_unpin; |
534 | } | 560 | } |
535 | 561 | ||
536 | ret = i915_vma_bind(vma, vma->obj->cache_level, flags); | 562 | ret = i915_vma_bind(vma, vma->obj->cache_level, flags); |
537 | if (ret) | 563 | if (ret) |
538 | goto err; | 564 | goto err_remove; |
539 | 565 | ||
540 | if ((bound ^ vma->flags) & I915_VMA_GLOBAL_BIND) | 566 | if ((bound ^ vma->flags) & I915_VMA_GLOBAL_BIND) |
541 | __i915_vma_set_map_and_fenceable(vma); | 567 | __i915_vma_set_map_and_fenceable(vma); |
@@ -544,7 +570,12 @@ int __i915_vma_do_pin(struct i915_vma *vma, | |||
544 | GEM_BUG_ON(i915_vma_misplaced(vma, size, alignment, flags)); | 570 | GEM_BUG_ON(i915_vma_misplaced(vma, size, alignment, flags)); |
545 | return 0; | 571 | return 0; |
546 | 572 | ||
547 | err: | 573 | err_remove: |
574 | if ((bound & I915_VMA_BIND_MASK) == 0) { | ||
575 | GEM_BUG_ON(vma->pages); | ||
576 | i915_vma_remove(vma); | ||
577 | } | ||
578 | err_unpin: | ||
548 | __i915_vma_unpin(vma); | 579 | __i915_vma_unpin(vma); |
549 | return ret; | 580 | return ret; |
550 | } | 581 | } |
@@ -657,9 +688,6 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
657 | } | 688 | } |
658 | vma->flags &= ~(I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND); | 689 | vma->flags &= ~(I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND); |
659 | 690 | ||
660 | drm_mm_remove_node(&vma->node); | ||
661 | list_move_tail(&vma->vm_link, &vma->vm->unbound_list); | ||
662 | |||
663 | if (vma->pages != obj->mm.pages) { | 691 | if (vma->pages != obj->mm.pages) { |
664 | GEM_BUG_ON(!vma->pages); | 692 | GEM_BUG_ON(!vma->pages); |
665 | sg_free_table(vma->pages); | 693 | sg_free_table(vma->pages); |
@@ -667,18 +695,7 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
667 | } | 695 | } |
668 | vma->pages = NULL; | 696 | vma->pages = NULL; |
669 | 697 | ||
670 | /* Since the unbound list is global, only move to that list if | 698 | i915_vma_remove(vma); |
671 | * no more VMAs exist. */ | ||
672 | if (--obj->bind_count == 0) | ||
673 | list_move_tail(&obj->global_link, | ||
674 | &to_i915(obj->base.dev)->mm.unbound_list); | ||
675 | |||
676 | /* And finally now the object is completely decoupled from this vma, | ||
677 | * we can drop its hold on the backing storage and allow it to be | ||
678 | * reaped by the shrinker. | ||
679 | */ | ||
680 | i915_gem_object_unpin_pages(obj); | ||
681 | GEM_BUG_ON(atomic_read(&obj->mm.pages_pin_count) < obj->bind_count); | ||
682 | 699 | ||
683 | destroy: | 700 | destroy: |
684 | if (unlikely(i915_vma_is_closed(vma))) | 701 | if (unlikely(i915_vma_is_closed(vma))) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 01341670738f..3282b0f4b134 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -3669,10 +3669,6 @@ static void intel_update_pipe_config(struct intel_crtc *crtc, | |||
3669 | /* drm_atomic_helper_update_legacy_modeset_state might not be called. */ | 3669 | /* drm_atomic_helper_update_legacy_modeset_state might not be called. */ |
3670 | crtc->base.mode = crtc->base.state->mode; | 3670 | crtc->base.mode = crtc->base.state->mode; |
3671 | 3671 | ||
3672 | DRM_DEBUG_KMS("Updating pipe size %ix%i -> %ix%i\n", | ||
3673 | old_crtc_state->pipe_src_w, old_crtc_state->pipe_src_h, | ||
3674 | pipe_config->pipe_src_w, pipe_config->pipe_src_h); | ||
3675 | |||
3676 | /* | 3672 | /* |
3677 | * Update pipe size and adjust fitter if needed: the reason for this is | 3673 | * Update pipe size and adjust fitter if needed: the reason for this is |
3678 | * that in compute_mode_changes we check the native mode (not the pfit | 3674 | * that in compute_mode_changes we check the native mode (not the pfit |
@@ -4796,23 +4792,17 @@ static void skylake_pfit_enable(struct intel_crtc *crtc) | |||
4796 | struct intel_crtc_scaler_state *scaler_state = | 4792 | struct intel_crtc_scaler_state *scaler_state = |
4797 | &crtc->config->scaler_state; | 4793 | &crtc->config->scaler_state; |
4798 | 4794 | ||
4799 | DRM_DEBUG_KMS("for crtc_state = %p\n", crtc->config); | ||
4800 | |||
4801 | if (crtc->config->pch_pfit.enabled) { | 4795 | if (crtc->config->pch_pfit.enabled) { |
4802 | int id; | 4796 | int id; |
4803 | 4797 | ||
4804 | if (WARN_ON(crtc->config->scaler_state.scaler_id < 0)) { | 4798 | if (WARN_ON(crtc->config->scaler_state.scaler_id < 0)) |
4805 | DRM_ERROR("Requesting pfit without getting a scaler first\n"); | ||
4806 | return; | 4799 | return; |
4807 | } | ||
4808 | 4800 | ||
4809 | id = scaler_state->scaler_id; | 4801 | id = scaler_state->scaler_id; |
4810 | I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN | | 4802 | I915_WRITE(SKL_PS_CTRL(pipe, id), PS_SCALER_EN | |
4811 | PS_FILTER_MEDIUM | scaler_state->scalers[id].mode); | 4803 | PS_FILTER_MEDIUM | scaler_state->scalers[id].mode); |
4812 | I915_WRITE(SKL_PS_WIN_POS(pipe, id), crtc->config->pch_pfit.pos); | 4804 | I915_WRITE(SKL_PS_WIN_POS(pipe, id), crtc->config->pch_pfit.pos); |
4813 | I915_WRITE(SKL_PS_WIN_SZ(pipe, id), crtc->config->pch_pfit.size); | 4805 | I915_WRITE(SKL_PS_WIN_SZ(pipe, id), crtc->config->pch_pfit.size); |
4814 | |||
4815 | DRM_DEBUG_KMS("for crtc_state = %p scaler_id = %d\n", crtc->config, id); | ||
4816 | } | 4806 | } |
4817 | } | 4807 | } |
4818 | 4808 | ||
@@ -14379,6 +14369,24 @@ static void skl_update_crtcs(struct drm_atomic_state *state, | |||
14379 | } while (progress); | 14369 | } while (progress); |
14380 | } | 14370 | } |
14381 | 14371 | ||
14372 | static void intel_atomic_helper_free_state(struct drm_i915_private *dev_priv) | ||
14373 | { | ||
14374 | struct intel_atomic_state *state, *next; | ||
14375 | struct llist_node *freed; | ||
14376 | |||
14377 | freed = llist_del_all(&dev_priv->atomic_helper.free_list); | ||
14378 | llist_for_each_entry_safe(state, next, freed, freed) | ||
14379 | drm_atomic_state_put(&state->base); | ||
14380 | } | ||
14381 | |||
14382 | static void intel_atomic_helper_free_state_worker(struct work_struct *work) | ||
14383 | { | ||
14384 | struct drm_i915_private *dev_priv = | ||
14385 | container_of(work, typeof(*dev_priv), atomic_helper.free_work); | ||
14386 | |||
14387 | intel_atomic_helper_free_state(dev_priv); | ||
14388 | } | ||
14389 | |||
14382 | static void intel_atomic_commit_tail(struct drm_atomic_state *state) | 14390 | static void intel_atomic_commit_tail(struct drm_atomic_state *state) |
14383 | { | 14391 | { |
14384 | struct drm_device *dev = state->dev; | 14392 | struct drm_device *dev = state->dev; |
@@ -14545,6 +14553,8 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) | |||
14545 | * can happen also when the device is completely off. | 14553 | * can happen also when the device is completely off. |
14546 | */ | 14554 | */ |
14547 | intel_uncore_arm_unclaimed_mmio_detection(dev_priv); | 14555 | intel_uncore_arm_unclaimed_mmio_detection(dev_priv); |
14556 | |||
14557 | intel_atomic_helper_free_state(dev_priv); | ||
14548 | } | 14558 | } |
14549 | 14559 | ||
14550 | static void intel_atomic_commit_work(struct work_struct *work) | 14560 | static void intel_atomic_commit_work(struct work_struct *work) |
@@ -14946,17 +14956,19 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc, | |||
14946 | to_intel_atomic_state(old_crtc_state->state); | 14956 | to_intel_atomic_state(old_crtc_state->state); |
14947 | bool modeset = needs_modeset(crtc->state); | 14957 | bool modeset = needs_modeset(crtc->state); |
14948 | 14958 | ||
14959 | if (!modeset && | ||
14960 | (intel_cstate->base.color_mgmt_changed || | ||
14961 | intel_cstate->update_pipe)) { | ||
14962 | intel_color_set_csc(crtc->state); | ||
14963 | intel_color_load_luts(crtc->state); | ||
14964 | } | ||
14965 | |||
14949 | /* Perform vblank evasion around commit operation */ | 14966 | /* Perform vblank evasion around commit operation */ |
14950 | intel_pipe_update_start(intel_crtc); | 14967 | intel_pipe_update_start(intel_crtc); |
14951 | 14968 | ||
14952 | if (modeset) | 14969 | if (modeset) |
14953 | goto out; | 14970 | goto out; |
14954 | 14971 | ||
14955 | if (crtc->state->color_mgmt_changed || to_intel_crtc_state(crtc->state)->update_pipe) { | ||
14956 | intel_color_set_csc(crtc->state); | ||
14957 | intel_color_load_luts(crtc->state); | ||
14958 | } | ||
14959 | |||
14960 | if (intel_cstate->update_pipe) | 14972 | if (intel_cstate->update_pipe) |
14961 | intel_update_pipe_config(intel_crtc, old_intel_cstate); | 14973 | intel_update_pipe_config(intel_crtc, old_intel_cstate); |
14962 | else if (INTEL_GEN(dev_priv) >= 9) | 14974 | else if (INTEL_GEN(dev_priv) >= 9) |
@@ -16599,18 +16611,6 @@ fail: | |||
16599 | drm_modeset_acquire_fini(&ctx); | 16611 | drm_modeset_acquire_fini(&ctx); |
16600 | } | 16612 | } |
16601 | 16613 | ||
16602 | static void intel_atomic_helper_free_state(struct work_struct *work) | ||
16603 | { | ||
16604 | struct drm_i915_private *dev_priv = | ||
16605 | container_of(work, typeof(*dev_priv), atomic_helper.free_work); | ||
16606 | struct intel_atomic_state *state, *next; | ||
16607 | struct llist_node *freed; | ||
16608 | |||
16609 | freed = llist_del_all(&dev_priv->atomic_helper.free_list); | ||
16610 | llist_for_each_entry_safe(state, next, freed, freed) | ||
16611 | drm_atomic_state_put(&state->base); | ||
16612 | } | ||
16613 | |||
16614 | int intel_modeset_init(struct drm_device *dev) | 16614 | int intel_modeset_init(struct drm_device *dev) |
16615 | { | 16615 | { |
16616 | struct drm_i915_private *dev_priv = to_i915(dev); | 16616 | struct drm_i915_private *dev_priv = to_i915(dev); |
@@ -16631,7 +16631,7 @@ int intel_modeset_init(struct drm_device *dev) | |||
16631 | dev->mode_config.funcs = &intel_mode_funcs; | 16631 | dev->mode_config.funcs = &intel_mode_funcs; |
16632 | 16632 | ||
16633 | INIT_WORK(&dev_priv->atomic_helper.free_work, | 16633 | INIT_WORK(&dev_priv->atomic_helper.free_work, |
16634 | intel_atomic_helper_free_state); | 16634 | intel_atomic_helper_free_state_worker); |
16635 | 16635 | ||
16636 | intel_init_quirks(dev); | 16636 | intel_init_quirks(dev); |
16637 | 16637 | ||
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 1b8ba2e77539..2d449fb5d1d2 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c | |||
@@ -357,14 +357,13 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, | |||
357 | bool *enabled, int width, int height) | 357 | bool *enabled, int width, int height) |
358 | { | 358 | { |
359 | struct drm_i915_private *dev_priv = to_i915(fb_helper->dev); | 359 | struct drm_i915_private *dev_priv = to_i915(fb_helper->dev); |
360 | unsigned long conn_configured, mask; | 360 | unsigned long conn_configured, conn_seq, mask; |
361 | unsigned int count = min(fb_helper->connector_count, BITS_PER_LONG); | 361 | unsigned int count = min(fb_helper->connector_count, BITS_PER_LONG); |
362 | int i, j; | 362 | int i, j; |
363 | bool *save_enabled; | 363 | bool *save_enabled; |
364 | bool fallback = true; | 364 | bool fallback = true; |
365 | int num_connectors_enabled = 0; | 365 | int num_connectors_enabled = 0; |
366 | int num_connectors_detected = 0; | 366 | int num_connectors_detected = 0; |
367 | int pass = 0; | ||
368 | 367 | ||
369 | save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL); | 368 | save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL); |
370 | if (!save_enabled) | 369 | if (!save_enabled) |
@@ -374,6 +373,7 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, | |||
374 | mask = BIT(count) - 1; | 373 | mask = BIT(count) - 1; |
375 | conn_configured = 0; | 374 | conn_configured = 0; |
376 | retry: | 375 | retry: |
376 | conn_seq = conn_configured; | ||
377 | for (i = 0; i < count; i++) { | 377 | for (i = 0; i < count; i++) { |
378 | struct drm_fb_helper_connector *fb_conn; | 378 | struct drm_fb_helper_connector *fb_conn; |
379 | struct drm_connector *connector; | 379 | struct drm_connector *connector; |
@@ -387,7 +387,7 @@ retry: | |||
387 | if (conn_configured & BIT(i)) | 387 | if (conn_configured & BIT(i)) |
388 | continue; | 388 | continue; |
389 | 389 | ||
390 | if (pass == 0 && !connector->has_tile) | 390 | if (conn_seq == 0 && !connector->has_tile) |
391 | continue; | 391 | continue; |
392 | 392 | ||
393 | if (connector->status == connector_status_connected) | 393 | if (connector->status == connector_status_connected) |
@@ -498,10 +498,8 @@ retry: | |||
498 | conn_configured |= BIT(i); | 498 | conn_configured |= BIT(i); |
499 | } | 499 | } |
500 | 500 | ||
501 | if ((conn_configured & mask) != mask) { | 501 | if ((conn_configured & mask) != mask && conn_configured != conn_seq) |
502 | pass++; | ||
503 | goto retry; | 502 | goto retry; |
504 | } | ||
505 | 503 | ||
506 | /* | 504 | /* |
507 | * If the BIOS didn't enable everything it could, fall back to have the | 505 | * If the BIOS didn't enable everything it could, fall back to have the |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 249623d45be0..940bab22d464 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -4891,6 +4891,12 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) | |||
4891 | break; | 4891 | break; |
4892 | } | 4892 | } |
4893 | 4893 | ||
4894 | /* When byt can survive without system hang with dynamic | ||
4895 | * sw freq adjustments, this restriction can be lifted. | ||
4896 | */ | ||
4897 | if (IS_VALLEYVIEW(dev_priv)) | ||
4898 | goto skip_hw_write; | ||
4899 | |||
4894 | I915_WRITE(GEN6_RP_UP_EI, | 4900 | I915_WRITE(GEN6_RP_UP_EI, |
4895 | GT_INTERVAL_FROM_US(dev_priv, ei_up)); | 4901 | GT_INTERVAL_FROM_US(dev_priv, ei_up)); |
4896 | I915_WRITE(GEN6_RP_UP_THRESHOLD, | 4902 | I915_WRITE(GEN6_RP_UP_THRESHOLD, |
@@ -4911,6 +4917,7 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) | |||
4911 | GEN6_RP_UP_BUSY_AVG | | 4917 | GEN6_RP_UP_BUSY_AVG | |
4912 | GEN6_RP_DOWN_IDLE_AVG); | 4918 | GEN6_RP_DOWN_IDLE_AVG); |
4913 | 4919 | ||
4920 | skip_hw_write: | ||
4914 | dev_priv->rps.power = new_power; | 4921 | dev_priv->rps.power = new_power; |
4915 | dev_priv->rps.up_threshold = threshold_up; | 4922 | dev_priv->rps.up_threshold = threshold_up; |
4916 | dev_priv->rps.down_threshold = threshold_down; | 4923 | dev_priv->rps.down_threshold = threshold_down; |
@@ -7916,10 +7923,10 @@ static bool skl_pcode_try_request(struct drm_i915_private *dev_priv, u32 mbox, | |||
7916 | * @timeout_base_ms: timeout for polling with preemption enabled | 7923 | * @timeout_base_ms: timeout for polling with preemption enabled |
7917 | * | 7924 | * |
7918 | * Keep resending the @request to @mbox until PCODE acknowledges it, PCODE | 7925 | * Keep resending the @request to @mbox until PCODE acknowledges it, PCODE |
7919 | * reports an error or an overall timeout of @timeout_base_ms+10 ms expires. | 7926 | * reports an error or an overall timeout of @timeout_base_ms+50 ms expires. |
7920 | * The request is acknowledged once the PCODE reply dword equals @reply after | 7927 | * The request is acknowledged once the PCODE reply dword equals @reply after |
7921 | * applying @reply_mask. Polling is first attempted with preemption enabled | 7928 | * applying @reply_mask. Polling is first attempted with preemption enabled |
7922 | * for @timeout_base_ms and if this times out for another 10 ms with | 7929 | * for @timeout_base_ms and if this times out for another 50 ms with |
7923 | * preemption disabled. | 7930 | * preemption disabled. |
7924 | * | 7931 | * |
7925 | * Returns 0 on success, %-ETIMEDOUT in case of a timeout, <0 in case of some | 7932 | * Returns 0 on success, %-ETIMEDOUT in case of a timeout, <0 in case of some |
@@ -7955,14 +7962,15 @@ int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request, | |||
7955 | * worst case) _and_ PCODE was busy for some reason even after a | 7962 | * worst case) _and_ PCODE was busy for some reason even after a |
7956 | * (queued) request and @timeout_base_ms delay. As a workaround retry | 7963 | * (queued) request and @timeout_base_ms delay. As a workaround retry |
7957 | * the poll with preemption disabled to maximize the number of | 7964 | * the poll with preemption disabled to maximize the number of |
7958 | * requests. Increase the timeout from @timeout_base_ms to 10ms to | 7965 | * requests. Increase the timeout from @timeout_base_ms to 50ms to |
7959 | * account for interrupts that could reduce the number of these | 7966 | * account for interrupts that could reduce the number of these |
7960 | * requests. | 7967 | * requests, and for any quirks of the PCODE firmware that delays |
7968 | * the request completion. | ||
7961 | */ | 7969 | */ |
7962 | DRM_DEBUG_KMS("PCODE timeout, retrying with preemption disabled\n"); | 7970 | DRM_DEBUG_KMS("PCODE timeout, retrying with preemption disabled\n"); |
7963 | WARN_ON_ONCE(timeout_base_ms > 3); | 7971 | WARN_ON_ONCE(timeout_base_ms > 3); |
7964 | preempt_disable(); | 7972 | preempt_disable(); |
7965 | ret = wait_for_atomic(COND, 10); | 7973 | ret = wait_for_atomic(COND, 50); |
7966 | preempt_enable(); | 7974 | preempt_enable(); |
7967 | 7975 | ||
7968 | out: | 7976 | out: |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 9ef54688872a..9481ca9a3ae7 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -254,9 +254,6 @@ skl_update_plane(struct drm_plane *drm_plane, | |||
254 | int scaler_id = plane_state->scaler_id; | 254 | int scaler_id = plane_state->scaler_id; |
255 | const struct intel_scaler *scaler; | 255 | const struct intel_scaler *scaler; |
256 | 256 | ||
257 | DRM_DEBUG_KMS("plane = %d PS_PLANE_SEL(plane) = 0x%x\n", | ||
258 | plane_id, PS_PLANE_SEL(plane_id)); | ||
259 | |||
260 | scaler = &crtc_state->scaler_state.scalers[scaler_id]; | 257 | scaler = &crtc_state->scaler_state.scalers[scaler_id]; |
261 | 258 | ||
262 | I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), | 259 | I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), |
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index abe08885a5ba..b7ff592b14f5 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c | |||
@@ -119,6 +119,8 @@ fw_domains_get(struct drm_i915_private *dev_priv, enum forcewake_domains fw_doma | |||
119 | 119 | ||
120 | for_each_fw_domain_masked(d, fw_domains, dev_priv) | 120 | for_each_fw_domain_masked(d, fw_domains, dev_priv) |
121 | fw_domain_wait_ack(d); | 121 | fw_domain_wait_ack(d); |
122 | |||
123 | dev_priv->uncore.fw_domains_active |= fw_domains; | ||
122 | } | 124 | } |
123 | 125 | ||
124 | static void | 126 | static void |
@@ -130,6 +132,8 @@ fw_domains_put(struct drm_i915_private *dev_priv, enum forcewake_domains fw_doma | |||
130 | fw_domain_put(d); | 132 | fw_domain_put(d); |
131 | fw_domain_posting_read(d); | 133 | fw_domain_posting_read(d); |
132 | } | 134 | } |
135 | |||
136 | dev_priv->uncore.fw_domains_active &= ~fw_domains; | ||
133 | } | 137 | } |
134 | 138 | ||
135 | static void | 139 | static void |
@@ -240,10 +244,8 @@ intel_uncore_fw_release_timer(struct hrtimer *timer) | |||
240 | if (WARN_ON(domain->wake_count == 0)) | 244 | if (WARN_ON(domain->wake_count == 0)) |
241 | domain->wake_count++; | 245 | domain->wake_count++; |
242 | 246 | ||
243 | if (--domain->wake_count == 0) { | 247 | if (--domain->wake_count == 0) |
244 | dev_priv->uncore.funcs.force_wake_put(dev_priv, domain->mask); | 248 | dev_priv->uncore.funcs.force_wake_put(dev_priv, domain->mask); |
245 | dev_priv->uncore.fw_domains_active &= ~domain->mask; | ||
246 | } | ||
247 | 249 | ||
248 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); | 250 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); |
249 | 251 | ||
@@ -454,10 +456,8 @@ static void __intel_uncore_forcewake_get(struct drm_i915_private *dev_priv, | |||
454 | fw_domains &= ~domain->mask; | 456 | fw_domains &= ~domain->mask; |
455 | } | 457 | } |
456 | 458 | ||
457 | if (fw_domains) { | 459 | if (fw_domains) |
458 | dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains); | 460 | dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains); |
459 | dev_priv->uncore.fw_domains_active |= fw_domains; | ||
460 | } | ||
461 | } | 461 | } |
462 | 462 | ||
463 | /** | 463 | /** |
@@ -968,7 +968,6 @@ static noinline void ___force_wake_auto(struct drm_i915_private *dev_priv, | |||
968 | fw_domain_arm_timer(domain); | 968 | fw_domain_arm_timer(domain); |
969 | 969 | ||
970 | dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains); | 970 | dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains); |
971 | dev_priv->uncore.fw_domains_active |= fw_domains; | ||
972 | } | 971 | } |
973 | 972 | ||
974 | static inline void __force_wake_auto(struct drm_i915_private *dev_priv, | 973 | static inline void __force_wake_auto(struct drm_i915_private *dev_priv, |
diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c index af267c35d813..ee5883f59be5 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c +++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c | |||
@@ -147,9 +147,6 @@ static int omap_gem_dmabuf_mmap(struct dma_buf *buffer, | |||
147 | struct drm_gem_object *obj = buffer->priv; | 147 | struct drm_gem_object *obj = buffer->priv; |
148 | int ret = 0; | 148 | int ret = 0; |
149 | 149 | ||
150 | if (WARN_ON(!obj->filp)) | ||
151 | return -EINVAL; | ||
152 | |||
153 | ret = drm_gem_mmap_obj(obj, omap_gem_mmap_size(obj), vma); | 150 | ret = drm_gem_mmap_obj(obj, omap_gem_mmap_size(obj), vma); |
154 | if (ret < 0) | 151 | if (ret < 0) |
155 | return ret; | 152 | return ret; |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index d12b8978142f..72e1588580a1 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
@@ -2984,6 +2984,12 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2984 | (rdev->pdev->device == 0x6667)) { | 2984 | (rdev->pdev->device == 0x6667)) { |
2985 | max_sclk = 75000; | 2985 | max_sclk = 75000; |
2986 | } | 2986 | } |
2987 | } else if (rdev->family == CHIP_OLAND) { | ||
2988 | if ((rdev->pdev->device == 0x6604) && | ||
2989 | (rdev->pdev->subsystem_vendor == 0x1028) && | ||
2990 | (rdev->pdev->subsystem_device == 0x066F)) { | ||
2991 | max_sclk = 75000; | ||
2992 | } | ||
2987 | } | 2993 | } |
2988 | 2994 | ||
2989 | if (rps->vce_active) { | 2995 | if (rps->vce_active) { |
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index f80bf9385e41..d745e8b50fb8 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c | |||
@@ -464,6 +464,7 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc) | |||
464 | { | 464 | { |
465 | struct drm_device *dev = crtc->dev; | 465 | struct drm_device *dev = crtc->dev; |
466 | struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); | 466 | struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); |
467 | unsigned long flags; | ||
467 | 468 | ||
468 | WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); | 469 | WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); |
469 | mutex_lock(&tilcdc_crtc->enable_lock); | 470 | mutex_lock(&tilcdc_crtc->enable_lock); |
@@ -484,7 +485,17 @@ static void tilcdc_crtc_enable(struct drm_crtc *crtc) | |||
484 | tilcdc_write_mask(dev, LCDC_RASTER_CTRL_REG, | 485 | tilcdc_write_mask(dev, LCDC_RASTER_CTRL_REG, |
485 | LCDC_PALETTE_LOAD_MODE(DATA_ONLY), | 486 | LCDC_PALETTE_LOAD_MODE(DATA_ONLY), |
486 | LCDC_PALETTE_LOAD_MODE_MASK); | 487 | LCDC_PALETTE_LOAD_MODE_MASK); |
488 | |||
489 | /* There is no real chance for a race here as the time stamp | ||
490 | * is taken before the raster DMA is started. The spin-lock is | ||
491 | * taken to have a memory barrier after taking the time-stamp | ||
492 | * and to avoid a context switch between taking the stamp and | ||
493 | * enabling the raster. | ||
494 | */ | ||
495 | spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags); | ||
496 | tilcdc_crtc->last_vblank = ktime_get(); | ||
487 | tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); | 497 | tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); |
498 | spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags); | ||
488 | 499 | ||
489 | drm_crtc_vblank_on(crtc); | 500 | drm_crtc_vblank_on(crtc); |
490 | 501 | ||
@@ -539,7 +550,6 @@ static void tilcdc_crtc_off(struct drm_crtc *crtc, bool shutdown) | |||
539 | } | 550 | } |
540 | 551 | ||
541 | drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq); | 552 | drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq); |
542 | tilcdc_crtc->last_vblank = 0; | ||
543 | 553 | ||
544 | tilcdc_crtc->enabled = false; | 554 | tilcdc_crtc->enabled = false; |
545 | mutex_unlock(&tilcdc_crtc->enable_lock); | 555 | mutex_unlock(&tilcdc_crtc->enable_lock); |
@@ -602,7 +612,6 @@ int tilcdc_crtc_update_fb(struct drm_crtc *crtc, | |||
602 | { | 612 | { |
603 | struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); | 613 | struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); |
604 | struct drm_device *dev = crtc->dev; | 614 | struct drm_device *dev = crtc->dev; |
605 | unsigned long flags; | ||
606 | 615 | ||
607 | WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); | 616 | WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); |
608 | 617 | ||
@@ -614,28 +623,30 @@ int tilcdc_crtc_update_fb(struct drm_crtc *crtc, | |||
614 | drm_framebuffer_reference(fb); | 623 | drm_framebuffer_reference(fb); |
615 | 624 | ||
616 | crtc->primary->fb = fb; | 625 | crtc->primary->fb = fb; |
626 | tilcdc_crtc->event = event; | ||
617 | 627 | ||
618 | spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags); | 628 | mutex_lock(&tilcdc_crtc->enable_lock); |
619 | 629 | ||
620 | if (crtc->hwmode.vrefresh && ktime_to_ns(tilcdc_crtc->last_vblank)) { | 630 | if (tilcdc_crtc->enabled) { |
631 | unsigned long flags; | ||
621 | ktime_t next_vblank; | 632 | ktime_t next_vblank; |
622 | s64 tdiff; | 633 | s64 tdiff; |
623 | 634 | ||
624 | next_vblank = ktime_add_us(tilcdc_crtc->last_vblank, | 635 | spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags); |
625 | 1000000 / crtc->hwmode.vrefresh); | ||
626 | 636 | ||
637 | next_vblank = ktime_add_us(tilcdc_crtc->last_vblank, | ||
638 | 1000000 / crtc->hwmode.vrefresh); | ||
627 | tdiff = ktime_to_us(ktime_sub(next_vblank, ktime_get())); | 639 | tdiff = ktime_to_us(ktime_sub(next_vblank, ktime_get())); |
628 | 640 | ||
629 | if (tdiff < TILCDC_VBLANK_SAFETY_THRESHOLD_US) | 641 | if (tdiff < TILCDC_VBLANK_SAFETY_THRESHOLD_US) |
630 | tilcdc_crtc->next_fb = fb; | 642 | tilcdc_crtc->next_fb = fb; |
631 | } | 643 | else |
632 | 644 | set_scanout(crtc, fb); | |
633 | if (tilcdc_crtc->next_fb != fb) | ||
634 | set_scanout(crtc, fb); | ||
635 | 645 | ||
636 | tilcdc_crtc->event = event; | 646 | spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags); |
647 | } | ||
637 | 648 | ||
638 | spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags); | 649 | mutex_unlock(&tilcdc_crtc->enable_lock); |
639 | 650 | ||
640 | return 0; | 651 | return 0; |
641 | } | 652 | } |
@@ -1036,5 +1047,5 @@ int tilcdc_crtc_create(struct drm_device *dev) | |||
1036 | 1047 | ||
1037 | fail: | 1048 | fail: |
1038 | tilcdc_crtc_destroy(crtc); | 1049 | tilcdc_crtc_destroy(crtc); |
1039 | return -ENOMEM; | 1050 | return ret; |
1040 | } | 1051 | } |
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 11e13c56126f..2da3ff650e1d 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
@@ -2317,6 +2317,9 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2317 | return -ENODEV; | 2317 | return -ENODEV; |
2318 | } | 2318 | } |
2319 | 2319 | ||
2320 | if (hostif->desc.bNumEndpoints < 1) | ||
2321 | return -ENODEV; | ||
2322 | |||
2320 | dev_info(&udev->dev, | 2323 | dev_info(&udev->dev, |
2321 | "%s: Device matched (Vendor: 0x%x, Product: 0x%x)\n", | 2324 | "%s: Device matched (Vendor: 0x%x, Product: 0x%x)\n", |
2322 | __func__, le16_to_cpu(udev->descriptor.idVendor), | 2325 | __func__, le16_to_cpu(udev->descriptor.idVendor), |
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 3f041b187033..f757cef293f8 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c | |||
@@ -392,6 +392,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, | |||
392 | * To get all the fields, copy all archdata | 392 | * To get all the fields, copy all archdata |
393 | */ | 393 | */ |
394 | dev->ofdev.dev.archdata = chip->lbus.pdev->dev.archdata; | 394 | dev->ofdev.dev.archdata = chip->lbus.pdev->dev.archdata; |
395 | dev->ofdev.dev.dma_ops = chip->lbus.pdev->dev.dma_ops; | ||
395 | #endif /* CONFIG_PCI */ | 396 | #endif /* CONFIG_PCI */ |
396 | 397 | ||
397 | #ifdef DEBUG | 398 | #ifdef DEBUG |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index f4ffd1eb8f44..dfb75979e455 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -989,26 +989,29 @@ static void flush_current_bio_list(struct blk_plug_cb *cb, bool from_schedule) | |||
989 | struct dm_offload *o = container_of(cb, struct dm_offload, cb); | 989 | struct dm_offload *o = container_of(cb, struct dm_offload, cb); |
990 | struct bio_list list; | 990 | struct bio_list list; |
991 | struct bio *bio; | 991 | struct bio *bio; |
992 | int i; | ||
992 | 993 | ||
993 | INIT_LIST_HEAD(&o->cb.list); | 994 | INIT_LIST_HEAD(&o->cb.list); |
994 | 995 | ||
995 | if (unlikely(!current->bio_list)) | 996 | if (unlikely(!current->bio_list)) |
996 | return; | 997 | return; |
997 | 998 | ||
998 | list = *current->bio_list; | 999 | for (i = 0; i < 2; i++) { |
999 | bio_list_init(current->bio_list); | 1000 | list = current->bio_list[i]; |
1000 | 1001 | bio_list_init(¤t->bio_list[i]); | |
1001 | while ((bio = bio_list_pop(&list))) { | 1002 | |
1002 | struct bio_set *bs = bio->bi_pool; | 1003 | while ((bio = bio_list_pop(&list))) { |
1003 | if (unlikely(!bs) || bs == fs_bio_set) { | 1004 | struct bio_set *bs = bio->bi_pool; |
1004 | bio_list_add(current->bio_list, bio); | 1005 | if (unlikely(!bs) || bs == fs_bio_set) { |
1005 | continue; | 1006 | bio_list_add(¤t->bio_list[i], bio); |
1007 | continue; | ||
1008 | } | ||
1009 | |||
1010 | spin_lock(&bs->rescue_lock); | ||
1011 | bio_list_add(&bs->rescue_list, bio); | ||
1012 | queue_work(bs->rescue_workqueue, &bs->rescue_work); | ||
1013 | spin_unlock(&bs->rescue_lock); | ||
1006 | } | 1014 | } |
1007 | |||
1008 | spin_lock(&bs->rescue_lock); | ||
1009 | bio_list_add(&bs->rescue_list, bio); | ||
1010 | queue_work(bs->rescue_workqueue, &bs->rescue_work); | ||
1011 | spin_unlock(&bs->rescue_lock); | ||
1012 | } | 1015 | } |
1013 | } | 1016 | } |
1014 | 1017 | ||
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 2b13117fb918..321ecac23027 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c | |||
@@ -777,7 +777,6 @@ static int gather_all_resync_info(struct mddev *mddev, int total_slots) | |||
777 | bm_lockres->flags |= DLM_LKF_NOQUEUE; | 777 | bm_lockres->flags |= DLM_LKF_NOQUEUE; |
778 | ret = dlm_lock_sync(bm_lockres, DLM_LOCK_PW); | 778 | ret = dlm_lock_sync(bm_lockres, DLM_LOCK_PW); |
779 | if (ret == -EAGAIN) { | 779 | if (ret == -EAGAIN) { |
780 | memset(bm_lockres->lksb.sb_lvbptr, '\0', LVB_SIZE); | ||
781 | s = read_resync_info(mddev, bm_lockres); | 780 | s = read_resync_info(mddev, bm_lockres); |
782 | if (s) { | 781 | if (s) { |
783 | pr_info("%s:%d Resync[%llu..%llu] in progress on %d\n", | 782 | pr_info("%s:%d Resync[%llu..%llu] in progress on %d\n", |
@@ -974,6 +973,7 @@ static int leave(struct mddev *mddev) | |||
974 | lockres_free(cinfo->bitmap_lockres); | 973 | lockres_free(cinfo->bitmap_lockres); |
975 | unlock_all_bitmaps(mddev); | 974 | unlock_all_bitmaps(mddev); |
976 | dlm_release_lockspace(cinfo->lockspace, 2); | 975 | dlm_release_lockspace(cinfo->lockspace, 2); |
976 | kfree(cinfo); | ||
977 | return 0; | 977 | return 0; |
978 | } | 978 | } |
979 | 979 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index 548d1b8014f8..f6ae1d67bcd0 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -440,14 +440,6 @@ void md_flush_request(struct mddev *mddev, struct bio *bio) | |||
440 | } | 440 | } |
441 | EXPORT_SYMBOL(md_flush_request); | 441 | EXPORT_SYMBOL(md_flush_request); |
442 | 442 | ||
443 | void md_unplug(struct blk_plug_cb *cb, bool from_schedule) | ||
444 | { | ||
445 | struct mddev *mddev = cb->data; | ||
446 | md_wakeup_thread(mddev->thread); | ||
447 | kfree(cb); | ||
448 | } | ||
449 | EXPORT_SYMBOL(md_unplug); | ||
450 | |||
451 | static inline struct mddev *mddev_get(struct mddev *mddev) | 443 | static inline struct mddev *mddev_get(struct mddev *mddev) |
452 | { | 444 | { |
453 | atomic_inc(&mddev->active); | 445 | atomic_inc(&mddev->active); |
@@ -1887,7 +1879,7 @@ super_1_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors) | |||
1887 | } | 1879 | } |
1888 | sb = page_address(rdev->sb_page); | 1880 | sb = page_address(rdev->sb_page); |
1889 | sb->data_size = cpu_to_le64(num_sectors); | 1881 | sb->data_size = cpu_to_le64(num_sectors); |
1890 | sb->super_offset = rdev->sb_start; | 1882 | sb->super_offset = cpu_to_le64(rdev->sb_start); |
1891 | sb->sb_csum = calc_sb_1_csum(sb); | 1883 | sb->sb_csum = calc_sb_1_csum(sb); |
1892 | do { | 1884 | do { |
1893 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, | 1885 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, |
@@ -2295,7 +2287,7 @@ static bool does_sb_need_changing(struct mddev *mddev) | |||
2295 | /* Check if any mddev parameters have changed */ | 2287 | /* Check if any mddev parameters have changed */ |
2296 | if ((mddev->dev_sectors != le64_to_cpu(sb->size)) || | 2288 | if ((mddev->dev_sectors != le64_to_cpu(sb->size)) || |
2297 | (mddev->reshape_position != le64_to_cpu(sb->reshape_position)) || | 2289 | (mddev->reshape_position != le64_to_cpu(sb->reshape_position)) || |
2298 | (mddev->layout != le64_to_cpu(sb->layout)) || | 2290 | (mddev->layout != le32_to_cpu(sb->layout)) || |
2299 | (mddev->raid_disks != le32_to_cpu(sb->raid_disks)) || | 2291 | (mddev->raid_disks != le32_to_cpu(sb->raid_disks)) || |
2300 | (mddev->chunk_sectors != le32_to_cpu(sb->chunksize))) | 2292 | (mddev->chunk_sectors != le32_to_cpu(sb->chunksize))) |
2301 | return true; | 2293 | return true; |
@@ -6458,11 +6450,10 @@ static int set_array_info(struct mddev *mddev, mdu_array_info_t *info) | |||
6458 | mddev->layout = info->layout; | 6450 | mddev->layout = info->layout; |
6459 | mddev->chunk_sectors = info->chunk_size >> 9; | 6451 | mddev->chunk_sectors = info->chunk_size >> 9; |
6460 | 6452 | ||
6461 | mddev->max_disks = MD_SB_DISKS; | ||
6462 | |||
6463 | if (mddev->persistent) { | 6453 | if (mddev->persistent) { |
6464 | mddev->flags = 0; | 6454 | mddev->max_disks = MD_SB_DISKS; |
6465 | mddev->sb_flags = 0; | 6455 | mddev->flags = 0; |
6456 | mddev->sb_flags = 0; | ||
6466 | } | 6457 | } |
6467 | set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags); | 6458 | set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags); |
6468 | 6459 | ||
@@ -6533,8 +6524,12 @@ static int update_size(struct mddev *mddev, sector_t num_sectors) | |||
6533 | return -ENOSPC; | 6524 | return -ENOSPC; |
6534 | } | 6525 | } |
6535 | rv = mddev->pers->resize(mddev, num_sectors); | 6526 | rv = mddev->pers->resize(mddev, num_sectors); |
6536 | if (!rv) | 6527 | if (!rv) { |
6537 | revalidate_disk(mddev->gendisk); | 6528 | if (mddev->queue) { |
6529 | set_capacity(mddev->gendisk, mddev->array_sectors); | ||
6530 | revalidate_disk(mddev->gendisk); | ||
6531 | } | ||
6532 | } | ||
6538 | return rv; | 6533 | return rv; |
6539 | } | 6534 | } |
6540 | 6535 | ||
diff --git a/drivers/md/md.h b/drivers/md/md.h index b8859cbf84b6..dde8ecb760c8 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -676,16 +676,10 @@ extern void mddev_resume(struct mddev *mddev); | |||
676 | extern struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs, | 676 | extern struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs, |
677 | struct mddev *mddev); | 677 | struct mddev *mddev); |
678 | 678 | ||
679 | extern void md_unplug(struct blk_plug_cb *cb, bool from_schedule); | ||
680 | extern void md_reload_sb(struct mddev *mddev, int raid_disk); | 679 | extern void md_reload_sb(struct mddev *mddev, int raid_disk); |
681 | extern void md_update_sb(struct mddev *mddev, int force); | 680 | extern void md_update_sb(struct mddev *mddev, int force); |
682 | extern void md_kick_rdev_from_array(struct md_rdev * rdev); | 681 | extern void md_kick_rdev_from_array(struct md_rdev * rdev); |
683 | struct md_rdev *md_find_rdev_nr_rcu(struct mddev *mddev, int nr); | 682 | struct md_rdev *md_find_rdev_nr_rcu(struct mddev *mddev, int nr); |
684 | static inline int mddev_check_plugged(struct mddev *mddev) | ||
685 | { | ||
686 | return !!blk_check_plugged(md_unplug, mddev, | ||
687 | sizeof(struct blk_plug_cb)); | ||
688 | } | ||
689 | 683 | ||
690 | static inline void rdev_dec_pending(struct md_rdev *rdev, struct mddev *mddev) | 684 | static inline void rdev_dec_pending(struct md_rdev *rdev, struct mddev *mddev) |
691 | { | 685 | { |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index fbc2d7851b49..a34f58772022 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1027,7 +1027,7 @@ static int get_unqueued_pending(struct r1conf *conf) | |||
1027 | static void freeze_array(struct r1conf *conf, int extra) | 1027 | static void freeze_array(struct r1conf *conf, int extra) |
1028 | { | 1028 | { |
1029 | /* Stop sync I/O and normal I/O and wait for everything to | 1029 | /* Stop sync I/O and normal I/O and wait for everything to |
1030 | * go quite. | 1030 | * go quiet. |
1031 | * This is called in two situations: | 1031 | * This is called in two situations: |
1032 | * 1) management command handlers (reshape, remove disk, quiesce). | 1032 | * 1) management command handlers (reshape, remove disk, quiesce). |
1033 | * 2) one normal I/O request failed. | 1033 | * 2) one normal I/O request failed. |
@@ -1587,9 +1587,30 @@ static void raid1_make_request(struct mddev *mddev, struct bio *bio) | |||
1587 | split = bio; | 1587 | split = bio; |
1588 | } | 1588 | } |
1589 | 1589 | ||
1590 | if (bio_data_dir(split) == READ) | 1590 | if (bio_data_dir(split) == READ) { |
1591 | raid1_read_request(mddev, split); | 1591 | raid1_read_request(mddev, split); |
1592 | else | 1592 | |
1593 | /* | ||
1594 | * If a bio is splitted, the first part of bio will | ||
1595 | * pass barrier but the bio is queued in | ||
1596 | * current->bio_list (see generic_make_request). If | ||
1597 | * there is a raise_barrier() called here, the second | ||
1598 | * part of bio can't pass barrier. But since the first | ||
1599 | * part bio isn't dispatched to underlaying disks yet, | ||
1600 | * the barrier is never released, hence raise_barrier | ||
1601 | * will alays wait. We have a deadlock. | ||
1602 | * Note, this only happens in read path. For write | ||
1603 | * path, the first part of bio is dispatched in a | ||
1604 | * schedule() call (because of blk plug) or offloaded | ||
1605 | * to raid10d. | ||
1606 | * Quitting from the function immediately can change | ||
1607 | * the bio order queued in bio_list and avoid the deadlock. | ||
1608 | */ | ||
1609 | if (split != bio) { | ||
1610 | generic_make_request(bio); | ||
1611 | break; | ||
1612 | } | ||
1613 | } else | ||
1593 | raid1_write_request(mddev, split); | 1614 | raid1_write_request(mddev, split); |
1594 | } while (split != bio); | 1615 | } while (split != bio); |
1595 | } | 1616 | } |
@@ -3246,8 +3267,6 @@ static int raid1_resize(struct mddev *mddev, sector_t sectors) | |||
3246 | return ret; | 3267 | return ret; |
3247 | } | 3268 | } |
3248 | md_set_array_sectors(mddev, newsize); | 3269 | md_set_array_sectors(mddev, newsize); |
3249 | set_capacity(mddev->gendisk, mddev->array_sectors); | ||
3250 | revalidate_disk(mddev->gendisk); | ||
3251 | if (sectors > mddev->dev_sectors && | 3270 | if (sectors > mddev->dev_sectors && |
3252 | mddev->recovery_cp > mddev->dev_sectors) { | 3271 | mddev->recovery_cp > mddev->dev_sectors) { |
3253 | mddev->recovery_cp = mddev->dev_sectors; | 3272 | mddev->recovery_cp = mddev->dev_sectors; |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 063c43d83b72..e89a8d78a9ed 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -974,7 +974,8 @@ static void wait_barrier(struct r10conf *conf) | |||
974 | !conf->barrier || | 974 | !conf->barrier || |
975 | (atomic_read(&conf->nr_pending) && | 975 | (atomic_read(&conf->nr_pending) && |
976 | current->bio_list && | 976 | current->bio_list && |
977 | !bio_list_empty(current->bio_list)), | 977 | (!bio_list_empty(¤t->bio_list[0]) || |
978 | !bio_list_empty(¤t->bio_list[1]))), | ||
978 | conf->resync_lock); | 979 | conf->resync_lock); |
979 | conf->nr_waiting--; | 980 | conf->nr_waiting--; |
980 | if (!conf->nr_waiting) | 981 | if (!conf->nr_waiting) |
@@ -1477,11 +1478,24 @@ retry_write: | |||
1477 | mbio->bi_bdev = (void*)rdev; | 1478 | mbio->bi_bdev = (void*)rdev; |
1478 | 1479 | ||
1479 | atomic_inc(&r10_bio->remaining); | 1480 | atomic_inc(&r10_bio->remaining); |
1481 | |||
1482 | cb = blk_check_plugged(raid10_unplug, mddev, | ||
1483 | sizeof(*plug)); | ||
1484 | if (cb) | ||
1485 | plug = container_of(cb, struct raid10_plug_cb, | ||
1486 | cb); | ||
1487 | else | ||
1488 | plug = NULL; | ||
1480 | spin_lock_irqsave(&conf->device_lock, flags); | 1489 | spin_lock_irqsave(&conf->device_lock, flags); |
1481 | bio_list_add(&conf->pending_bio_list, mbio); | 1490 | if (plug) { |
1482 | conf->pending_count++; | 1491 | bio_list_add(&plug->pending, mbio); |
1492 | plug->pending_cnt++; | ||
1493 | } else { | ||
1494 | bio_list_add(&conf->pending_bio_list, mbio); | ||
1495 | conf->pending_count++; | ||
1496 | } | ||
1483 | spin_unlock_irqrestore(&conf->device_lock, flags); | 1497 | spin_unlock_irqrestore(&conf->device_lock, flags); |
1484 | if (!mddev_check_plugged(mddev)) | 1498 | if (!plug) |
1485 | md_wakeup_thread(mddev->thread); | 1499 | md_wakeup_thread(mddev->thread); |
1486 | } | 1500 | } |
1487 | } | 1501 | } |
@@ -1571,7 +1585,25 @@ static void raid10_make_request(struct mddev *mddev, struct bio *bio) | |||
1571 | split = bio; | 1585 | split = bio; |
1572 | } | 1586 | } |
1573 | 1587 | ||
1588 | /* | ||
1589 | * If a bio is splitted, the first part of bio will pass | ||
1590 | * barrier but the bio is queued in current->bio_list (see | ||
1591 | * generic_make_request). If there is a raise_barrier() called | ||
1592 | * here, the second part of bio can't pass barrier. But since | ||
1593 | * the first part bio isn't dispatched to underlaying disks | ||
1594 | * yet, the barrier is never released, hence raise_barrier will | ||
1595 | * alays wait. We have a deadlock. | ||
1596 | * Note, this only happens in read path. For write path, the | ||
1597 | * first part of bio is dispatched in a schedule() call | ||
1598 | * (because of blk plug) or offloaded to raid10d. | ||
1599 | * Quitting from the function immediately can change the bio | ||
1600 | * order queued in bio_list and avoid the deadlock. | ||
1601 | */ | ||
1574 | __make_request(mddev, split); | 1602 | __make_request(mddev, split); |
1603 | if (split != bio && bio_data_dir(bio) == READ) { | ||
1604 | generic_make_request(bio); | ||
1605 | break; | ||
1606 | } | ||
1575 | } while (split != bio); | 1607 | } while (split != bio); |
1576 | 1608 | ||
1577 | /* In case raid10d snuck in to freeze_array */ | 1609 | /* In case raid10d snuck in to freeze_array */ |
@@ -3943,10 +3975,6 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors) | |||
3943 | return ret; | 3975 | return ret; |
3944 | } | 3976 | } |
3945 | md_set_array_sectors(mddev, size); | 3977 | md_set_array_sectors(mddev, size); |
3946 | if (mddev->queue) { | ||
3947 | set_capacity(mddev->gendisk, mddev->array_sectors); | ||
3948 | revalidate_disk(mddev->gendisk); | ||
3949 | } | ||
3950 | if (sectors > mddev->dev_sectors && | 3978 | if (sectors > mddev->dev_sectors && |
3951 | mddev->recovery_cp > oldsize) { | 3979 | mddev->recovery_cp > oldsize) { |
3952 | mddev->recovery_cp = oldsize; | 3980 | mddev->recovery_cp = oldsize; |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 4fb09b3fcb41..ed5cd705b985 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1401,7 +1401,8 @@ static int set_syndrome_sources(struct page **srcs, | |||
1401 | (test_bit(R5_Wantdrain, &dev->flags) || | 1401 | (test_bit(R5_Wantdrain, &dev->flags) || |
1402 | test_bit(R5_InJournal, &dev->flags))) || | 1402 | test_bit(R5_InJournal, &dev->flags))) || |
1403 | (srctype == SYNDROME_SRC_WRITTEN && | 1403 | (srctype == SYNDROME_SRC_WRITTEN && |
1404 | dev->written)) { | 1404 | (dev->written || |
1405 | test_bit(R5_InJournal, &dev->flags)))) { | ||
1405 | if (test_bit(R5_InJournal, &dev->flags)) | 1406 | if (test_bit(R5_InJournal, &dev->flags)) |
1406 | srcs[slot] = sh->dev[i].orig_page; | 1407 | srcs[slot] = sh->dev[i].orig_page; |
1407 | else | 1408 | else |
@@ -7605,8 +7606,6 @@ static int raid5_resize(struct mddev *mddev, sector_t sectors) | |||
7605 | return ret; | 7606 | return ret; |
7606 | } | 7607 | } |
7607 | md_set_array_sectors(mddev, newsize); | 7608 | md_set_array_sectors(mddev, newsize); |
7608 | set_capacity(mddev->gendisk, mddev->array_sectors); | ||
7609 | revalidate_disk(mddev->gendisk); | ||
7610 | if (sectors > mddev->dev_sectors && | 7609 | if (sectors > mddev->dev_sectors && |
7611 | mddev->recovery_cp > mddev->dev_sectors) { | 7610 | mddev->recovery_cp > mddev->dev_sectors) { |
7612 | mddev->recovery_cp = mddev->dev_sectors; | 7611 | mddev->recovery_cp = mddev->dev_sectors; |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index 248f60d171a5..ffea9859f5a7 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c | |||
@@ -2272,10 +2272,7 @@ static int xgbe_one_poll(struct napi_struct *napi, int budget) | |||
2272 | processed = xgbe_rx_poll(channel, budget); | 2272 | processed = xgbe_rx_poll(channel, budget); |
2273 | 2273 | ||
2274 | /* If we processed everything, we are done */ | 2274 | /* If we processed everything, we are done */ |
2275 | if (processed < budget) { | 2275 | if ((processed < budget) && napi_complete_done(napi, processed)) { |
2276 | /* Turn off polling */ | ||
2277 | napi_complete_done(napi, processed); | ||
2278 | |||
2279 | /* Enable Tx and Rx interrupts */ | 2276 | /* Enable Tx and Rx interrupts */ |
2280 | if (pdata->channel_irq_mode) | 2277 | if (pdata->channel_irq_mode) |
2281 | xgbe_enable_rx_tx_int(pdata, channel); | 2278 | xgbe_enable_rx_tx_int(pdata, channel); |
@@ -2317,10 +2314,7 @@ static int xgbe_all_poll(struct napi_struct *napi, int budget) | |||
2317 | } while ((processed < budget) && (processed != last_processed)); | 2314 | } while ((processed < budget) && (processed != last_processed)); |
2318 | 2315 | ||
2319 | /* If we processed everything, we are done */ | 2316 | /* If we processed everything, we are done */ |
2320 | if (processed < budget) { | 2317 | if ((processed < budget) && napi_complete_done(napi, processed)) { |
2321 | /* Turn off polling */ | ||
2322 | napi_complete_done(napi, processed); | ||
2323 | |||
2324 | /* Enable Tx and Rx interrupts */ | 2318 | /* Enable Tx and Rx interrupts */ |
2325 | xgbe_enable_rx_tx_ints(pdata); | 2319 | xgbe_enable_rx_tx_ints(pdata); |
2326 | } | 2320 | } |
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c index 581de71a958a..4c6c882c6a1c 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c | |||
@@ -213,9 +213,9 @@ void aq_pci_func_free_irqs(struct aq_pci_func_s *self) | |||
213 | if (!((1U << i) & self->msix_entry_mask)) | 213 | if (!((1U << i) & self->msix_entry_mask)) |
214 | continue; | 214 | continue; |
215 | 215 | ||
216 | free_irq(pci_irq_vector(pdev, i), self->aq_vec[i]); | ||
217 | if (pdev->msix_enabled) | 216 | if (pdev->msix_enabled) |
218 | irq_set_affinity_hint(pci_irq_vector(pdev, i), NULL); | 217 | irq_set_affinity_hint(pci_irq_vector(pdev, i), NULL); |
218 | free_irq(pci_irq_vector(pdev, i), self->aq_vec[i]); | ||
219 | self->msix_entry_mask &= ~(1U << i); | 219 | self->msix_entry_mask &= ~(1U << i); |
220 | } | 220 | } |
221 | } | 221 | } |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index d8d06fdfc42b..ac76fc251d26 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -13292,17 +13292,15 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev, | |||
13292 | dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 13292 | dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
13293 | NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA; | 13293 | NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA; |
13294 | 13294 | ||
13295 | /* VF with OLD Hypervisor or old PF do not support filtering */ | ||
13296 | if (IS_PF(bp)) { | 13295 | if (IS_PF(bp)) { |
13297 | if (chip_is_e1x) | 13296 | if (chip_is_e1x) |
13298 | bp->accept_any_vlan = true; | 13297 | bp->accept_any_vlan = true; |
13299 | else | 13298 | else |
13300 | dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER; | 13299 | dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER; |
13301 | #ifdef CONFIG_BNX2X_SRIOV | ||
13302 | } else if (bp->acquire_resp.pfdev_info.pf_cap & PFVF_CAP_VLAN_FILTER) { | ||
13303 | dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER; | ||
13304 | #endif | ||
13305 | } | 13300 | } |
13301 | /* For VF we'll know whether to enable VLAN filtering after | ||
13302 | * getting a response to CHANNEL_TLV_ACQUIRE from PF. | ||
13303 | */ | ||
13306 | 13304 | ||
13307 | dev->features |= dev->hw_features | NETIF_F_HW_VLAN_CTAG_RX; | 13305 | dev->features |= dev->hw_features | NETIF_F_HW_VLAN_CTAG_RX; |
13308 | dev->features |= NETIF_F_HIGHDMA; | 13306 | dev->features |= NETIF_F_HIGHDMA; |
@@ -13738,7 +13736,7 @@ static int bnx2x_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) | |||
13738 | if (!netif_running(bp->dev)) { | 13736 | if (!netif_running(bp->dev)) { |
13739 | DP(BNX2X_MSG_PTP, | 13737 | DP(BNX2X_MSG_PTP, |
13740 | "PTP adjfreq called while the interface is down\n"); | 13738 | "PTP adjfreq called while the interface is down\n"); |
13741 | return -EFAULT; | 13739 | return -ENETDOWN; |
13742 | } | 13740 | } |
13743 | 13741 | ||
13744 | if (ppb < 0) { | 13742 | if (ppb < 0) { |
@@ -13797,6 +13795,12 @@ static int bnx2x_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) | |||
13797 | { | 13795 | { |
13798 | struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info); | 13796 | struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info); |
13799 | 13797 | ||
13798 | if (!netif_running(bp->dev)) { | ||
13799 | DP(BNX2X_MSG_PTP, | ||
13800 | "PTP adjtime called while the interface is down\n"); | ||
13801 | return -ENETDOWN; | ||
13802 | } | ||
13803 | |||
13800 | DP(BNX2X_MSG_PTP, "PTP adjtime called, delta = %llx\n", delta); | 13804 | DP(BNX2X_MSG_PTP, "PTP adjtime called, delta = %llx\n", delta); |
13801 | 13805 | ||
13802 | timecounter_adjtime(&bp->timecounter, delta); | 13806 | timecounter_adjtime(&bp->timecounter, delta); |
@@ -13809,6 +13813,12 @@ static int bnx2x_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) | |||
13809 | struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info); | 13813 | struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info); |
13810 | u64 ns; | 13814 | u64 ns; |
13811 | 13815 | ||
13816 | if (!netif_running(bp->dev)) { | ||
13817 | DP(BNX2X_MSG_PTP, | ||
13818 | "PTP gettime called while the interface is down\n"); | ||
13819 | return -ENETDOWN; | ||
13820 | } | ||
13821 | |||
13812 | ns = timecounter_read(&bp->timecounter); | 13822 | ns = timecounter_read(&bp->timecounter); |
13813 | 13823 | ||
13814 | DP(BNX2X_MSG_PTP, "PTP gettime called, ns = %llu\n", ns); | 13824 | DP(BNX2X_MSG_PTP, "PTP gettime called, ns = %llu\n", ns); |
@@ -13824,6 +13834,12 @@ static int bnx2x_ptp_settime(struct ptp_clock_info *ptp, | |||
13824 | struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info); | 13834 | struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info); |
13825 | u64 ns; | 13835 | u64 ns; |
13826 | 13836 | ||
13837 | if (!netif_running(bp->dev)) { | ||
13838 | DP(BNX2X_MSG_PTP, | ||
13839 | "PTP settime called while the interface is down\n"); | ||
13840 | return -ENETDOWN; | ||
13841 | } | ||
13842 | |||
13827 | ns = timespec64_to_ns(ts); | 13843 | ns = timespec64_to_ns(ts); |
13828 | 13844 | ||
13829 | DP(BNX2X_MSG_PTP, "PTP settime called, ns = %llu\n", ns); | 13845 | DP(BNX2X_MSG_PTP, "PTP settime called, ns = %llu\n", ns); |
@@ -13991,6 +14007,14 @@ static int bnx2x_init_one(struct pci_dev *pdev, | |||
13991 | rc = bnx2x_vfpf_acquire(bp, tx_count, rx_count); | 14007 | rc = bnx2x_vfpf_acquire(bp, tx_count, rx_count); |
13992 | if (rc) | 14008 | if (rc) |
13993 | goto init_one_freemem; | 14009 | goto init_one_freemem; |
14010 | |||
14011 | #ifdef CONFIG_BNX2X_SRIOV | ||
14012 | /* VF with OLD Hypervisor or old PF do not support filtering */ | ||
14013 | if (bp->acquire_resp.pfdev_info.pf_cap & PFVF_CAP_VLAN_FILTER) { | ||
14014 | dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER; | ||
14015 | dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; | ||
14016 | } | ||
14017 | #endif | ||
13994 | } | 14018 | } |
13995 | 14019 | ||
13996 | /* Enable SRIOV if capability found in configuration space */ | 14020 | /* Enable SRIOV if capability found in configuration space */ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index 6fad22adbbb9..bdfd53b46bc5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | |||
@@ -434,7 +434,9 @@ static int bnx2x_vf_mac_vlan_config(struct bnx2x *bp, | |||
434 | 434 | ||
435 | /* Add/Remove the filter */ | 435 | /* Add/Remove the filter */ |
436 | rc = bnx2x_config_vlan_mac(bp, &ramrod); | 436 | rc = bnx2x_config_vlan_mac(bp, &ramrod); |
437 | if (rc && rc != -EEXIST) { | 437 | if (rc == -EEXIST) |
438 | return 0; | ||
439 | if (rc) { | ||
438 | BNX2X_ERR("Failed to %s %s\n", | 440 | BNX2X_ERR("Failed to %s %s\n", |
439 | filter->add ? "add" : "delete", | 441 | filter->add ? "add" : "delete", |
440 | (filter->type == BNX2X_VF_FILTER_VLAN_MAC) ? | 442 | (filter->type == BNX2X_VF_FILTER_VLAN_MAC) ? |
@@ -444,6 +446,8 @@ static int bnx2x_vf_mac_vlan_config(struct bnx2x *bp, | |||
444 | return rc; | 446 | return rc; |
445 | } | 447 | } |
446 | 448 | ||
449 | filter->applied = true; | ||
450 | |||
447 | return 0; | 451 | return 0; |
448 | } | 452 | } |
449 | 453 | ||
@@ -469,8 +473,10 @@ int bnx2x_vf_mac_vlan_config_list(struct bnx2x *bp, struct bnx2x_virtf *vf, | |||
469 | /* Rollback if needed */ | 473 | /* Rollback if needed */ |
470 | if (i != filters->count) { | 474 | if (i != filters->count) { |
471 | BNX2X_ERR("Managed only %d/%d filters - rolling back\n", | 475 | BNX2X_ERR("Managed only %d/%d filters - rolling back\n", |
472 | i, filters->count + 1); | 476 | i, filters->count); |
473 | while (--i >= 0) { | 477 | while (--i >= 0) { |
478 | if (!filters->filters[i].applied) | ||
479 | continue; | ||
474 | filters->filters[i].add = !filters->filters[i].add; | 480 | filters->filters[i].add = !filters->filters[i].add; |
475 | bnx2x_vf_mac_vlan_config(bp, vf, qid, | 481 | bnx2x_vf_mac_vlan_config(bp, vf, qid, |
476 | &filters->filters[i], | 482 | &filters->filters[i], |
@@ -1899,7 +1905,8 @@ void bnx2x_iov_adjust_stats_req(struct bnx2x *bp) | |||
1899 | continue; | 1905 | continue; |
1900 | } | 1906 | } |
1901 | 1907 | ||
1902 | DP(BNX2X_MSG_IOV, "add addresses for vf %d\n", vf->abs_vfid); | 1908 | DP_AND((BNX2X_MSG_IOV | BNX2X_MSG_STATS), |
1909 | "add addresses for vf %d\n", vf->abs_vfid); | ||
1903 | for_each_vfq(vf, j) { | 1910 | for_each_vfq(vf, j) { |
1904 | struct bnx2x_vf_queue *rxq = vfq_get(vf, j); | 1911 | struct bnx2x_vf_queue *rxq = vfq_get(vf, j); |
1905 | 1912 | ||
@@ -1920,11 +1927,12 @@ void bnx2x_iov_adjust_stats_req(struct bnx2x *bp) | |||
1920 | cpu_to_le32(U64_HI(q_stats_addr)); | 1927 | cpu_to_le32(U64_HI(q_stats_addr)); |
1921 | cur_query_entry->address.lo = | 1928 | cur_query_entry->address.lo = |
1922 | cpu_to_le32(U64_LO(q_stats_addr)); | 1929 | cpu_to_le32(U64_LO(q_stats_addr)); |
1923 | DP(BNX2X_MSG_IOV, | 1930 | DP_AND((BNX2X_MSG_IOV | BNX2X_MSG_STATS), |
1924 | "added address %x %x for vf %d queue %d client %d\n", | 1931 | "added address %x %x for vf %d queue %d client %d\n", |
1925 | cur_query_entry->address.hi, | 1932 | cur_query_entry->address.hi, |
1926 | cur_query_entry->address.lo, cur_query_entry->funcID, | 1933 | cur_query_entry->address.lo, |
1927 | j, cur_query_entry->index); | 1934 | cur_query_entry->funcID, |
1935 | j, cur_query_entry->index); | ||
1928 | cur_query_entry++; | 1936 | cur_query_entry++; |
1929 | cur_data_offset += sizeof(struct per_queue_stats); | 1937 | cur_data_offset += sizeof(struct per_queue_stats); |
1930 | stats_count++; | 1938 | stats_count++; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h index 7a6d406f4c11..888d0b6632e8 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h | |||
@@ -114,6 +114,7 @@ struct bnx2x_vf_mac_vlan_filter { | |||
114 | (BNX2X_VF_FILTER_MAC | BNX2X_VF_FILTER_VLAN) /*shortcut*/ | 114 | (BNX2X_VF_FILTER_MAC | BNX2X_VF_FILTER_VLAN) /*shortcut*/ |
115 | 115 | ||
116 | bool add; | 116 | bool add; |
117 | bool applied; | ||
117 | u8 *mac; | 118 | u8 *mac; |
118 | u16 vid; | 119 | u16 vid; |
119 | }; | 120 | }; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c index bfae300cf25f..76a4668c50fe 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c | |||
@@ -868,7 +868,7 @@ int bnx2x_vfpf_set_mcast(struct net_device *dev) | |||
868 | struct bnx2x *bp = netdev_priv(dev); | 868 | struct bnx2x *bp = netdev_priv(dev); |
869 | struct vfpf_set_q_filters_tlv *req = &bp->vf2pf_mbox->req.set_q_filters; | 869 | struct vfpf_set_q_filters_tlv *req = &bp->vf2pf_mbox->req.set_q_filters; |
870 | struct pfvf_general_resp_tlv *resp = &bp->vf2pf_mbox->resp.general_resp; | 870 | struct pfvf_general_resp_tlv *resp = &bp->vf2pf_mbox->resp.general_resp; |
871 | int rc, i = 0; | 871 | int rc = 0, i = 0; |
872 | struct netdev_hw_addr *ha; | 872 | struct netdev_hw_addr *ha; |
873 | 873 | ||
874 | if (bp->state != BNX2X_STATE_OPEN) { | 874 | if (bp->state != BNX2X_STATE_OPEN) { |
@@ -883,6 +883,15 @@ int bnx2x_vfpf_set_mcast(struct net_device *dev) | |||
883 | /* Get Rx mode requested */ | 883 | /* Get Rx mode requested */ |
884 | DP(NETIF_MSG_IFUP, "dev->flags = %x\n", dev->flags); | 884 | DP(NETIF_MSG_IFUP, "dev->flags = %x\n", dev->flags); |
885 | 885 | ||
886 | /* We support PFVF_MAX_MULTICAST_PER_VF mcast addresses tops */ | ||
887 | if (netdev_mc_count(dev) > PFVF_MAX_MULTICAST_PER_VF) { | ||
888 | DP(NETIF_MSG_IFUP, | ||
889 | "VF supports not more than %d multicast MAC addresses\n", | ||
890 | PFVF_MAX_MULTICAST_PER_VF); | ||
891 | rc = -EINVAL; | ||
892 | goto out; | ||
893 | } | ||
894 | |||
886 | netdev_for_each_mc_addr(ha, dev) { | 895 | netdev_for_each_mc_addr(ha, dev) { |
887 | DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n", | 896 | DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n", |
888 | bnx2x_mc_addr(ha)); | 897 | bnx2x_mc_addr(ha)); |
@@ -890,16 +899,6 @@ int bnx2x_vfpf_set_mcast(struct net_device *dev) | |||
890 | i++; | 899 | i++; |
891 | } | 900 | } |
892 | 901 | ||
893 | /* We support four PFVF_MAX_MULTICAST_PER_VF mcast | ||
894 | * addresses tops | ||
895 | */ | ||
896 | if (i >= PFVF_MAX_MULTICAST_PER_VF) { | ||
897 | DP(NETIF_MSG_IFUP, | ||
898 | "VF supports not more than %d multicast MAC addresses\n", | ||
899 | PFVF_MAX_MULTICAST_PER_VF); | ||
900 | return -EINVAL; | ||
901 | } | ||
902 | |||
903 | req->n_multicast = i; | 902 | req->n_multicast = i; |
904 | req->flags |= VFPF_SET_Q_FILTERS_MULTICAST_CHANGED; | 903 | req->flags |= VFPF_SET_Q_FILTERS_MULTICAST_CHANGED; |
905 | req->vf_qid = 0; | 904 | req->vf_qid = 0; |
@@ -924,7 +923,7 @@ int bnx2x_vfpf_set_mcast(struct net_device *dev) | |||
924 | out: | 923 | out: |
925 | bnx2x_vfpf_finalize(bp, &req->first_tlv); | 924 | bnx2x_vfpf_finalize(bp, &req->first_tlv); |
926 | 925 | ||
927 | return 0; | 926 | return rc; |
928 | } | 927 | } |
929 | 928 | ||
930 | /* request pf to add a vlan for the vf */ | 929 | /* request pf to add a vlan for the vf */ |
@@ -1778,6 +1777,23 @@ static int bnx2x_vf_mbx_qfilters(struct bnx2x *bp, struct bnx2x_virtf *vf) | |||
1778 | goto op_err; | 1777 | goto op_err; |
1779 | } | 1778 | } |
1780 | 1779 | ||
1780 | /* build vlan list */ | ||
1781 | fl = NULL; | ||
1782 | |||
1783 | rc = bnx2x_vf_mbx_macvlan_list(bp, vf, msg, &fl, | ||
1784 | VFPF_VLAN_FILTER); | ||
1785 | if (rc) | ||
1786 | goto op_err; | ||
1787 | |||
1788 | if (fl) { | ||
1789 | /* set vlan list */ | ||
1790 | rc = bnx2x_vf_mac_vlan_config_list(bp, vf, fl, | ||
1791 | msg->vf_qid, | ||
1792 | false); | ||
1793 | if (rc) | ||
1794 | goto op_err; | ||
1795 | } | ||
1796 | |||
1781 | } | 1797 | } |
1782 | 1798 | ||
1783 | if (msg->flags & VFPF_SET_Q_FILTERS_RX_MASK_CHANGED) { | 1799 | if (msg->flags & VFPF_SET_Q_FILTERS_RX_MASK_CHANGED) { |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 235733e91c79..32de4589d16a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
@@ -4465,6 +4465,10 @@ static int bnxt_hwrm_func_qcfg(struct bnxt *bp) | |||
4465 | vf->vlan = le16_to_cpu(resp->vlan) & VLAN_VID_MASK; | 4465 | vf->vlan = le16_to_cpu(resp->vlan) & VLAN_VID_MASK; |
4466 | } | 4466 | } |
4467 | #endif | 4467 | #endif |
4468 | if (BNXT_PF(bp) && (le16_to_cpu(resp->flags) & | ||
4469 | FUNC_QCFG_RESP_FLAGS_FW_DCBX_AGENT_ENABLED)) | ||
4470 | bp->flags |= BNXT_FLAG_FW_LLDP_AGENT; | ||
4471 | |||
4468 | switch (resp->port_partition_type) { | 4472 | switch (resp->port_partition_type) { |
4469 | case FUNC_QCFG_RESP_PORT_PARTITION_TYPE_NPAR1_0: | 4473 | case FUNC_QCFG_RESP_PORT_PARTITION_TYPE_NPAR1_0: |
4470 | case FUNC_QCFG_RESP_PORT_PARTITION_TYPE_NPAR1_5: | 4474 | case FUNC_QCFG_RESP_PORT_PARTITION_TYPE_NPAR1_5: |
@@ -5507,8 +5511,9 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp) | |||
5507 | bp->lpi_tmr_hi = le32_to_cpu(resp->valid_tx_lpi_timer_high) & | 5511 | bp->lpi_tmr_hi = le32_to_cpu(resp->valid_tx_lpi_timer_high) & |
5508 | PORT_PHY_QCAPS_RESP_TX_LPI_TIMER_HIGH_MASK; | 5512 | PORT_PHY_QCAPS_RESP_TX_LPI_TIMER_HIGH_MASK; |
5509 | } | 5513 | } |
5510 | link_info->support_auto_speeds = | 5514 | if (resp->supported_speeds_auto_mode) |
5511 | le16_to_cpu(resp->supported_speeds_auto_mode); | 5515 | link_info->support_auto_speeds = |
5516 | le16_to_cpu(resp->supported_speeds_auto_mode); | ||
5512 | 5517 | ||
5513 | hwrm_phy_qcaps_exit: | 5518 | hwrm_phy_qcaps_exit: |
5514 | mutex_unlock(&bp->hwrm_cmd_lock); | 5519 | mutex_unlock(&bp->hwrm_cmd_lock); |
@@ -6495,8 +6500,14 @@ static void bnxt_reset_task(struct bnxt *bp, bool silent) | |||
6495 | if (!silent) | 6500 | if (!silent) |
6496 | bnxt_dbg_dump_states(bp); | 6501 | bnxt_dbg_dump_states(bp); |
6497 | if (netif_running(bp->dev)) { | 6502 | if (netif_running(bp->dev)) { |
6503 | int rc; | ||
6504 | |||
6505 | if (!silent) | ||
6506 | bnxt_ulp_stop(bp); | ||
6498 | bnxt_close_nic(bp, false, false); | 6507 | bnxt_close_nic(bp, false, false); |
6499 | bnxt_open_nic(bp, false, false); | 6508 | rc = bnxt_open_nic(bp, false, false); |
6509 | if (!silent && !rc) | ||
6510 | bnxt_ulp_start(bp); | ||
6500 | } | 6511 | } |
6501 | } | 6512 | } |
6502 | 6513 | ||
@@ -7444,6 +7455,10 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
7444 | if (rc) | 7455 | if (rc) |
7445 | goto init_err_pci_clean; | 7456 | goto init_err_pci_clean; |
7446 | 7457 | ||
7458 | rc = bnxt_hwrm_func_reset(bp); | ||
7459 | if (rc) | ||
7460 | goto init_err_pci_clean; | ||
7461 | |||
7447 | bnxt_hwrm_fw_set_time(bp); | 7462 | bnxt_hwrm_fw_set_time(bp); |
7448 | 7463 | ||
7449 | dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG | | 7464 | dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG | |
@@ -7554,10 +7569,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
7554 | if (rc) | 7569 | if (rc) |
7555 | goto init_err_pci_clean; | 7570 | goto init_err_pci_clean; |
7556 | 7571 | ||
7557 | rc = bnxt_hwrm_func_reset(bp); | ||
7558 | if (rc) | ||
7559 | goto init_err_pci_clean; | ||
7560 | |||
7561 | rc = bnxt_init_int_mode(bp); | 7572 | rc = bnxt_init_int_mode(bp); |
7562 | if (rc) | 7573 | if (rc) |
7563 | goto init_err_pci_clean; | 7574 | goto init_err_pci_clean; |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index faf26a2f726b..c7a5b84a5cb2 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h | |||
@@ -993,6 +993,7 @@ struct bnxt { | |||
993 | BNXT_FLAG_ROCEV2_CAP) | 993 | BNXT_FLAG_ROCEV2_CAP) |
994 | #define BNXT_FLAG_NO_AGG_RINGS 0x20000 | 994 | #define BNXT_FLAG_NO_AGG_RINGS 0x20000 |
995 | #define BNXT_FLAG_RX_PAGE_MODE 0x40000 | 995 | #define BNXT_FLAG_RX_PAGE_MODE 0x40000 |
996 | #define BNXT_FLAG_FW_LLDP_AGENT 0x80000 | ||
996 | #define BNXT_FLAG_CHIP_NITRO_A0 0x1000000 | 997 | #define BNXT_FLAG_CHIP_NITRO_A0 0x1000000 |
997 | 998 | ||
998 | #define BNXT_FLAG_ALL_CONFIG_FEATS (BNXT_FLAG_TPA | \ | 999 | #define BNXT_FLAG_ALL_CONFIG_FEATS (BNXT_FLAG_TPA | \ |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c index fdf2d8caf7bf..03532061d211 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c | |||
@@ -474,7 +474,7 @@ void bnxt_dcb_init(struct bnxt *bp) | |||
474 | return; | 474 | return; |
475 | 475 | ||
476 | bp->dcbx_cap = DCB_CAP_DCBX_VER_IEEE; | 476 | bp->dcbx_cap = DCB_CAP_DCBX_VER_IEEE; |
477 | if (BNXT_PF(bp)) | 477 | if (BNXT_PF(bp) && !(bp->flags & BNXT_FLAG_FW_LLDP_AGENT)) |
478 | bp->dcbx_cap |= DCB_CAP_DCBX_HOST; | 478 | bp->dcbx_cap |= DCB_CAP_DCBX_HOST; |
479 | else | 479 | else |
480 | bp->dcbx_cap |= DCB_CAP_DCBX_LLD_MANAGED; | 480 | bp->dcbx_cap |= DCB_CAP_DCBX_LLD_MANAGED; |
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index f92896835d2a..69015fa50f20 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Broadcom GENET (Gigabit Ethernet) controller driver | 2 | * Broadcom GENET (Gigabit Ethernet) controller driver |
3 | * | 3 | * |
4 | * Copyright (c) 2014 Broadcom Corporation | 4 | * Copyright (c) 2014-2017 Broadcom |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 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 as | 7 | * it under the terms of the GNU General Public License version 2 as |
@@ -450,6 +450,22 @@ static inline void bcmgenet_rdma_ring_writel(struct bcmgenet_priv *priv, | |||
450 | genet_dma_ring_regs[r]); | 450 | genet_dma_ring_regs[r]); |
451 | } | 451 | } |
452 | 452 | ||
453 | static int bcmgenet_begin(struct net_device *dev) | ||
454 | { | ||
455 | struct bcmgenet_priv *priv = netdev_priv(dev); | ||
456 | |||
457 | /* Turn on the clock */ | ||
458 | return clk_prepare_enable(priv->clk); | ||
459 | } | ||
460 | |||
461 | static void bcmgenet_complete(struct net_device *dev) | ||
462 | { | ||
463 | struct bcmgenet_priv *priv = netdev_priv(dev); | ||
464 | |||
465 | /* Turn off the clock */ | ||
466 | clk_disable_unprepare(priv->clk); | ||
467 | } | ||
468 | |||
453 | static int bcmgenet_get_link_ksettings(struct net_device *dev, | 469 | static int bcmgenet_get_link_ksettings(struct net_device *dev, |
454 | struct ethtool_link_ksettings *cmd) | 470 | struct ethtool_link_ksettings *cmd) |
455 | { | 471 | { |
@@ -778,8 +794,9 @@ static const struct bcmgenet_stats bcmgenet_gstrings_stats[] = { | |||
778 | STAT_GENET_RUNT("rx_runt_bytes", mib.rx_runt_bytes), | 794 | STAT_GENET_RUNT("rx_runt_bytes", mib.rx_runt_bytes), |
779 | /* Misc UniMAC counters */ | 795 | /* Misc UniMAC counters */ |
780 | STAT_GENET_MISC("rbuf_ovflow_cnt", mib.rbuf_ovflow_cnt, | 796 | STAT_GENET_MISC("rbuf_ovflow_cnt", mib.rbuf_ovflow_cnt, |
781 | UMAC_RBUF_OVFL_CNT), | 797 | UMAC_RBUF_OVFL_CNT_V1), |
782 | STAT_GENET_MISC("rbuf_err_cnt", mib.rbuf_err_cnt, UMAC_RBUF_ERR_CNT), | 798 | STAT_GENET_MISC("rbuf_err_cnt", mib.rbuf_err_cnt, |
799 | UMAC_RBUF_ERR_CNT_V1), | ||
783 | STAT_GENET_MISC("mdf_err_cnt", mib.mdf_err_cnt, UMAC_MDF_ERR_CNT), | 800 | STAT_GENET_MISC("mdf_err_cnt", mib.mdf_err_cnt, UMAC_MDF_ERR_CNT), |
784 | STAT_GENET_SOFT_MIB("alloc_rx_buff_failed", mib.alloc_rx_buff_failed), | 801 | STAT_GENET_SOFT_MIB("alloc_rx_buff_failed", mib.alloc_rx_buff_failed), |
785 | STAT_GENET_SOFT_MIB("rx_dma_failed", mib.rx_dma_failed), | 802 | STAT_GENET_SOFT_MIB("rx_dma_failed", mib.rx_dma_failed), |
@@ -821,6 +838,45 @@ static void bcmgenet_get_strings(struct net_device *dev, u32 stringset, | |||
821 | } | 838 | } |
822 | } | 839 | } |
823 | 840 | ||
841 | static u32 bcmgenet_update_stat_misc(struct bcmgenet_priv *priv, u16 offset) | ||
842 | { | ||
843 | u16 new_offset; | ||
844 | u32 val; | ||
845 | |||
846 | switch (offset) { | ||
847 | case UMAC_RBUF_OVFL_CNT_V1: | ||
848 | if (GENET_IS_V2(priv)) | ||
849 | new_offset = RBUF_OVFL_CNT_V2; | ||
850 | else | ||
851 | new_offset = RBUF_OVFL_CNT_V3PLUS; | ||
852 | |||
853 | val = bcmgenet_rbuf_readl(priv, new_offset); | ||
854 | /* clear if overflowed */ | ||
855 | if (val == ~0) | ||
856 | bcmgenet_rbuf_writel(priv, 0, new_offset); | ||
857 | break; | ||
858 | case UMAC_RBUF_ERR_CNT_V1: | ||
859 | if (GENET_IS_V2(priv)) | ||
860 | new_offset = RBUF_ERR_CNT_V2; | ||
861 | else | ||
862 | new_offset = RBUF_ERR_CNT_V3PLUS; | ||
863 | |||
864 | val = bcmgenet_rbuf_readl(priv, new_offset); | ||
865 | /* clear if overflowed */ | ||
866 | if (val == ~0) | ||
867 | bcmgenet_rbuf_writel(priv, 0, new_offset); | ||
868 | break; | ||
869 | default: | ||
870 | val = bcmgenet_umac_readl(priv, offset); | ||
871 | /* clear if overflowed */ | ||
872 | if (val == ~0) | ||
873 | bcmgenet_umac_writel(priv, 0, offset); | ||
874 | break; | ||
875 | } | ||
876 | |||
877 | return val; | ||
878 | } | ||
879 | |||
824 | static void bcmgenet_update_mib_counters(struct bcmgenet_priv *priv) | 880 | static void bcmgenet_update_mib_counters(struct bcmgenet_priv *priv) |
825 | { | 881 | { |
826 | int i, j = 0; | 882 | int i, j = 0; |
@@ -836,19 +892,28 @@ static void bcmgenet_update_mib_counters(struct bcmgenet_priv *priv) | |||
836 | case BCMGENET_STAT_NETDEV: | 892 | case BCMGENET_STAT_NETDEV: |
837 | case BCMGENET_STAT_SOFT: | 893 | case BCMGENET_STAT_SOFT: |
838 | continue; | 894 | continue; |
839 | case BCMGENET_STAT_MIB_RX: | ||
840 | case BCMGENET_STAT_MIB_TX: | ||
841 | case BCMGENET_STAT_RUNT: | 895 | case BCMGENET_STAT_RUNT: |
842 | if (s->type != BCMGENET_STAT_MIB_RX) | 896 | offset += BCMGENET_STAT_OFFSET; |
843 | offset = BCMGENET_STAT_OFFSET; | 897 | /* fall through */ |
898 | case BCMGENET_STAT_MIB_TX: | ||
899 | offset += BCMGENET_STAT_OFFSET; | ||
900 | /* fall through */ | ||
901 | case BCMGENET_STAT_MIB_RX: | ||
844 | val = bcmgenet_umac_readl(priv, | 902 | val = bcmgenet_umac_readl(priv, |
845 | UMAC_MIB_START + j + offset); | 903 | UMAC_MIB_START + j + offset); |
904 | offset = 0; /* Reset Offset */ | ||
846 | break; | 905 | break; |
847 | case BCMGENET_STAT_MISC: | 906 | case BCMGENET_STAT_MISC: |
848 | val = bcmgenet_umac_readl(priv, s->reg_offset); | 907 | if (GENET_IS_V1(priv)) { |
849 | /* clear if overflowed */ | 908 | val = bcmgenet_umac_readl(priv, s->reg_offset); |
850 | if (val == ~0) | 909 | /* clear if overflowed */ |
851 | bcmgenet_umac_writel(priv, 0, s->reg_offset); | 910 | if (val == ~0) |
911 | bcmgenet_umac_writel(priv, 0, | ||
912 | s->reg_offset); | ||
913 | } else { | ||
914 | val = bcmgenet_update_stat_misc(priv, | ||
915 | s->reg_offset); | ||
916 | } | ||
852 | break; | 917 | break; |
853 | } | 918 | } |
854 | 919 | ||
@@ -973,6 +1038,8 @@ static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_eee *e) | |||
973 | 1038 | ||
974 | /* standard ethtool support functions. */ | 1039 | /* standard ethtool support functions. */ |
975 | static const struct ethtool_ops bcmgenet_ethtool_ops = { | 1040 | static const struct ethtool_ops bcmgenet_ethtool_ops = { |
1041 | .begin = bcmgenet_begin, | ||
1042 | .complete = bcmgenet_complete, | ||
976 | .get_strings = bcmgenet_get_strings, | 1043 | .get_strings = bcmgenet_get_strings, |
977 | .get_sset_count = bcmgenet_get_sset_count, | 1044 | .get_sset_count = bcmgenet_get_sset_count, |
978 | .get_ethtool_stats = bcmgenet_get_ethtool_stats, | 1045 | .get_ethtool_stats = bcmgenet_get_ethtool_stats, |
@@ -1167,7 +1234,6 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, | |||
1167 | struct bcmgenet_priv *priv = netdev_priv(dev); | 1234 | struct bcmgenet_priv *priv = netdev_priv(dev); |
1168 | struct device *kdev = &priv->pdev->dev; | 1235 | struct device *kdev = &priv->pdev->dev; |
1169 | struct enet_cb *tx_cb_ptr; | 1236 | struct enet_cb *tx_cb_ptr; |
1170 | struct netdev_queue *txq; | ||
1171 | unsigned int pkts_compl = 0; | 1237 | unsigned int pkts_compl = 0; |
1172 | unsigned int bytes_compl = 0; | 1238 | unsigned int bytes_compl = 0; |
1173 | unsigned int c_index; | 1239 | unsigned int c_index; |
@@ -1219,13 +1285,8 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, | |||
1219 | dev->stats.tx_packets += pkts_compl; | 1285 | dev->stats.tx_packets += pkts_compl; |
1220 | dev->stats.tx_bytes += bytes_compl; | 1286 | dev->stats.tx_bytes += bytes_compl; |
1221 | 1287 | ||
1222 | txq = netdev_get_tx_queue(dev, ring->queue); | 1288 | netdev_tx_completed_queue(netdev_get_tx_queue(dev, ring->queue), |
1223 | netdev_tx_completed_queue(txq, pkts_compl, bytes_compl); | 1289 | pkts_compl, bytes_compl); |
1224 | |||
1225 | if (ring->free_bds > (MAX_SKB_FRAGS + 1)) { | ||
1226 | if (netif_tx_queue_stopped(txq)) | ||
1227 | netif_tx_wake_queue(txq); | ||
1228 | } | ||
1229 | 1290 | ||
1230 | return pkts_compl; | 1291 | return pkts_compl; |
1231 | } | 1292 | } |
@@ -1248,8 +1309,16 @@ static int bcmgenet_tx_poll(struct napi_struct *napi, int budget) | |||
1248 | struct bcmgenet_tx_ring *ring = | 1309 | struct bcmgenet_tx_ring *ring = |
1249 | container_of(napi, struct bcmgenet_tx_ring, napi); | 1310 | container_of(napi, struct bcmgenet_tx_ring, napi); |
1250 | unsigned int work_done = 0; | 1311 | unsigned int work_done = 0; |
1312 | struct netdev_queue *txq; | ||
1313 | unsigned long flags; | ||
1251 | 1314 | ||
1252 | work_done = bcmgenet_tx_reclaim(ring->priv->dev, ring); | 1315 | spin_lock_irqsave(&ring->lock, flags); |
1316 | work_done = __bcmgenet_tx_reclaim(ring->priv->dev, ring); | ||
1317 | if (ring->free_bds > (MAX_SKB_FRAGS + 1)) { | ||
1318 | txq = netdev_get_tx_queue(ring->priv->dev, ring->queue); | ||
1319 | netif_tx_wake_queue(txq); | ||
1320 | } | ||
1321 | spin_unlock_irqrestore(&ring->lock, flags); | ||
1253 | 1322 | ||
1254 | if (work_done == 0) { | 1323 | if (work_done == 0) { |
1255 | napi_complete(napi); | 1324 | napi_complete(napi); |
@@ -2457,24 +2526,28 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv) | |||
2457 | /* Interrupt bottom half */ | 2526 | /* Interrupt bottom half */ |
2458 | static void bcmgenet_irq_task(struct work_struct *work) | 2527 | static void bcmgenet_irq_task(struct work_struct *work) |
2459 | { | 2528 | { |
2529 | unsigned long flags; | ||
2530 | unsigned int status; | ||
2460 | struct bcmgenet_priv *priv = container_of( | 2531 | struct bcmgenet_priv *priv = container_of( |
2461 | work, struct bcmgenet_priv, bcmgenet_irq_work); | 2532 | work, struct bcmgenet_priv, bcmgenet_irq_work); |
2462 | 2533 | ||
2463 | netif_dbg(priv, intr, priv->dev, "%s\n", __func__); | 2534 | netif_dbg(priv, intr, priv->dev, "%s\n", __func__); |
2464 | 2535 | ||
2465 | if (priv->irq0_stat & UMAC_IRQ_MPD_R) { | 2536 | spin_lock_irqsave(&priv->lock, flags); |
2466 | priv->irq0_stat &= ~UMAC_IRQ_MPD_R; | 2537 | status = priv->irq0_stat; |
2538 | priv->irq0_stat = 0; | ||
2539 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2540 | |||
2541 | if (status & UMAC_IRQ_MPD_R) { | ||
2467 | netif_dbg(priv, wol, priv->dev, | 2542 | netif_dbg(priv, wol, priv->dev, |
2468 | "magic packet detected, waking up\n"); | 2543 | "magic packet detected, waking up\n"); |
2469 | bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC); | 2544 | bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC); |
2470 | } | 2545 | } |
2471 | 2546 | ||
2472 | /* Link UP/DOWN event */ | 2547 | /* Link UP/DOWN event */ |
2473 | if (priv->irq0_stat & UMAC_IRQ_LINK_EVENT) { | 2548 | if (status & UMAC_IRQ_LINK_EVENT) |
2474 | phy_mac_interrupt(priv->phydev, | 2549 | phy_mac_interrupt(priv->phydev, |
2475 | !!(priv->irq0_stat & UMAC_IRQ_LINK_UP)); | 2550 | !!(status & UMAC_IRQ_LINK_UP)); |
2476 | priv->irq0_stat &= ~UMAC_IRQ_LINK_EVENT; | ||
2477 | } | ||
2478 | } | 2551 | } |
2479 | 2552 | ||
2480 | /* bcmgenet_isr1: handle Rx and Tx priority queues */ | 2553 | /* bcmgenet_isr1: handle Rx and Tx priority queues */ |
@@ -2483,22 +2556,21 @@ static irqreturn_t bcmgenet_isr1(int irq, void *dev_id) | |||
2483 | struct bcmgenet_priv *priv = dev_id; | 2556 | struct bcmgenet_priv *priv = dev_id; |
2484 | struct bcmgenet_rx_ring *rx_ring; | 2557 | struct bcmgenet_rx_ring *rx_ring; |
2485 | struct bcmgenet_tx_ring *tx_ring; | 2558 | struct bcmgenet_tx_ring *tx_ring; |
2486 | unsigned int index; | 2559 | unsigned int index, status; |
2487 | 2560 | ||
2488 | /* Save irq status for bottom-half processing. */ | 2561 | /* Read irq status */ |
2489 | priv->irq1_stat = | 2562 | status = bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_STAT) & |
2490 | bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_STAT) & | ||
2491 | ~bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_MASK_STATUS); | 2563 | ~bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_MASK_STATUS); |
2492 | 2564 | ||
2493 | /* clear interrupts */ | 2565 | /* clear interrupts */ |
2494 | bcmgenet_intrl2_1_writel(priv, priv->irq1_stat, INTRL2_CPU_CLEAR); | 2566 | bcmgenet_intrl2_1_writel(priv, status, INTRL2_CPU_CLEAR); |
2495 | 2567 | ||
2496 | netif_dbg(priv, intr, priv->dev, | 2568 | netif_dbg(priv, intr, priv->dev, |
2497 | "%s: IRQ=0x%x\n", __func__, priv->irq1_stat); | 2569 | "%s: IRQ=0x%x\n", __func__, status); |
2498 | 2570 | ||
2499 | /* Check Rx priority queue interrupts */ | 2571 | /* Check Rx priority queue interrupts */ |
2500 | for (index = 0; index < priv->hw_params->rx_queues; index++) { | 2572 | for (index = 0; index < priv->hw_params->rx_queues; index++) { |
2501 | if (!(priv->irq1_stat & BIT(UMAC_IRQ1_RX_INTR_SHIFT + index))) | 2573 | if (!(status & BIT(UMAC_IRQ1_RX_INTR_SHIFT + index))) |
2502 | continue; | 2574 | continue; |
2503 | 2575 | ||
2504 | rx_ring = &priv->rx_rings[index]; | 2576 | rx_ring = &priv->rx_rings[index]; |
@@ -2511,7 +2583,7 @@ static irqreturn_t bcmgenet_isr1(int irq, void *dev_id) | |||
2511 | 2583 | ||
2512 | /* Check Tx priority queue interrupts */ | 2584 | /* Check Tx priority queue interrupts */ |
2513 | for (index = 0; index < priv->hw_params->tx_queues; index++) { | 2585 | for (index = 0; index < priv->hw_params->tx_queues; index++) { |
2514 | if (!(priv->irq1_stat & BIT(index))) | 2586 | if (!(status & BIT(index))) |
2515 | continue; | 2587 | continue; |
2516 | 2588 | ||
2517 | tx_ring = &priv->tx_rings[index]; | 2589 | tx_ring = &priv->tx_rings[index]; |
@@ -2531,19 +2603,20 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id) | |||
2531 | struct bcmgenet_priv *priv = dev_id; | 2603 | struct bcmgenet_priv *priv = dev_id; |
2532 | struct bcmgenet_rx_ring *rx_ring; | 2604 | struct bcmgenet_rx_ring *rx_ring; |
2533 | struct bcmgenet_tx_ring *tx_ring; | 2605 | struct bcmgenet_tx_ring *tx_ring; |
2606 | unsigned int status; | ||
2607 | unsigned long flags; | ||
2534 | 2608 | ||
2535 | /* Save irq status for bottom-half processing. */ | 2609 | /* Read irq status */ |
2536 | priv->irq0_stat = | 2610 | status = bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_STAT) & |
2537 | bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_STAT) & | ||
2538 | ~bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_MASK_STATUS); | 2611 | ~bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_MASK_STATUS); |
2539 | 2612 | ||
2540 | /* clear interrupts */ | 2613 | /* clear interrupts */ |
2541 | bcmgenet_intrl2_0_writel(priv, priv->irq0_stat, INTRL2_CPU_CLEAR); | 2614 | bcmgenet_intrl2_0_writel(priv, status, INTRL2_CPU_CLEAR); |
2542 | 2615 | ||
2543 | netif_dbg(priv, intr, priv->dev, | 2616 | netif_dbg(priv, intr, priv->dev, |
2544 | "IRQ=0x%x\n", priv->irq0_stat); | 2617 | "IRQ=0x%x\n", status); |
2545 | 2618 | ||
2546 | if (priv->irq0_stat & UMAC_IRQ_RXDMA_DONE) { | 2619 | if (status & UMAC_IRQ_RXDMA_DONE) { |
2547 | rx_ring = &priv->rx_rings[DESC_INDEX]; | 2620 | rx_ring = &priv->rx_rings[DESC_INDEX]; |
2548 | 2621 | ||
2549 | if (likely(napi_schedule_prep(&rx_ring->napi))) { | 2622 | if (likely(napi_schedule_prep(&rx_ring->napi))) { |
@@ -2552,7 +2625,7 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id) | |||
2552 | } | 2625 | } |
2553 | } | 2626 | } |
2554 | 2627 | ||
2555 | if (priv->irq0_stat & UMAC_IRQ_TXDMA_DONE) { | 2628 | if (status & UMAC_IRQ_TXDMA_DONE) { |
2556 | tx_ring = &priv->tx_rings[DESC_INDEX]; | 2629 | tx_ring = &priv->tx_rings[DESC_INDEX]; |
2557 | 2630 | ||
2558 | if (likely(napi_schedule_prep(&tx_ring->napi))) { | 2631 | if (likely(napi_schedule_prep(&tx_ring->napi))) { |
@@ -2561,22 +2634,23 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id) | |||
2561 | } | 2634 | } |
2562 | } | 2635 | } |
2563 | 2636 | ||
2564 | if (priv->irq0_stat & (UMAC_IRQ_PHY_DET_R | | ||
2565 | UMAC_IRQ_PHY_DET_F | | ||
2566 | UMAC_IRQ_LINK_EVENT | | ||
2567 | UMAC_IRQ_HFB_SM | | ||
2568 | UMAC_IRQ_HFB_MM | | ||
2569 | UMAC_IRQ_MPD_R)) { | ||
2570 | /* all other interested interrupts handled in bottom half */ | ||
2571 | schedule_work(&priv->bcmgenet_irq_work); | ||
2572 | } | ||
2573 | |||
2574 | if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) && | 2637 | if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) && |
2575 | priv->irq0_stat & (UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR)) { | 2638 | status & (UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR)) { |
2576 | priv->irq0_stat &= ~(UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR); | ||
2577 | wake_up(&priv->wq); | 2639 | wake_up(&priv->wq); |
2578 | } | 2640 | } |
2579 | 2641 | ||
2642 | /* all other interested interrupts handled in bottom half */ | ||
2643 | status &= (UMAC_IRQ_LINK_EVENT | | ||
2644 | UMAC_IRQ_MPD_R); | ||
2645 | if (status) { | ||
2646 | /* Save irq status for bottom-half processing. */ | ||
2647 | spin_lock_irqsave(&priv->lock, flags); | ||
2648 | priv->irq0_stat |= status; | ||
2649 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2650 | |||
2651 | schedule_work(&priv->bcmgenet_irq_work); | ||
2652 | } | ||
2653 | |||
2580 | return IRQ_HANDLED; | 2654 | return IRQ_HANDLED; |
2581 | } | 2655 | } |
2582 | 2656 | ||
@@ -2801,6 +2875,8 @@ err_irq0: | |||
2801 | err_fini_dma: | 2875 | err_fini_dma: |
2802 | bcmgenet_fini_dma(priv); | 2876 | bcmgenet_fini_dma(priv); |
2803 | err_clk_disable: | 2877 | err_clk_disable: |
2878 | if (priv->internal_phy) | ||
2879 | bcmgenet_power_down(priv, GENET_POWER_PASSIVE); | ||
2804 | clk_disable_unprepare(priv->clk); | 2880 | clk_disable_unprepare(priv->clk); |
2805 | return ret; | 2881 | return ret; |
2806 | } | 2882 | } |
@@ -3177,6 +3253,12 @@ static void bcmgenet_set_hw_params(struct bcmgenet_priv *priv) | |||
3177 | */ | 3253 | */ |
3178 | gphy_rev = reg & 0xffff; | 3254 | gphy_rev = reg & 0xffff; |
3179 | 3255 | ||
3256 | /* This is reserved so should require special treatment */ | ||
3257 | if (gphy_rev == 0 || gphy_rev == 0x01ff) { | ||
3258 | pr_warn("Invalid GPHY revision detected: 0x%04x\n", gphy_rev); | ||
3259 | return; | ||
3260 | } | ||
3261 | |||
3180 | /* This is the good old scheme, just GPHY major, no minor nor patch */ | 3262 | /* This is the good old scheme, just GPHY major, no minor nor patch */ |
3181 | if ((gphy_rev & 0xf0) != 0) | 3263 | if ((gphy_rev & 0xf0) != 0) |
3182 | priv->gphy_rev = gphy_rev << 8; | 3264 | priv->gphy_rev = gphy_rev << 8; |
@@ -3185,12 +3267,6 @@ static void bcmgenet_set_hw_params(struct bcmgenet_priv *priv) | |||
3185 | else if ((gphy_rev & 0xff00) != 0) | 3267 | else if ((gphy_rev & 0xff00) != 0) |
3186 | priv->gphy_rev = gphy_rev; | 3268 | priv->gphy_rev = gphy_rev; |
3187 | 3269 | ||
3188 | /* This is reserved so should require special treatment */ | ||
3189 | else if (gphy_rev == 0 || gphy_rev == 0x01ff) { | ||
3190 | pr_warn("Invalid GPHY revision detected: 0x%04x\n", gphy_rev); | ||
3191 | return; | ||
3192 | } | ||
3193 | |||
3194 | #ifdef CONFIG_PHYS_ADDR_T_64BIT | 3270 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
3195 | if (!(params->flags & GENET_HAS_40BITS)) | 3271 | if (!(params->flags & GENET_HAS_40BITS)) |
3196 | pr_warn("GENET does not support 40-bits PA\n"); | 3272 | pr_warn("GENET does not support 40-bits PA\n"); |
@@ -3233,6 +3309,7 @@ static int bcmgenet_probe(struct platform_device *pdev) | |||
3233 | const void *macaddr; | 3309 | const void *macaddr; |
3234 | struct resource *r; | 3310 | struct resource *r; |
3235 | int err = -EIO; | 3311 | int err = -EIO; |
3312 | const char *phy_mode_str; | ||
3236 | 3313 | ||
3237 | /* Up to GENET_MAX_MQ_CNT + 1 TX queues and RX queues */ | 3314 | /* Up to GENET_MAX_MQ_CNT + 1 TX queues and RX queues */ |
3238 | dev = alloc_etherdev_mqs(sizeof(*priv), GENET_MAX_MQ_CNT + 1, | 3315 | dev = alloc_etherdev_mqs(sizeof(*priv), GENET_MAX_MQ_CNT + 1, |
@@ -3276,6 +3353,8 @@ static int bcmgenet_probe(struct platform_device *pdev) | |||
3276 | goto err; | 3353 | goto err; |
3277 | } | 3354 | } |
3278 | 3355 | ||
3356 | spin_lock_init(&priv->lock); | ||
3357 | |||
3279 | SET_NETDEV_DEV(dev, &pdev->dev); | 3358 | SET_NETDEV_DEV(dev, &pdev->dev); |
3280 | dev_set_drvdata(&pdev->dev, dev); | 3359 | dev_set_drvdata(&pdev->dev, dev); |
3281 | ether_addr_copy(dev->dev_addr, macaddr); | 3360 | ether_addr_copy(dev->dev_addr, macaddr); |
@@ -3338,6 +3417,13 @@ static int bcmgenet_probe(struct platform_device *pdev) | |||
3338 | priv->clk_eee = NULL; | 3417 | priv->clk_eee = NULL; |
3339 | } | 3418 | } |
3340 | 3419 | ||
3420 | /* If this is an internal GPHY, power it on now, before UniMAC is | ||
3421 | * brought out of reset as absolutely no UniMAC activity is allowed | ||
3422 | */ | ||
3423 | if (dn && !of_property_read_string(dn, "phy-mode", &phy_mode_str) && | ||
3424 | !strcasecmp(phy_mode_str, "internal")) | ||
3425 | bcmgenet_power_up(priv, GENET_POWER_PASSIVE); | ||
3426 | |||
3341 | err = reset_umac(priv); | 3427 | err = reset_umac(priv); |
3342 | if (err) | 3428 | if (err) |
3343 | goto err_clk_disable; | 3429 | goto err_clk_disable; |
@@ -3502,6 +3588,8 @@ static int bcmgenet_resume(struct device *d) | |||
3502 | return 0; | 3588 | return 0; |
3503 | 3589 | ||
3504 | out_clk_disable: | 3590 | out_clk_disable: |
3591 | if (priv->internal_phy) | ||
3592 | bcmgenet_power_down(priv, GENET_POWER_PASSIVE); | ||
3505 | clk_disable_unprepare(priv->clk); | 3593 | clk_disable_unprepare(priv->clk); |
3506 | return ret; | 3594 | return ret; |
3507 | } | 3595 | } |
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 1e2dc34d331a..db7f289d65ae 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2014 Broadcom Corporation | 2 | * Copyright (c) 2014-2017 Broadcom |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License version 2 as | 5 | * it under the terms of the GNU General Public License version 2 as |
@@ -214,7 +214,9 @@ struct bcmgenet_mib_counters { | |||
214 | #define MDIO_REG_SHIFT 16 | 214 | #define MDIO_REG_SHIFT 16 |
215 | #define MDIO_REG_MASK 0x1F | 215 | #define MDIO_REG_MASK 0x1F |
216 | 216 | ||
217 | #define UMAC_RBUF_OVFL_CNT 0x61C | 217 | #define UMAC_RBUF_OVFL_CNT_V1 0x61C |
218 | #define RBUF_OVFL_CNT_V2 0x80 | ||
219 | #define RBUF_OVFL_CNT_V3PLUS 0x94 | ||
218 | 220 | ||
219 | #define UMAC_MPD_CTRL 0x620 | 221 | #define UMAC_MPD_CTRL 0x620 |
220 | #define MPD_EN (1 << 0) | 222 | #define MPD_EN (1 << 0) |
@@ -224,7 +226,9 @@ struct bcmgenet_mib_counters { | |||
224 | 226 | ||
225 | #define UMAC_MPD_PW_MS 0x624 | 227 | #define UMAC_MPD_PW_MS 0x624 |
226 | #define UMAC_MPD_PW_LS 0x628 | 228 | #define UMAC_MPD_PW_LS 0x628 |
227 | #define UMAC_RBUF_ERR_CNT 0x634 | 229 | #define UMAC_RBUF_ERR_CNT_V1 0x634 |
230 | #define RBUF_ERR_CNT_V2 0x84 | ||
231 | #define RBUF_ERR_CNT_V3PLUS 0x98 | ||
228 | #define UMAC_MDF_ERR_CNT 0x638 | 232 | #define UMAC_MDF_ERR_CNT 0x638 |
229 | #define UMAC_MDF_CTRL 0x650 | 233 | #define UMAC_MDF_CTRL 0x650 |
230 | #define UMAC_MDF_ADDR 0x654 | 234 | #define UMAC_MDF_ADDR 0x654 |
@@ -619,11 +623,13 @@ struct bcmgenet_priv { | |||
619 | struct work_struct bcmgenet_irq_work; | 623 | struct work_struct bcmgenet_irq_work; |
620 | int irq0; | 624 | int irq0; |
621 | int irq1; | 625 | int irq1; |
622 | unsigned int irq0_stat; | ||
623 | unsigned int irq1_stat; | ||
624 | int wol_irq; | 626 | int wol_irq; |
625 | bool wol_irq_disabled; | 627 | bool wol_irq_disabled; |
626 | 628 | ||
629 | /* shared status */ | ||
630 | spinlock_t lock; | ||
631 | unsigned int irq0_stat; | ||
632 | |||
627 | /* HW descriptors/checksum variables */ | 633 | /* HW descriptors/checksum variables */ |
628 | bool desc_64b_en; | 634 | bool desc_64b_en; |
629 | bool desc_rxchk_en; | 635 | bool desc_rxchk_en; |
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c index be9c0e3f5ade..92f46b1375c3 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c | |||
@@ -152,7 +152,7 @@ struct octnic_gather { | |||
152 | */ | 152 | */ |
153 | struct octeon_sg_entry *sg; | 153 | struct octeon_sg_entry *sg; |
154 | 154 | ||
155 | u64 sg_dma_ptr; | 155 | dma_addr_t sg_dma_ptr; |
156 | }; | 156 | }; |
157 | 157 | ||
158 | struct handshake { | 158 | struct handshake { |
@@ -734,6 +734,9 @@ static void delete_glists(struct lio *lio) | |||
734 | struct octnic_gather *g; | 734 | struct octnic_gather *g; |
735 | int i; | 735 | int i; |
736 | 736 | ||
737 | kfree(lio->glist_lock); | ||
738 | lio->glist_lock = NULL; | ||
739 | |||
737 | if (!lio->glist) | 740 | if (!lio->glist) |
738 | return; | 741 | return; |
739 | 742 | ||
@@ -741,23 +744,26 @@ static void delete_glists(struct lio *lio) | |||
741 | do { | 744 | do { |
742 | g = (struct octnic_gather *) | 745 | g = (struct octnic_gather *) |
743 | list_delete_head(&lio->glist[i]); | 746 | list_delete_head(&lio->glist[i]); |
744 | if (g) { | 747 | if (g) |
745 | if (g->sg) { | ||
746 | dma_unmap_single(&lio->oct_dev-> | ||
747 | pci_dev->dev, | ||
748 | g->sg_dma_ptr, | ||
749 | g->sg_size, | ||
750 | DMA_TO_DEVICE); | ||
751 | kfree((void *)((unsigned long)g->sg - | ||
752 | g->adjust)); | ||
753 | } | ||
754 | kfree(g); | 748 | kfree(g); |
755 | } | ||
756 | } while (g); | 749 | } while (g); |
750 | |||
751 | if (lio->glists_virt_base && lio->glists_virt_base[i]) { | ||
752 | lio_dma_free(lio->oct_dev, | ||
753 | lio->glist_entry_size * lio->tx_qsize, | ||
754 | lio->glists_virt_base[i], | ||
755 | lio->glists_dma_base[i]); | ||
756 | } | ||
757 | } | 757 | } |
758 | 758 | ||
759 | kfree((void *)lio->glist); | 759 | kfree(lio->glists_virt_base); |
760 | kfree((void *)lio->glist_lock); | 760 | lio->glists_virt_base = NULL; |
761 | |||
762 | kfree(lio->glists_dma_base); | ||
763 | lio->glists_dma_base = NULL; | ||
764 | |||
765 | kfree(lio->glist); | ||
766 | lio->glist = NULL; | ||
761 | } | 767 | } |
762 | 768 | ||
763 | /** | 769 | /** |
@@ -772,13 +778,30 @@ static int setup_glists(struct octeon_device *oct, struct lio *lio, int num_iqs) | |||
772 | lio->glist_lock = kcalloc(num_iqs, sizeof(*lio->glist_lock), | 778 | lio->glist_lock = kcalloc(num_iqs, sizeof(*lio->glist_lock), |
773 | GFP_KERNEL); | 779 | GFP_KERNEL); |
774 | if (!lio->glist_lock) | 780 | if (!lio->glist_lock) |
775 | return 1; | 781 | return -ENOMEM; |
776 | 782 | ||
777 | lio->glist = kcalloc(num_iqs, sizeof(*lio->glist), | 783 | lio->glist = kcalloc(num_iqs, sizeof(*lio->glist), |
778 | GFP_KERNEL); | 784 | GFP_KERNEL); |
779 | if (!lio->glist) { | 785 | if (!lio->glist) { |
780 | kfree((void *)lio->glist_lock); | 786 | kfree(lio->glist_lock); |
781 | return 1; | 787 | lio->glist_lock = NULL; |
788 | return -ENOMEM; | ||
789 | } | ||
790 | |||
791 | lio->glist_entry_size = | ||
792 | ROUNDUP8((ROUNDUP4(OCTNIC_MAX_SG) >> 2) * OCT_SG_ENTRY_SIZE); | ||
793 | |||
794 | /* allocate memory to store virtual and dma base address of | ||
795 | * per glist consistent memory | ||
796 | */ | ||
797 | lio->glists_virt_base = kcalloc(num_iqs, sizeof(*lio->glists_virt_base), | ||
798 | GFP_KERNEL); | ||
799 | lio->glists_dma_base = kcalloc(num_iqs, sizeof(*lio->glists_dma_base), | ||
800 | GFP_KERNEL); | ||
801 | |||
802 | if (!lio->glists_virt_base || !lio->glists_dma_base) { | ||
803 | delete_glists(lio); | ||
804 | return -ENOMEM; | ||
782 | } | 805 | } |
783 | 806 | ||
784 | for (i = 0; i < num_iqs; i++) { | 807 | for (i = 0; i < num_iqs; i++) { |
@@ -788,6 +811,16 @@ static int setup_glists(struct octeon_device *oct, struct lio *lio, int num_iqs) | |||
788 | 811 | ||
789 | INIT_LIST_HEAD(&lio->glist[i]); | 812 | INIT_LIST_HEAD(&lio->glist[i]); |
790 | 813 | ||
814 | lio->glists_virt_base[i] = | ||
815 | lio_dma_alloc(oct, | ||
816 | lio->glist_entry_size * lio->tx_qsize, | ||
817 | &lio->glists_dma_base[i]); | ||
818 | |||
819 | if (!lio->glists_virt_base[i]) { | ||
820 | delete_glists(lio); | ||
821 | return -ENOMEM; | ||
822 | } | ||
823 | |||
791 | for (j = 0; j < lio->tx_qsize; j++) { | 824 | for (j = 0; j < lio->tx_qsize; j++) { |
792 | g = kzalloc_node(sizeof(*g), GFP_KERNEL, | 825 | g = kzalloc_node(sizeof(*g), GFP_KERNEL, |
793 | numa_node); | 826 | numa_node); |
@@ -796,43 +829,18 @@ static int setup_glists(struct octeon_device *oct, struct lio *lio, int num_iqs) | |||
796 | if (!g) | 829 | if (!g) |
797 | break; | 830 | break; |
798 | 831 | ||
799 | g->sg_size = ((ROUNDUP4(OCTNIC_MAX_SG) >> 2) * | 832 | g->sg = lio->glists_virt_base[i] + |
800 | OCT_SG_ENTRY_SIZE); | 833 | (j * lio->glist_entry_size); |
801 | 834 | ||
802 | g->sg = kmalloc_node(g->sg_size + 8, | 835 | g->sg_dma_ptr = lio->glists_dma_base[i] + |
803 | GFP_KERNEL, numa_node); | 836 | (j * lio->glist_entry_size); |
804 | if (!g->sg) | ||
805 | g->sg = kmalloc(g->sg_size + 8, GFP_KERNEL); | ||
806 | if (!g->sg) { | ||
807 | kfree(g); | ||
808 | break; | ||
809 | } | ||
810 | |||
811 | /* The gather component should be aligned on 64-bit | ||
812 | * boundary | ||
813 | */ | ||
814 | if (((unsigned long)g->sg) & 7) { | ||
815 | g->adjust = 8 - (((unsigned long)g->sg) & 7); | ||
816 | g->sg = (struct octeon_sg_entry *) | ||
817 | ((unsigned long)g->sg + g->adjust); | ||
818 | } | ||
819 | g->sg_dma_ptr = dma_map_single(&oct->pci_dev->dev, | ||
820 | g->sg, g->sg_size, | ||
821 | DMA_TO_DEVICE); | ||
822 | if (dma_mapping_error(&oct->pci_dev->dev, | ||
823 | g->sg_dma_ptr)) { | ||
824 | kfree((void *)((unsigned long)g->sg - | ||
825 | g->adjust)); | ||
826 | kfree(g); | ||
827 | break; | ||
828 | } | ||
829 | 837 | ||
830 | list_add_tail(&g->list, &lio->glist[i]); | 838 | list_add_tail(&g->list, &lio->glist[i]); |
831 | } | 839 | } |
832 | 840 | ||
833 | if (j != lio->tx_qsize) { | 841 | if (j != lio->tx_qsize) { |
834 | delete_glists(lio); | 842 | delete_glists(lio); |
835 | return 1; | 843 | return -ENOMEM; |
836 | } | 844 | } |
837 | } | 845 | } |
838 | 846 | ||
@@ -1885,9 +1893,6 @@ static void free_netsgbuf(void *buf) | |||
1885 | i++; | 1893 | i++; |
1886 | } | 1894 | } |
1887 | 1895 | ||
1888 | dma_sync_single_for_cpu(&lio->oct_dev->pci_dev->dev, | ||
1889 | g->sg_dma_ptr, g->sg_size, DMA_TO_DEVICE); | ||
1890 | |||
1891 | iq = skb_iq(lio, skb); | 1896 | iq = skb_iq(lio, skb); |
1892 | spin_lock(&lio->glist_lock[iq]); | 1897 | spin_lock(&lio->glist_lock[iq]); |
1893 | list_add_tail(&g->list, &lio->glist[iq]); | 1898 | list_add_tail(&g->list, &lio->glist[iq]); |
@@ -1933,9 +1938,6 @@ static void free_netsgbuf_with_resp(void *buf) | |||
1933 | i++; | 1938 | i++; |
1934 | } | 1939 | } |
1935 | 1940 | ||
1936 | dma_sync_single_for_cpu(&lio->oct_dev->pci_dev->dev, | ||
1937 | g->sg_dma_ptr, g->sg_size, DMA_TO_DEVICE); | ||
1938 | |||
1939 | iq = skb_iq(lio, skb); | 1941 | iq = skb_iq(lio, skb); |
1940 | 1942 | ||
1941 | spin_lock(&lio->glist_lock[iq]); | 1943 | spin_lock(&lio->glist_lock[iq]); |
@@ -3273,8 +3275,6 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
3273 | i++; | 3275 | i++; |
3274 | } | 3276 | } |
3275 | 3277 | ||
3276 | dma_sync_single_for_device(&oct->pci_dev->dev, g->sg_dma_ptr, | ||
3277 | g->sg_size, DMA_TO_DEVICE); | ||
3278 | dptr = g->sg_dma_ptr; | 3278 | dptr = g->sg_dma_ptr; |
3279 | 3279 | ||
3280 | if (OCTEON_CN23XX_PF(oct)) | 3280 | if (OCTEON_CN23XX_PF(oct)) |
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c index 9d5e03502c76..7b83be4ce1fe 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c | |||
@@ -108,6 +108,8 @@ struct octnic_gather { | |||
108 | * received from the IP layer. | 108 | * received from the IP layer. |
109 | */ | 109 | */ |
110 | struct octeon_sg_entry *sg; | 110 | struct octeon_sg_entry *sg; |
111 | |||
112 | dma_addr_t sg_dma_ptr; | ||
111 | }; | 113 | }; |
112 | 114 | ||
113 | struct octeon_device_priv { | 115 | struct octeon_device_priv { |
@@ -490,6 +492,9 @@ static void delete_glists(struct lio *lio) | |||
490 | struct octnic_gather *g; | 492 | struct octnic_gather *g; |
491 | int i; | 493 | int i; |
492 | 494 | ||
495 | kfree(lio->glist_lock); | ||
496 | lio->glist_lock = NULL; | ||
497 | |||
493 | if (!lio->glist) | 498 | if (!lio->glist) |
494 | return; | 499 | return; |
495 | 500 | ||
@@ -497,17 +502,26 @@ static void delete_glists(struct lio *lio) | |||
497 | do { | 502 | do { |
498 | g = (struct octnic_gather *) | 503 | g = (struct octnic_gather *) |
499 | list_delete_head(&lio->glist[i]); | 504 | list_delete_head(&lio->glist[i]); |
500 | if (g) { | 505 | if (g) |
501 | if (g->sg) | ||
502 | kfree((void *)((unsigned long)g->sg - | ||
503 | g->adjust)); | ||
504 | kfree(g); | 506 | kfree(g); |
505 | } | ||
506 | } while (g); | 507 | } while (g); |
508 | |||
509 | if (lio->glists_virt_base && lio->glists_virt_base[i]) { | ||
510 | lio_dma_free(lio->oct_dev, | ||
511 | lio->glist_entry_size * lio->tx_qsize, | ||
512 | lio->glists_virt_base[i], | ||
513 | lio->glists_dma_base[i]); | ||
514 | } | ||
507 | } | 515 | } |
508 | 516 | ||
517 | kfree(lio->glists_virt_base); | ||
518 | lio->glists_virt_base = NULL; | ||
519 | |||
520 | kfree(lio->glists_dma_base); | ||
521 | lio->glists_dma_base = NULL; | ||
522 | |||
509 | kfree(lio->glist); | 523 | kfree(lio->glist); |
510 | kfree(lio->glist_lock); | 524 | lio->glist = NULL; |
511 | } | 525 | } |
512 | 526 | ||
513 | /** | 527 | /** |
@@ -522,13 +536,30 @@ static int setup_glists(struct lio *lio, int num_iqs) | |||
522 | lio->glist_lock = | 536 | lio->glist_lock = |
523 | kzalloc(sizeof(*lio->glist_lock) * num_iqs, GFP_KERNEL); | 537 | kzalloc(sizeof(*lio->glist_lock) * num_iqs, GFP_KERNEL); |
524 | if (!lio->glist_lock) | 538 | if (!lio->glist_lock) |
525 | return 1; | 539 | return -ENOMEM; |
526 | 540 | ||
527 | lio->glist = | 541 | lio->glist = |
528 | kzalloc(sizeof(*lio->glist) * num_iqs, GFP_KERNEL); | 542 | kzalloc(sizeof(*lio->glist) * num_iqs, GFP_KERNEL); |
529 | if (!lio->glist) { | 543 | if (!lio->glist) { |
530 | kfree(lio->glist_lock); | 544 | kfree(lio->glist_lock); |
531 | return 1; | 545 | lio->glist_lock = NULL; |
546 | return -ENOMEM; | ||
547 | } | ||
548 | |||
549 | lio->glist_entry_size = | ||
550 | ROUNDUP8((ROUNDUP4(OCTNIC_MAX_SG) >> 2) * OCT_SG_ENTRY_SIZE); | ||
551 | |||
552 | /* allocate memory to store virtual and dma base address of | ||
553 | * per glist consistent memory | ||
554 | */ | ||
555 | lio->glists_virt_base = kcalloc(num_iqs, sizeof(*lio->glists_virt_base), | ||
556 | GFP_KERNEL); | ||
557 | lio->glists_dma_base = kcalloc(num_iqs, sizeof(*lio->glists_dma_base), | ||
558 | GFP_KERNEL); | ||
559 | |||
560 | if (!lio->glists_virt_base || !lio->glists_dma_base) { | ||
561 | delete_glists(lio); | ||
562 | return -ENOMEM; | ||
532 | } | 563 | } |
533 | 564 | ||
534 | for (i = 0; i < num_iqs; i++) { | 565 | for (i = 0; i < num_iqs; i++) { |
@@ -536,34 +567,33 @@ static int setup_glists(struct lio *lio, int num_iqs) | |||
536 | 567 | ||
537 | INIT_LIST_HEAD(&lio->glist[i]); | 568 | INIT_LIST_HEAD(&lio->glist[i]); |
538 | 569 | ||
570 | lio->glists_virt_base[i] = | ||
571 | lio_dma_alloc(lio->oct_dev, | ||
572 | lio->glist_entry_size * lio->tx_qsize, | ||
573 | &lio->glists_dma_base[i]); | ||
574 | |||
575 | if (!lio->glists_virt_base[i]) { | ||
576 | delete_glists(lio); | ||
577 | return -ENOMEM; | ||
578 | } | ||
579 | |||
539 | for (j = 0; j < lio->tx_qsize; j++) { | 580 | for (j = 0; j < lio->tx_qsize; j++) { |
540 | g = kzalloc(sizeof(*g), GFP_KERNEL); | 581 | g = kzalloc(sizeof(*g), GFP_KERNEL); |
541 | if (!g) | 582 | if (!g) |
542 | break; | 583 | break; |
543 | 584 | ||
544 | g->sg_size = ((ROUNDUP4(OCTNIC_MAX_SG) >> 2) * | 585 | g->sg = lio->glists_virt_base[i] + |
545 | OCT_SG_ENTRY_SIZE); | 586 | (j * lio->glist_entry_size); |
546 | 587 | ||
547 | g->sg = kmalloc(g->sg_size + 8, GFP_KERNEL); | 588 | g->sg_dma_ptr = lio->glists_dma_base[i] + |
548 | if (!g->sg) { | 589 | (j * lio->glist_entry_size); |
549 | kfree(g); | ||
550 | break; | ||
551 | } | ||
552 | 590 | ||
553 | /* The gather component should be aligned on 64-bit | ||
554 | * boundary | ||
555 | */ | ||
556 | if (((unsigned long)g->sg) & 7) { | ||
557 | g->adjust = 8 - (((unsigned long)g->sg) & 7); | ||
558 | g->sg = (struct octeon_sg_entry *) | ||
559 | ((unsigned long)g->sg + g->adjust); | ||
560 | } | ||
561 | list_add_tail(&g->list, &lio->glist[i]); | 591 | list_add_tail(&g->list, &lio->glist[i]); |
562 | } | 592 | } |
563 | 593 | ||
564 | if (j != lio->tx_qsize) { | 594 | if (j != lio->tx_qsize) { |
565 | delete_glists(lio); | 595 | delete_glists(lio); |
566 | return 1; | 596 | return -ENOMEM; |
567 | } | 597 | } |
568 | } | 598 | } |
569 | 599 | ||
@@ -1324,10 +1354,6 @@ static void free_netsgbuf(void *buf) | |||
1324 | i++; | 1354 | i++; |
1325 | } | 1355 | } |
1326 | 1356 | ||
1327 | dma_unmap_single(&lio->oct_dev->pci_dev->dev, | ||
1328 | finfo->dptr, g->sg_size, | ||
1329 | DMA_TO_DEVICE); | ||
1330 | |||
1331 | iq = skb_iq(lio, skb); | 1357 | iq = skb_iq(lio, skb); |
1332 | 1358 | ||
1333 | spin_lock(&lio->glist_lock[iq]); | 1359 | spin_lock(&lio->glist_lock[iq]); |
@@ -1374,10 +1400,6 @@ static void free_netsgbuf_with_resp(void *buf) | |||
1374 | i++; | 1400 | i++; |
1375 | } | 1401 | } |
1376 | 1402 | ||
1377 | dma_unmap_single(&lio->oct_dev->pci_dev->dev, | ||
1378 | finfo->dptr, g->sg_size, | ||
1379 | DMA_TO_DEVICE); | ||
1380 | |||
1381 | iq = skb_iq(lio, skb); | 1403 | iq = skb_iq(lio, skb); |
1382 | 1404 | ||
1383 | spin_lock(&lio->glist_lock[iq]); | 1405 | spin_lock(&lio->glist_lock[iq]); |
@@ -2382,23 +2404,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
2382 | i++; | 2404 | i++; |
2383 | } | 2405 | } |
2384 | 2406 | ||
2385 | dptr = dma_map_single(&oct->pci_dev->dev, | 2407 | dptr = g->sg_dma_ptr; |
2386 | g->sg, g->sg_size, | ||
2387 | DMA_TO_DEVICE); | ||
2388 | if (dma_mapping_error(&oct->pci_dev->dev, dptr)) { | ||
2389 | dev_err(&oct->pci_dev->dev, "%s DMA mapping error 4\n", | ||
2390 | __func__); | ||
2391 | dma_unmap_single(&oct->pci_dev->dev, g->sg[0].ptr[0], | ||
2392 | skb->len - skb->data_len, | ||
2393 | DMA_TO_DEVICE); | ||
2394 | for (j = 1; j <= frags; j++) { | ||
2395 | frag = &skb_shinfo(skb)->frags[j - 1]; | ||
2396 | dma_unmap_page(&oct->pci_dev->dev, | ||
2397 | g->sg[j >> 2].ptr[j & 3], | ||
2398 | frag->size, DMA_TO_DEVICE); | ||
2399 | } | ||
2400 | return NETDEV_TX_BUSY; | ||
2401 | } | ||
2402 | 2408 | ||
2403 | ndata.cmd.cmd3.dptr = dptr; | 2409 | ndata.cmd.cmd3.dptr = dptr; |
2404 | finfo->dptr = dptr; | 2410 | finfo->dptr = dptr; |
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_config.h b/drivers/net/ethernet/cavium/liquidio/octeon_config.h index b3dc2e9651a8..d29ebc531151 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_config.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_config.h | |||
@@ -71,17 +71,17 @@ | |||
71 | #define CN23XX_MAX_RINGS_PER_VF 8 | 71 | #define CN23XX_MAX_RINGS_PER_VF 8 |
72 | 72 | ||
73 | #define CN23XX_MAX_INPUT_QUEUES CN23XX_MAX_RINGS_PER_PF | 73 | #define CN23XX_MAX_INPUT_QUEUES CN23XX_MAX_RINGS_PER_PF |
74 | #define CN23XX_MAX_IQ_DESCRIPTORS 2048 | 74 | #define CN23XX_MAX_IQ_DESCRIPTORS 512 |
75 | #define CN23XX_DB_MIN 1 | 75 | #define CN23XX_DB_MIN 1 |
76 | #define CN23XX_DB_MAX 8 | 76 | #define CN23XX_DB_MAX 8 |
77 | #define CN23XX_DB_TIMEOUT 1 | 77 | #define CN23XX_DB_TIMEOUT 1 |
78 | 78 | ||
79 | #define CN23XX_MAX_OUTPUT_QUEUES CN23XX_MAX_RINGS_PER_PF | 79 | #define CN23XX_MAX_OUTPUT_QUEUES CN23XX_MAX_RINGS_PER_PF |
80 | #define CN23XX_MAX_OQ_DESCRIPTORS 2048 | 80 | #define CN23XX_MAX_OQ_DESCRIPTORS 512 |
81 | #define CN23XX_OQ_BUF_SIZE 1536 | 81 | #define CN23XX_OQ_BUF_SIZE 1536 |
82 | #define CN23XX_OQ_PKTSPER_INTR 128 | 82 | #define CN23XX_OQ_PKTSPER_INTR 128 |
83 | /*#define CAVIUM_ONLY_CN23XX_RX_PERF*/ | 83 | /*#define CAVIUM_ONLY_CN23XX_RX_PERF*/ |
84 | #define CN23XX_OQ_REFIL_THRESHOLD 128 | 84 | #define CN23XX_OQ_REFIL_THRESHOLD 16 |
85 | 85 | ||
86 | #define CN23XX_OQ_INTR_PKT 64 | 86 | #define CN23XX_OQ_INTR_PKT 64 |
87 | #define CN23XX_OQ_INTR_TIME 100 | 87 | #define CN23XX_OQ_INTR_TIME 100 |
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_droq.c b/drivers/net/ethernet/cavium/liquidio/octeon_droq.c index 0be87d119a97..79f809479af6 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_droq.c +++ b/drivers/net/ethernet/cavium/liquidio/octeon_droq.c | |||
@@ -155,11 +155,6 @@ octeon_droq_destroy_ring_buffers(struct octeon_device *oct, | |||
155 | recv_buffer_destroy(droq->recv_buf_list[i].buffer, | 155 | recv_buffer_destroy(droq->recv_buf_list[i].buffer, |
156 | pg_info); | 156 | pg_info); |
157 | 157 | ||
158 | if (droq->desc_ring && droq->desc_ring[i].info_ptr) | ||
159 | lio_unmap_ring_info(oct->pci_dev, | ||
160 | (u64)droq-> | ||
161 | desc_ring[i].info_ptr, | ||
162 | OCT_DROQ_INFO_SIZE); | ||
163 | droq->recv_buf_list[i].buffer = NULL; | 158 | droq->recv_buf_list[i].buffer = NULL; |
164 | } | 159 | } |
165 | 160 | ||
@@ -211,10 +206,7 @@ int octeon_delete_droq(struct octeon_device *oct, u32 q_no) | |||
211 | vfree(droq->recv_buf_list); | 206 | vfree(droq->recv_buf_list); |
212 | 207 | ||
213 | if (droq->info_base_addr) | 208 | if (droq->info_base_addr) |
214 | cnnic_free_aligned_dma(oct->pci_dev, droq->info_list, | 209 | lio_free_info_buffer(oct, droq); |
215 | droq->info_alloc_size, | ||
216 | droq->info_base_addr, | ||
217 | droq->info_list_dma); | ||
218 | 210 | ||
219 | if (droq->desc_ring) | 211 | if (droq->desc_ring) |
220 | lio_dma_free(oct, (droq->max_count * OCT_DROQ_DESC_SIZE), | 212 | lio_dma_free(oct, (droq->max_count * OCT_DROQ_DESC_SIZE), |
@@ -294,12 +286,7 @@ int octeon_init_droq(struct octeon_device *oct, | |||
294 | dev_dbg(&oct->pci_dev->dev, "droq[%d]: num_desc: %d\n", q_no, | 286 | dev_dbg(&oct->pci_dev->dev, "droq[%d]: num_desc: %d\n", q_no, |
295 | droq->max_count); | 287 | droq->max_count); |
296 | 288 | ||
297 | droq->info_list = | 289 | droq->info_list = lio_alloc_info_buffer(oct, droq); |
298 | cnnic_numa_alloc_aligned_dma((droq->max_count * | ||
299 | OCT_DROQ_INFO_SIZE), | ||
300 | &droq->info_alloc_size, | ||
301 | &droq->info_base_addr, | ||
302 | numa_node); | ||
303 | if (!droq->info_list) { | 290 | if (!droq->info_list) { |
304 | dev_err(&oct->pci_dev->dev, "Cannot allocate memory for info list.\n"); | 291 | dev_err(&oct->pci_dev->dev, "Cannot allocate memory for info list.\n"); |
305 | lio_dma_free(oct, (droq->max_count * OCT_DROQ_DESC_SIZE), | 292 | lio_dma_free(oct, (droq->max_count * OCT_DROQ_DESC_SIZE), |
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_droq.h b/drivers/net/ethernet/cavium/liquidio/octeon_droq.h index e62074090681..6982c0af5ecc 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_droq.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_droq.h | |||
@@ -325,10 +325,10 @@ struct octeon_droq { | |||
325 | size_t desc_ring_dma; | 325 | size_t desc_ring_dma; |
326 | 326 | ||
327 | /** Info ptr list are allocated at this virtual address. */ | 327 | /** Info ptr list are allocated at this virtual address. */ |
328 | size_t info_base_addr; | 328 | void *info_base_addr; |
329 | 329 | ||
330 | /** DMA mapped address of the info list */ | 330 | /** DMA mapped address of the info list */ |
331 | size_t info_list_dma; | 331 | dma_addr_t info_list_dma; |
332 | 332 | ||
333 | /** Allocated size of info list. */ | 333 | /** Allocated size of info list. */ |
334 | u32 info_alloc_size; | 334 | u32 info_alloc_size; |
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_main.h b/drivers/net/ethernet/cavium/liquidio/octeon_main.h index aa36e9ae7676..bed9ef17bc26 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_main.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_main.h | |||
@@ -140,48 +140,6 @@ err_release_region: | |||
140 | return 1; | 140 | return 1; |
141 | } | 141 | } |
142 | 142 | ||
143 | static inline void * | ||
144 | cnnic_numa_alloc_aligned_dma(u32 size, | ||
145 | u32 *alloc_size, | ||
146 | size_t *orig_ptr, | ||
147 | int numa_node) | ||
148 | { | ||
149 | int retries = 0; | ||
150 | void *ptr = NULL; | ||
151 | |||
152 | #define OCTEON_MAX_ALLOC_RETRIES 1 | ||
153 | do { | ||
154 | struct page *page = NULL; | ||
155 | |||
156 | page = alloc_pages_node(numa_node, | ||
157 | GFP_KERNEL, | ||
158 | get_order(size)); | ||
159 | if (!page) | ||
160 | page = alloc_pages(GFP_KERNEL, | ||
161 | get_order(size)); | ||
162 | ptr = (void *)page_address(page); | ||
163 | if ((unsigned long)ptr & 0x07) { | ||
164 | __free_pages(page, get_order(size)); | ||
165 | ptr = NULL; | ||
166 | /* Increment the size required if the first | ||
167 | * attempt failed. | ||
168 | */ | ||
169 | if (!retries) | ||
170 | size += 7; | ||
171 | } | ||
172 | retries++; | ||
173 | } while ((retries <= OCTEON_MAX_ALLOC_RETRIES) && !ptr); | ||
174 | |||
175 | *alloc_size = size; | ||
176 | *orig_ptr = (unsigned long)ptr; | ||
177 | if ((unsigned long)ptr & 0x07) | ||
178 | ptr = (void *)(((unsigned long)ptr + 7) & ~(7UL)); | ||
179 | return ptr; | ||
180 | } | ||
181 | |||
182 | #define cnnic_free_aligned_dma(pci_dev, ptr, size, orig_ptr, dma_addr) \ | ||
183 | free_pages(orig_ptr, get_order(size)) | ||
184 | |||
185 | static inline int | 143 | static inline int |
186 | sleep_cond(wait_queue_head_t *wait_queue, int *condition) | 144 | sleep_cond(wait_queue_head_t *wait_queue, int *condition) |
187 | { | 145 | { |
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_network.h b/drivers/net/ethernet/cavium/liquidio/octeon_network.h index 6bb89419006e..eef2a1e8a7e3 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_network.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_network.h | |||
@@ -62,6 +62,9 @@ struct lio { | |||
62 | 62 | ||
63 | /** Array of gather component linked lists */ | 63 | /** Array of gather component linked lists */ |
64 | struct list_head *glist; | 64 | struct list_head *glist; |
65 | void **glists_virt_base; | ||
66 | dma_addr_t *glists_dma_base; | ||
67 | u32 glist_entry_size; | ||
65 | 68 | ||
66 | /** Pointer to the NIC properties for the Octeon device this network | 69 | /** Pointer to the NIC properties for the Octeon device this network |
67 | * interface is associated with. | 70 | * interface is associated with. |
@@ -344,6 +347,29 @@ static inline void tx_buffer_free(void *buffer) | |||
344 | #define lio_dma_free(oct, size, virt_addr, dma_addr) \ | 347 | #define lio_dma_free(oct, size, virt_addr, dma_addr) \ |
345 | dma_free_coherent(&(oct)->pci_dev->dev, size, virt_addr, dma_addr) | 348 | dma_free_coherent(&(oct)->pci_dev->dev, size, virt_addr, dma_addr) |
346 | 349 | ||
350 | static inline void * | ||
351 | lio_alloc_info_buffer(struct octeon_device *oct, | ||
352 | struct octeon_droq *droq) | ||
353 | { | ||
354 | void *virt_ptr; | ||
355 | |||
356 | virt_ptr = lio_dma_alloc(oct, (droq->max_count * OCT_DROQ_INFO_SIZE), | ||
357 | &droq->info_list_dma); | ||
358 | if (virt_ptr) { | ||
359 | droq->info_alloc_size = droq->max_count * OCT_DROQ_INFO_SIZE; | ||
360 | droq->info_base_addr = virt_ptr; | ||
361 | } | ||
362 | |||
363 | return virt_ptr; | ||
364 | } | ||
365 | |||
366 | static inline void lio_free_info_buffer(struct octeon_device *oct, | ||
367 | struct octeon_droq *droq) | ||
368 | { | ||
369 | lio_dma_free(oct, droq->info_alloc_size, droq->info_base_addr, | ||
370 | droq->info_list_dma); | ||
371 | } | ||
372 | |||
347 | static inline | 373 | static inline |
348 | void *get_rbd(struct sk_buff *skb) | 374 | void *get_rbd(struct sk_buff *skb) |
349 | { | 375 | { |
@@ -359,22 +385,7 @@ void *get_rbd(struct sk_buff *skb) | |||
359 | static inline u64 | 385 | static inline u64 |
360 | lio_map_ring_info(struct octeon_droq *droq, u32 i) | 386 | lio_map_ring_info(struct octeon_droq *droq, u32 i) |
361 | { | 387 | { |
362 | dma_addr_t dma_addr; | 388 | return droq->info_list_dma + (i * sizeof(struct octeon_droq_info)); |
363 | struct octeon_device *oct = droq->oct_dev; | ||
364 | |||
365 | dma_addr = dma_map_single(&oct->pci_dev->dev, &droq->info_list[i], | ||
366 | OCT_DROQ_INFO_SIZE, DMA_FROM_DEVICE); | ||
367 | |||
368 | WARN_ON(dma_mapping_error(&oct->pci_dev->dev, dma_addr)); | ||
369 | |||
370 | return (u64)dma_addr; | ||
371 | } | ||
372 | |||
373 | static inline void | ||
374 | lio_unmap_ring_info(struct pci_dev *pci_dev, | ||
375 | u64 info_ptr, u32 size) | ||
376 | { | ||
377 | dma_unmap_single(&pci_dev->dev, info_ptr, size, DMA_FROM_DEVICE); | ||
378 | } | 389 | } |
379 | 390 | ||
380 | static inline u64 | 391 | static inline u64 |
diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h index e739c7153562..2269ff562d95 100644 --- a/drivers/net/ethernet/cavium/thunder/nic.h +++ b/drivers/net/ethernet/cavium/thunder/nic.h | |||
@@ -269,6 +269,7 @@ struct nicvf { | |||
269 | #define MAX_QUEUES_PER_QSET 8 | 269 | #define MAX_QUEUES_PER_QSET 8 |
270 | struct queue_set *qs; | 270 | struct queue_set *qs; |
271 | struct nicvf_cq_poll *napi[8]; | 271 | struct nicvf_cq_poll *napi[8]; |
272 | void *iommu_domain; | ||
272 | u8 vf_id; | 273 | u8 vf_id; |
273 | u8 sqs_id; | 274 | u8 sqs_id; |
274 | bool sqs_mode; | 275 | bool sqs_mode; |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index 6feaa24bcfd4..24017588f531 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/log2.h> | 16 | #include <linux/log2.h> |
17 | #include <linux/prefetch.h> | 17 | #include <linux/prefetch.h> |
18 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
19 | #include <linux/iommu.h> | ||
19 | 20 | ||
20 | #include "nic_reg.h" | 21 | #include "nic_reg.h" |
21 | #include "nic.h" | 22 | #include "nic.h" |
@@ -525,7 +526,12 @@ static void nicvf_snd_pkt_handler(struct net_device *netdev, | |||
525 | /* Get actual TSO descriptors and free them */ | 526 | /* Get actual TSO descriptors and free them */ |
526 | tso_sqe = | 527 | tso_sqe = |
527 | (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, hdr->rsvd2); | 528 | (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, hdr->rsvd2); |
529 | nicvf_unmap_sndq_buffers(nic, sq, hdr->rsvd2, | ||
530 | tso_sqe->subdesc_cnt); | ||
528 | nicvf_put_sq_desc(sq, tso_sqe->subdesc_cnt + 1); | 531 | nicvf_put_sq_desc(sq, tso_sqe->subdesc_cnt + 1); |
532 | } else { | ||
533 | nicvf_unmap_sndq_buffers(nic, sq, cqe_tx->sqe_ptr, | ||
534 | hdr->subdesc_cnt); | ||
529 | } | 535 | } |
530 | nicvf_put_sq_desc(sq, hdr->subdesc_cnt + 1); | 536 | nicvf_put_sq_desc(sq, hdr->subdesc_cnt + 1); |
531 | prefetch(skb); | 537 | prefetch(skb); |
@@ -576,6 +582,7 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev, | |||
576 | { | 582 | { |
577 | struct sk_buff *skb; | 583 | struct sk_buff *skb; |
578 | struct nicvf *nic = netdev_priv(netdev); | 584 | struct nicvf *nic = netdev_priv(netdev); |
585 | struct nicvf *snic = nic; | ||
579 | int err = 0; | 586 | int err = 0; |
580 | int rq_idx; | 587 | int rq_idx; |
581 | 588 | ||
@@ -592,7 +599,7 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev, | |||
592 | if (err && !cqe_rx->rb_cnt) | 599 | if (err && !cqe_rx->rb_cnt) |
593 | return; | 600 | return; |
594 | 601 | ||
595 | skb = nicvf_get_rcv_skb(nic, cqe_rx); | 602 | skb = nicvf_get_rcv_skb(snic, cqe_rx); |
596 | if (!skb) { | 603 | if (!skb) { |
597 | netdev_dbg(nic->netdev, "Packet not received\n"); | 604 | netdev_dbg(nic->netdev, "Packet not received\n"); |
598 | return; | 605 | return; |
@@ -1643,6 +1650,9 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1643 | if (!pass1_silicon(nic->pdev)) | 1650 | if (!pass1_silicon(nic->pdev)) |
1644 | nic->hw_tso = true; | 1651 | nic->hw_tso = true; |
1645 | 1652 | ||
1653 | /* Get iommu domain for iova to physical addr conversion */ | ||
1654 | nic->iommu_domain = iommu_get_domain_for_dev(dev); | ||
1655 | |||
1646 | pci_read_config_word(nic->pdev, PCI_SUBSYSTEM_ID, &sdevid); | 1656 | pci_read_config_word(nic->pdev, PCI_SUBSYSTEM_ID, &sdevid); |
1647 | if (sdevid == 0xA134) | 1657 | if (sdevid == 0xA134) |
1648 | nic->t88 = true; | 1658 | nic->t88 = true; |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c index ac0390be3b12..f13289f0d238 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/netdevice.h> | 10 | #include <linux/netdevice.h> |
11 | #include <linux/ip.h> | 11 | #include <linux/ip.h> |
12 | #include <linux/etherdevice.h> | 12 | #include <linux/etherdevice.h> |
13 | #include <linux/iommu.h> | ||
13 | #include <net/ip.h> | 14 | #include <net/ip.h> |
14 | #include <net/tso.h> | 15 | #include <net/tso.h> |
15 | 16 | ||
@@ -18,6 +19,16 @@ | |||
18 | #include "q_struct.h" | 19 | #include "q_struct.h" |
19 | #include "nicvf_queues.h" | 20 | #include "nicvf_queues.h" |
20 | 21 | ||
22 | #define NICVF_PAGE_ORDER ((PAGE_SIZE <= 4096) ? PAGE_ALLOC_COSTLY_ORDER : 0) | ||
23 | |||
24 | static inline u64 nicvf_iova_to_phys(struct nicvf *nic, dma_addr_t dma_addr) | ||
25 | { | ||
26 | /* Translation is installed only when IOMMU is present */ | ||
27 | if (nic->iommu_domain) | ||
28 | return iommu_iova_to_phys(nic->iommu_domain, dma_addr); | ||
29 | return dma_addr; | ||
30 | } | ||
31 | |||
21 | static void nicvf_get_page(struct nicvf *nic) | 32 | static void nicvf_get_page(struct nicvf *nic) |
22 | { | 33 | { |
23 | if (!nic->rb_pageref || !nic->rb_page) | 34 | if (!nic->rb_pageref || !nic->rb_page) |
@@ -87,7 +98,7 @@ static void nicvf_free_q_desc_mem(struct nicvf *nic, struct q_desc_mem *dmem) | |||
87 | static inline int nicvf_alloc_rcv_buffer(struct nicvf *nic, gfp_t gfp, | 98 | static inline int nicvf_alloc_rcv_buffer(struct nicvf *nic, gfp_t gfp, |
88 | u32 buf_len, u64 **rbuf) | 99 | u32 buf_len, u64 **rbuf) |
89 | { | 100 | { |
90 | int order = (PAGE_SIZE <= 4096) ? PAGE_ALLOC_COSTLY_ORDER : 0; | 101 | int order = NICVF_PAGE_ORDER; |
91 | 102 | ||
92 | /* Check if request can be accomodated in previous allocated page */ | 103 | /* Check if request can be accomodated in previous allocated page */ |
93 | if (nic->rb_page && | 104 | if (nic->rb_page && |
@@ -97,22 +108,27 @@ static inline int nicvf_alloc_rcv_buffer(struct nicvf *nic, gfp_t gfp, | |||
97 | } | 108 | } |
98 | 109 | ||
99 | nicvf_get_page(nic); | 110 | nicvf_get_page(nic); |
100 | nic->rb_page = NULL; | ||
101 | 111 | ||
102 | /* Allocate a new page */ | 112 | /* Allocate a new page */ |
113 | nic->rb_page = alloc_pages(gfp | __GFP_COMP | __GFP_NOWARN, | ||
114 | order); | ||
103 | if (!nic->rb_page) { | 115 | if (!nic->rb_page) { |
104 | nic->rb_page = alloc_pages(gfp | __GFP_COMP | __GFP_NOWARN, | 116 | this_cpu_inc(nic->pnicvf->drv_stats->rcv_buffer_alloc_failures); |
105 | order); | 117 | return -ENOMEM; |
106 | if (!nic->rb_page) { | ||
107 | this_cpu_inc(nic->pnicvf->drv_stats-> | ||
108 | rcv_buffer_alloc_failures); | ||
109 | return -ENOMEM; | ||
110 | } | ||
111 | nic->rb_page_offset = 0; | ||
112 | } | 118 | } |
113 | 119 | nic->rb_page_offset = 0; | |
114 | ret: | 120 | ret: |
115 | *rbuf = (u64 *)((u64)page_address(nic->rb_page) + nic->rb_page_offset); | 121 | /* HW will ensure data coherency, CPU sync not required */ |
122 | *rbuf = (u64 *)((u64)dma_map_page_attrs(&nic->pdev->dev, nic->rb_page, | ||
123 | nic->rb_page_offset, buf_len, | ||
124 | DMA_FROM_DEVICE, | ||
125 | DMA_ATTR_SKIP_CPU_SYNC)); | ||
126 | if (dma_mapping_error(&nic->pdev->dev, (dma_addr_t)*rbuf)) { | ||
127 | if (!nic->rb_page_offset) | ||
128 | __free_pages(nic->rb_page, order); | ||
129 | nic->rb_page = NULL; | ||
130 | return -ENOMEM; | ||
131 | } | ||
116 | nic->rb_page_offset += buf_len; | 132 | nic->rb_page_offset += buf_len; |
117 | 133 | ||
118 | return 0; | 134 | return 0; |
@@ -158,16 +174,21 @@ static int nicvf_init_rbdr(struct nicvf *nic, struct rbdr *rbdr, | |||
158 | rbdr->dma_size = buf_size; | 174 | rbdr->dma_size = buf_size; |
159 | rbdr->enable = true; | 175 | rbdr->enable = true; |
160 | rbdr->thresh = RBDR_THRESH; | 176 | rbdr->thresh = RBDR_THRESH; |
177 | rbdr->head = 0; | ||
178 | rbdr->tail = 0; | ||
161 | 179 | ||
162 | nic->rb_page = NULL; | 180 | nic->rb_page = NULL; |
163 | for (idx = 0; idx < ring_len; idx++) { | 181 | for (idx = 0; idx < ring_len; idx++) { |
164 | err = nicvf_alloc_rcv_buffer(nic, GFP_KERNEL, RCV_FRAG_LEN, | 182 | err = nicvf_alloc_rcv_buffer(nic, GFP_KERNEL, RCV_FRAG_LEN, |
165 | &rbuf); | 183 | &rbuf); |
166 | if (err) | 184 | if (err) { |
185 | /* To free already allocated and mapped ones */ | ||
186 | rbdr->tail = idx - 1; | ||
167 | return err; | 187 | return err; |
188 | } | ||
168 | 189 | ||
169 | desc = GET_RBDR_DESC(rbdr, idx); | 190 | desc = GET_RBDR_DESC(rbdr, idx); |
170 | desc->buf_addr = virt_to_phys(rbuf) >> NICVF_RCV_BUF_ALIGN; | 191 | desc->buf_addr = (u64)rbuf >> NICVF_RCV_BUF_ALIGN; |
171 | } | 192 | } |
172 | 193 | ||
173 | nicvf_get_page(nic); | 194 | nicvf_get_page(nic); |
@@ -179,7 +200,7 @@ static int nicvf_init_rbdr(struct nicvf *nic, struct rbdr *rbdr, | |||
179 | static void nicvf_free_rbdr(struct nicvf *nic, struct rbdr *rbdr) | 200 | static void nicvf_free_rbdr(struct nicvf *nic, struct rbdr *rbdr) |
180 | { | 201 | { |
181 | int head, tail; | 202 | int head, tail; |
182 | u64 buf_addr; | 203 | u64 buf_addr, phys_addr; |
183 | struct rbdr_entry_t *desc; | 204 | struct rbdr_entry_t *desc; |
184 | 205 | ||
185 | if (!rbdr) | 206 | if (!rbdr) |
@@ -192,18 +213,26 @@ static void nicvf_free_rbdr(struct nicvf *nic, struct rbdr *rbdr) | |||
192 | head = rbdr->head; | 213 | head = rbdr->head; |
193 | tail = rbdr->tail; | 214 | tail = rbdr->tail; |
194 | 215 | ||
195 | /* Free SKBs */ | 216 | /* Release page references */ |
196 | while (head != tail) { | 217 | while (head != tail) { |
197 | desc = GET_RBDR_DESC(rbdr, head); | 218 | desc = GET_RBDR_DESC(rbdr, head); |
198 | buf_addr = desc->buf_addr << NICVF_RCV_BUF_ALIGN; | 219 | buf_addr = ((u64)desc->buf_addr) << NICVF_RCV_BUF_ALIGN; |
199 | put_page(virt_to_page(phys_to_virt(buf_addr))); | 220 | phys_addr = nicvf_iova_to_phys(nic, buf_addr); |
221 | dma_unmap_page_attrs(&nic->pdev->dev, buf_addr, RCV_FRAG_LEN, | ||
222 | DMA_FROM_DEVICE, DMA_ATTR_SKIP_CPU_SYNC); | ||
223 | if (phys_addr) | ||
224 | put_page(virt_to_page(phys_to_virt(phys_addr))); | ||
200 | head++; | 225 | head++; |
201 | head &= (rbdr->dmem.q_len - 1); | 226 | head &= (rbdr->dmem.q_len - 1); |
202 | } | 227 | } |
203 | /* Free SKB of tail desc */ | 228 | /* Release buffer of tail desc */ |
204 | desc = GET_RBDR_DESC(rbdr, tail); | 229 | desc = GET_RBDR_DESC(rbdr, tail); |
205 | buf_addr = desc->buf_addr << NICVF_RCV_BUF_ALIGN; | 230 | buf_addr = ((u64)desc->buf_addr) << NICVF_RCV_BUF_ALIGN; |
206 | put_page(virt_to_page(phys_to_virt(buf_addr))); | 231 | phys_addr = nicvf_iova_to_phys(nic, buf_addr); |
232 | dma_unmap_page_attrs(&nic->pdev->dev, buf_addr, RCV_FRAG_LEN, | ||
233 | DMA_FROM_DEVICE, DMA_ATTR_SKIP_CPU_SYNC); | ||
234 | if (phys_addr) | ||
235 | put_page(virt_to_page(phys_to_virt(phys_addr))); | ||
207 | 236 | ||
208 | /* Free RBDR ring */ | 237 | /* Free RBDR ring */ |
209 | nicvf_free_q_desc_mem(nic, &rbdr->dmem); | 238 | nicvf_free_q_desc_mem(nic, &rbdr->dmem); |
@@ -250,7 +279,7 @@ refill: | |||
250 | break; | 279 | break; |
251 | 280 | ||
252 | desc = GET_RBDR_DESC(rbdr, tail); | 281 | desc = GET_RBDR_DESC(rbdr, tail); |
253 | desc->buf_addr = virt_to_phys(rbuf) >> NICVF_RCV_BUF_ALIGN; | 282 | desc->buf_addr = (u64)rbuf >> NICVF_RCV_BUF_ALIGN; |
254 | refill_rb_cnt--; | 283 | refill_rb_cnt--; |
255 | new_rb++; | 284 | new_rb++; |
256 | } | 285 | } |
@@ -361,9 +390,29 @@ static int nicvf_init_snd_queue(struct nicvf *nic, | |||
361 | return 0; | 390 | return 0; |
362 | } | 391 | } |
363 | 392 | ||
393 | void nicvf_unmap_sndq_buffers(struct nicvf *nic, struct snd_queue *sq, | ||
394 | int hdr_sqe, u8 subdesc_cnt) | ||
395 | { | ||
396 | u8 idx; | ||
397 | struct sq_gather_subdesc *gather; | ||
398 | |||
399 | /* Unmap DMA mapped skb data buffers */ | ||
400 | for (idx = 0; idx < subdesc_cnt; idx++) { | ||
401 | hdr_sqe++; | ||
402 | hdr_sqe &= (sq->dmem.q_len - 1); | ||
403 | gather = (struct sq_gather_subdesc *)GET_SQ_DESC(sq, hdr_sqe); | ||
404 | /* HW will ensure data coherency, CPU sync not required */ | ||
405 | dma_unmap_page_attrs(&nic->pdev->dev, gather->addr, | ||
406 | gather->size, DMA_TO_DEVICE, | ||
407 | DMA_ATTR_SKIP_CPU_SYNC); | ||
408 | } | ||
409 | } | ||
410 | |||
364 | static void nicvf_free_snd_queue(struct nicvf *nic, struct snd_queue *sq) | 411 | static void nicvf_free_snd_queue(struct nicvf *nic, struct snd_queue *sq) |
365 | { | 412 | { |
366 | struct sk_buff *skb; | 413 | struct sk_buff *skb; |
414 | struct sq_hdr_subdesc *hdr; | ||
415 | struct sq_hdr_subdesc *tso_sqe; | ||
367 | 416 | ||
368 | if (!sq) | 417 | if (!sq) |
369 | return; | 418 | return; |
@@ -379,8 +428,22 @@ static void nicvf_free_snd_queue(struct nicvf *nic, struct snd_queue *sq) | |||
379 | smp_rmb(); | 428 | smp_rmb(); |
380 | while (sq->head != sq->tail) { | 429 | while (sq->head != sq->tail) { |
381 | skb = (struct sk_buff *)sq->skbuff[sq->head]; | 430 | skb = (struct sk_buff *)sq->skbuff[sq->head]; |
382 | if (skb) | 431 | if (!skb) |
383 | dev_kfree_skb_any(skb); | 432 | goto next; |
433 | hdr = (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, sq->head); | ||
434 | /* Check for dummy descriptor used for HW TSO offload on 88xx */ | ||
435 | if (hdr->dont_send) { | ||
436 | /* Get actual TSO descriptors and unmap them */ | ||
437 | tso_sqe = | ||
438 | (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, hdr->rsvd2); | ||
439 | nicvf_unmap_sndq_buffers(nic, sq, hdr->rsvd2, | ||
440 | tso_sqe->subdesc_cnt); | ||
441 | } else { | ||
442 | nicvf_unmap_sndq_buffers(nic, sq, sq->head, | ||
443 | hdr->subdesc_cnt); | ||
444 | } | ||
445 | dev_kfree_skb_any(skb); | ||
446 | next: | ||
384 | sq->head++; | 447 | sq->head++; |
385 | sq->head &= (sq->dmem.q_len - 1); | 448 | sq->head &= (sq->dmem.q_len - 1); |
386 | } | 449 | } |
@@ -559,9 +622,11 @@ static void nicvf_rcv_queue_config(struct nicvf *nic, struct queue_set *qs, | |||
559 | nicvf_send_msg_to_pf(nic, &mbx); | 622 | nicvf_send_msg_to_pf(nic, &mbx); |
560 | 623 | ||
561 | if (!nic->sqs_mode && (qidx == 0)) { | 624 | if (!nic->sqs_mode && (qidx == 0)) { |
562 | /* Enable checking L3/L4 length and TCP/UDP checksums */ | 625 | /* Enable checking L3/L4 length and TCP/UDP checksums |
626 | * Also allow IPv6 pkts with zero UDP checksum. | ||
627 | */ | ||
563 | nicvf_queue_reg_write(nic, NIC_QSET_RQ_GEN_CFG, 0, | 628 | nicvf_queue_reg_write(nic, NIC_QSET_RQ_GEN_CFG, 0, |
564 | (BIT(24) | BIT(23) | BIT(21))); | 629 | (BIT(24) | BIT(23) | BIT(21) | BIT(20))); |
565 | nicvf_config_vlan_stripping(nic, nic->netdev->features); | 630 | nicvf_config_vlan_stripping(nic, nic->netdev->features); |
566 | } | 631 | } |
567 | 632 | ||
@@ -882,6 +947,14 @@ static inline int nicvf_get_sq_desc(struct snd_queue *sq, int desc_cnt) | |||
882 | return qentry; | 947 | return qentry; |
883 | } | 948 | } |
884 | 949 | ||
950 | /* Rollback to previous tail pointer when descriptors not used */ | ||
951 | static inline void nicvf_rollback_sq_desc(struct snd_queue *sq, | ||
952 | int qentry, int desc_cnt) | ||
953 | { | ||
954 | sq->tail = qentry; | ||
955 | atomic_add(desc_cnt, &sq->free_cnt); | ||
956 | } | ||
957 | |||
885 | /* Free descriptor back to SQ for future use */ | 958 | /* Free descriptor back to SQ for future use */ |
886 | void nicvf_put_sq_desc(struct snd_queue *sq, int desc_cnt) | 959 | void nicvf_put_sq_desc(struct snd_queue *sq, int desc_cnt) |
887 | { | 960 | { |
@@ -1207,8 +1280,9 @@ int nicvf_sq_append_skb(struct nicvf *nic, struct snd_queue *sq, | |||
1207 | struct sk_buff *skb, u8 sq_num) | 1280 | struct sk_buff *skb, u8 sq_num) |
1208 | { | 1281 | { |
1209 | int i, size; | 1282 | int i, size; |
1210 | int subdesc_cnt, tso_sqe = 0; | 1283 | int subdesc_cnt, hdr_sqe = 0; |
1211 | int qentry; | 1284 | int qentry; |
1285 | u64 dma_addr; | ||
1212 | 1286 | ||
1213 | subdesc_cnt = nicvf_sq_subdesc_required(nic, skb); | 1287 | subdesc_cnt = nicvf_sq_subdesc_required(nic, skb); |
1214 | if (subdesc_cnt > atomic_read(&sq->free_cnt)) | 1288 | if (subdesc_cnt > atomic_read(&sq->free_cnt)) |
@@ -1223,12 +1297,21 @@ int nicvf_sq_append_skb(struct nicvf *nic, struct snd_queue *sq, | |||
1223 | /* Add SQ header subdesc */ | 1297 | /* Add SQ header subdesc */ |
1224 | nicvf_sq_add_hdr_subdesc(nic, sq, qentry, subdesc_cnt - 1, | 1298 | nicvf_sq_add_hdr_subdesc(nic, sq, qentry, subdesc_cnt - 1, |
1225 | skb, skb->len); | 1299 | skb, skb->len); |
1226 | tso_sqe = qentry; | 1300 | hdr_sqe = qentry; |
1227 | 1301 | ||
1228 | /* Add SQ gather subdescs */ | 1302 | /* Add SQ gather subdescs */ |
1229 | qentry = nicvf_get_nxt_sqentry(sq, qentry); | 1303 | qentry = nicvf_get_nxt_sqentry(sq, qentry); |
1230 | size = skb_is_nonlinear(skb) ? skb_headlen(skb) : skb->len; | 1304 | size = skb_is_nonlinear(skb) ? skb_headlen(skb) : skb->len; |
1231 | nicvf_sq_add_gather_subdesc(sq, qentry, size, virt_to_phys(skb->data)); | 1305 | /* HW will ensure data coherency, CPU sync not required */ |
1306 | dma_addr = dma_map_page_attrs(&nic->pdev->dev, virt_to_page(skb->data), | ||
1307 | offset_in_page(skb->data), size, | ||
1308 | DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC); | ||
1309 | if (dma_mapping_error(&nic->pdev->dev, dma_addr)) { | ||
1310 | nicvf_rollback_sq_desc(sq, qentry, subdesc_cnt); | ||
1311 | return 0; | ||
1312 | } | ||
1313 | |||
1314 | nicvf_sq_add_gather_subdesc(sq, qentry, size, dma_addr); | ||
1232 | 1315 | ||
1233 | /* Check for scattered buffer */ | 1316 | /* Check for scattered buffer */ |
1234 | if (!skb_is_nonlinear(skb)) | 1317 | if (!skb_is_nonlinear(skb)) |
@@ -1241,15 +1324,26 @@ int nicvf_sq_append_skb(struct nicvf *nic, struct snd_queue *sq, | |||
1241 | 1324 | ||
1242 | qentry = nicvf_get_nxt_sqentry(sq, qentry); | 1325 | qentry = nicvf_get_nxt_sqentry(sq, qentry); |
1243 | size = skb_frag_size(frag); | 1326 | size = skb_frag_size(frag); |
1244 | nicvf_sq_add_gather_subdesc(sq, qentry, size, | 1327 | dma_addr = dma_map_page_attrs(&nic->pdev->dev, |
1245 | virt_to_phys( | 1328 | skb_frag_page(frag), |
1246 | skb_frag_address(frag))); | 1329 | frag->page_offset, size, |
1330 | DMA_TO_DEVICE, | ||
1331 | DMA_ATTR_SKIP_CPU_SYNC); | ||
1332 | if (dma_mapping_error(&nic->pdev->dev, dma_addr)) { | ||
1333 | /* Free entire chain of mapped buffers | ||
1334 | * here 'i' = frags mapped + above mapped skb->data | ||
1335 | */ | ||
1336 | nicvf_unmap_sndq_buffers(nic, sq, hdr_sqe, i); | ||
1337 | nicvf_rollback_sq_desc(sq, qentry, subdesc_cnt); | ||
1338 | return 0; | ||
1339 | } | ||
1340 | nicvf_sq_add_gather_subdesc(sq, qentry, size, dma_addr); | ||
1247 | } | 1341 | } |
1248 | 1342 | ||
1249 | doorbell: | 1343 | doorbell: |
1250 | if (nic->t88 && skb_shinfo(skb)->gso_size) { | 1344 | if (nic->t88 && skb_shinfo(skb)->gso_size) { |
1251 | qentry = nicvf_get_nxt_sqentry(sq, qentry); | 1345 | qentry = nicvf_get_nxt_sqentry(sq, qentry); |
1252 | nicvf_sq_add_cqe_subdesc(sq, qentry, tso_sqe, skb); | 1346 | nicvf_sq_add_cqe_subdesc(sq, qentry, hdr_sqe, skb); |
1253 | } | 1347 | } |
1254 | 1348 | ||
1255 | nicvf_sq_doorbell(nic, skb, sq_num, subdesc_cnt); | 1349 | nicvf_sq_doorbell(nic, skb, sq_num, subdesc_cnt); |
@@ -1282,6 +1376,7 @@ struct sk_buff *nicvf_get_rcv_skb(struct nicvf *nic, struct cqe_rx_t *cqe_rx) | |||
1282 | int offset; | 1376 | int offset; |
1283 | u16 *rb_lens = NULL; | 1377 | u16 *rb_lens = NULL; |
1284 | u64 *rb_ptrs = NULL; | 1378 | u64 *rb_ptrs = NULL; |
1379 | u64 phys_addr; | ||
1285 | 1380 | ||
1286 | rb_lens = (void *)cqe_rx + (3 * sizeof(u64)); | 1381 | rb_lens = (void *)cqe_rx + (3 * sizeof(u64)); |
1287 | /* Except 88xx pass1 on all other chips CQE_RX2_S is added to | 1382 | /* Except 88xx pass1 on all other chips CQE_RX2_S is added to |
@@ -1296,15 +1391,23 @@ struct sk_buff *nicvf_get_rcv_skb(struct nicvf *nic, struct cqe_rx_t *cqe_rx) | |||
1296 | else | 1391 | else |
1297 | rb_ptrs = (void *)cqe_rx + (7 * sizeof(u64)); | 1392 | rb_ptrs = (void *)cqe_rx + (7 * sizeof(u64)); |
1298 | 1393 | ||
1299 | netdev_dbg(nic->netdev, "%s rb_cnt %d rb0_ptr %llx rb0_sz %d\n", | ||
1300 | __func__, cqe_rx->rb_cnt, cqe_rx->rb0_ptr, cqe_rx->rb0_sz); | ||
1301 | |||
1302 | for (frag = 0; frag < cqe_rx->rb_cnt; frag++) { | 1394 | for (frag = 0; frag < cqe_rx->rb_cnt; frag++) { |
1303 | payload_len = rb_lens[frag_num(frag)]; | 1395 | payload_len = rb_lens[frag_num(frag)]; |
1396 | phys_addr = nicvf_iova_to_phys(nic, *rb_ptrs); | ||
1397 | if (!phys_addr) { | ||
1398 | if (skb) | ||
1399 | dev_kfree_skb_any(skb); | ||
1400 | return NULL; | ||
1401 | } | ||
1402 | |||
1304 | if (!frag) { | 1403 | if (!frag) { |
1305 | /* First fragment */ | 1404 | /* First fragment */ |
1405 | dma_unmap_page_attrs(&nic->pdev->dev, | ||
1406 | *rb_ptrs - cqe_rx->align_pad, | ||
1407 | RCV_FRAG_LEN, DMA_FROM_DEVICE, | ||
1408 | DMA_ATTR_SKIP_CPU_SYNC); | ||
1306 | skb = nicvf_rb_ptr_to_skb(nic, | 1409 | skb = nicvf_rb_ptr_to_skb(nic, |
1307 | *rb_ptrs - cqe_rx->align_pad, | 1410 | phys_addr - cqe_rx->align_pad, |
1308 | payload_len); | 1411 | payload_len); |
1309 | if (!skb) | 1412 | if (!skb) |
1310 | return NULL; | 1413 | return NULL; |
@@ -1312,8 +1415,11 @@ struct sk_buff *nicvf_get_rcv_skb(struct nicvf *nic, struct cqe_rx_t *cqe_rx) | |||
1312 | skb_put(skb, payload_len); | 1415 | skb_put(skb, payload_len); |
1313 | } else { | 1416 | } else { |
1314 | /* Add fragments */ | 1417 | /* Add fragments */ |
1315 | page = virt_to_page(phys_to_virt(*rb_ptrs)); | 1418 | dma_unmap_page_attrs(&nic->pdev->dev, *rb_ptrs, |
1316 | offset = phys_to_virt(*rb_ptrs) - page_address(page); | 1419 | RCV_FRAG_LEN, DMA_FROM_DEVICE, |
1420 | DMA_ATTR_SKIP_CPU_SYNC); | ||
1421 | page = virt_to_page(phys_to_virt(phys_addr)); | ||
1422 | offset = phys_to_virt(phys_addr) - page_address(page); | ||
1317 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, | 1423 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, |
1318 | offset, payload_len, RCV_FRAG_LEN); | 1424 | offset, payload_len, RCV_FRAG_LEN); |
1319 | } | 1425 | } |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h index 5cb84da99a2d..10cb4b84625b 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h +++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h | |||
@@ -87,7 +87,7 @@ | |||
87 | #define RCV_BUF_COUNT (1ULL << (RBDR_SIZE + 13)) | 87 | #define RCV_BUF_COUNT (1ULL << (RBDR_SIZE + 13)) |
88 | #define MAX_RCV_BUF_COUNT (1ULL << (RBDR_SIZE6 + 13)) | 88 | #define MAX_RCV_BUF_COUNT (1ULL << (RBDR_SIZE6 + 13)) |
89 | #define RBDR_THRESH (RCV_BUF_COUNT / 2) | 89 | #define RBDR_THRESH (RCV_BUF_COUNT / 2) |
90 | #define DMA_BUFFER_LEN 2048 /* In multiples of 128bytes */ | 90 | #define DMA_BUFFER_LEN 1536 /* In multiples of 128bytes */ |
91 | #define RCV_FRAG_LEN (SKB_DATA_ALIGN(DMA_BUFFER_LEN + NET_SKB_PAD) + \ | 91 | #define RCV_FRAG_LEN (SKB_DATA_ALIGN(DMA_BUFFER_LEN + NET_SKB_PAD) + \ |
92 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) | 92 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) |
93 | 93 | ||
@@ -301,6 +301,8 @@ struct queue_set { | |||
301 | 301 | ||
302 | #define CQ_ERR_MASK (CQ_WR_FULL | CQ_WR_DISABLE | CQ_WR_FAULT) | 302 | #define CQ_ERR_MASK (CQ_WR_FULL | CQ_WR_DISABLE | CQ_WR_FAULT) |
303 | 303 | ||
304 | void nicvf_unmap_sndq_buffers(struct nicvf *nic, struct snd_queue *sq, | ||
305 | int hdr_sqe, u8 subdesc_cnt); | ||
304 | void nicvf_config_vlan_stripping(struct nicvf *nic, | 306 | void nicvf_config_vlan_stripping(struct nicvf *nic, |
305 | netdev_features_t features); | 307 | netdev_features_t features); |
306 | int nicvf_set_qset_resources(struct nicvf *nic); | 308 | int nicvf_set_qset_resources(struct nicvf *nic); |
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c index 4c8e8cf730bb..64a1095e4d14 100644 --- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c +++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c | |||
@@ -123,14 +123,44 @@ static int bgx_poll_reg(struct bgx *bgx, u8 lmac, u64 reg, u64 mask, bool zero) | |||
123 | return 1; | 123 | return 1; |
124 | } | 124 | } |
125 | 125 | ||
126 | static int max_bgx_per_node; | ||
127 | static void set_max_bgx_per_node(struct pci_dev *pdev) | ||
128 | { | ||
129 | u16 sdevid; | ||
130 | |||
131 | if (max_bgx_per_node) | ||
132 | return; | ||
133 | |||
134 | pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &sdevid); | ||
135 | switch (sdevid) { | ||
136 | case PCI_SUBSYS_DEVID_81XX_BGX: | ||
137 | max_bgx_per_node = MAX_BGX_PER_CN81XX; | ||
138 | break; | ||
139 | case PCI_SUBSYS_DEVID_83XX_BGX: | ||
140 | max_bgx_per_node = MAX_BGX_PER_CN83XX; | ||
141 | break; | ||
142 | case PCI_SUBSYS_DEVID_88XX_BGX: | ||
143 | default: | ||
144 | max_bgx_per_node = MAX_BGX_PER_CN88XX; | ||
145 | break; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | static struct bgx *get_bgx(int node, int bgx_idx) | ||
150 | { | ||
151 | int idx = (node * max_bgx_per_node) + bgx_idx; | ||
152 | |||
153 | return bgx_vnic[idx]; | ||
154 | } | ||
155 | |||
126 | /* Return number of BGX present in HW */ | 156 | /* Return number of BGX present in HW */ |
127 | unsigned bgx_get_map(int node) | 157 | unsigned bgx_get_map(int node) |
128 | { | 158 | { |
129 | int i; | 159 | int i; |
130 | unsigned map = 0; | 160 | unsigned map = 0; |
131 | 161 | ||
132 | for (i = 0; i < MAX_BGX_PER_NODE; i++) { | 162 | for (i = 0; i < max_bgx_per_node; i++) { |
133 | if (bgx_vnic[(node * MAX_BGX_PER_NODE) + i]) | 163 | if (bgx_vnic[(node * max_bgx_per_node) + i]) |
134 | map |= (1 << i); | 164 | map |= (1 << i); |
135 | } | 165 | } |
136 | 166 | ||
@@ -143,7 +173,7 @@ int bgx_get_lmac_count(int node, int bgx_idx) | |||
143 | { | 173 | { |
144 | struct bgx *bgx; | 174 | struct bgx *bgx; |
145 | 175 | ||
146 | bgx = bgx_vnic[(node * MAX_BGX_PER_NODE) + bgx_idx]; | 176 | bgx = get_bgx(node, bgx_idx); |
147 | if (bgx) | 177 | if (bgx) |
148 | return bgx->lmac_count; | 178 | return bgx->lmac_count; |
149 | 179 | ||
@@ -158,7 +188,7 @@ void bgx_get_lmac_link_state(int node, int bgx_idx, int lmacid, void *status) | |||
158 | struct bgx *bgx; | 188 | struct bgx *bgx; |
159 | struct lmac *lmac; | 189 | struct lmac *lmac; |
160 | 190 | ||
161 | bgx = bgx_vnic[(node * MAX_BGX_PER_NODE) + bgx_idx]; | 191 | bgx = get_bgx(node, bgx_idx); |
162 | if (!bgx) | 192 | if (!bgx) |
163 | return; | 193 | return; |
164 | 194 | ||
@@ -172,7 +202,7 @@ EXPORT_SYMBOL(bgx_get_lmac_link_state); | |||
172 | 202 | ||
173 | const u8 *bgx_get_lmac_mac(int node, int bgx_idx, int lmacid) | 203 | const u8 *bgx_get_lmac_mac(int node, int bgx_idx, int lmacid) |
174 | { | 204 | { |
175 | struct bgx *bgx = bgx_vnic[(node * MAX_BGX_PER_NODE) + bgx_idx]; | 205 | struct bgx *bgx = get_bgx(node, bgx_idx); |
176 | 206 | ||
177 | if (bgx) | 207 | if (bgx) |
178 | return bgx->lmac[lmacid].mac; | 208 | return bgx->lmac[lmacid].mac; |
@@ -183,7 +213,7 @@ EXPORT_SYMBOL(bgx_get_lmac_mac); | |||
183 | 213 | ||
184 | void bgx_set_lmac_mac(int node, int bgx_idx, int lmacid, const u8 *mac) | 214 | void bgx_set_lmac_mac(int node, int bgx_idx, int lmacid, const u8 *mac) |
185 | { | 215 | { |
186 | struct bgx *bgx = bgx_vnic[(node * MAX_BGX_PER_NODE) + bgx_idx]; | 216 | struct bgx *bgx = get_bgx(node, bgx_idx); |
187 | 217 | ||
188 | if (!bgx) | 218 | if (!bgx) |
189 | return; | 219 | return; |
@@ -194,7 +224,7 @@ EXPORT_SYMBOL(bgx_set_lmac_mac); | |||
194 | 224 | ||
195 | void bgx_lmac_rx_tx_enable(int node, int bgx_idx, int lmacid, bool enable) | 225 | void bgx_lmac_rx_tx_enable(int node, int bgx_idx, int lmacid, bool enable) |
196 | { | 226 | { |
197 | struct bgx *bgx = bgx_vnic[(node * MAX_BGX_PER_NODE) + bgx_idx]; | 227 | struct bgx *bgx = get_bgx(node, bgx_idx); |
198 | struct lmac *lmac; | 228 | struct lmac *lmac; |
199 | u64 cfg; | 229 | u64 cfg; |
200 | 230 | ||
@@ -217,7 +247,7 @@ EXPORT_SYMBOL(bgx_lmac_rx_tx_enable); | |||
217 | void bgx_lmac_get_pfc(int node, int bgx_idx, int lmacid, void *pause) | 247 | void bgx_lmac_get_pfc(int node, int bgx_idx, int lmacid, void *pause) |
218 | { | 248 | { |
219 | struct pfc *pfc = (struct pfc *)pause; | 249 | struct pfc *pfc = (struct pfc *)pause; |
220 | struct bgx *bgx = bgx_vnic[(node * MAX_BGX_PER_CN88XX) + bgx_idx]; | 250 | struct bgx *bgx = get_bgx(node, bgx_idx); |
221 | struct lmac *lmac; | 251 | struct lmac *lmac; |
222 | u64 cfg; | 252 | u64 cfg; |
223 | 253 | ||
@@ -237,7 +267,7 @@ EXPORT_SYMBOL(bgx_lmac_get_pfc); | |||
237 | void bgx_lmac_set_pfc(int node, int bgx_idx, int lmacid, void *pause) | 267 | void bgx_lmac_set_pfc(int node, int bgx_idx, int lmacid, void *pause) |
238 | { | 268 | { |
239 | struct pfc *pfc = (struct pfc *)pause; | 269 | struct pfc *pfc = (struct pfc *)pause; |
240 | struct bgx *bgx = bgx_vnic[(node * MAX_BGX_PER_CN88XX) + bgx_idx]; | 270 | struct bgx *bgx = get_bgx(node, bgx_idx); |
241 | struct lmac *lmac; | 271 | struct lmac *lmac; |
242 | u64 cfg; | 272 | u64 cfg; |
243 | 273 | ||
@@ -369,7 +399,7 @@ u64 bgx_get_rx_stats(int node, int bgx_idx, int lmac, int idx) | |||
369 | { | 399 | { |
370 | struct bgx *bgx; | 400 | struct bgx *bgx; |
371 | 401 | ||
372 | bgx = bgx_vnic[(node * MAX_BGX_PER_NODE) + bgx_idx]; | 402 | bgx = get_bgx(node, bgx_idx); |
373 | if (!bgx) | 403 | if (!bgx) |
374 | return 0; | 404 | return 0; |
375 | 405 | ||
@@ -383,7 +413,7 @@ u64 bgx_get_tx_stats(int node, int bgx_idx, int lmac, int idx) | |||
383 | { | 413 | { |
384 | struct bgx *bgx; | 414 | struct bgx *bgx; |
385 | 415 | ||
386 | bgx = bgx_vnic[(node * MAX_BGX_PER_NODE) + bgx_idx]; | 416 | bgx = get_bgx(node, bgx_idx); |
387 | if (!bgx) | 417 | if (!bgx) |
388 | return 0; | 418 | return 0; |
389 | 419 | ||
@@ -411,7 +441,7 @@ void bgx_lmac_internal_loopback(int node, int bgx_idx, | |||
411 | struct lmac *lmac; | 441 | struct lmac *lmac; |
412 | u64 cfg; | 442 | u64 cfg; |
413 | 443 | ||
414 | bgx = bgx_vnic[(node * MAX_BGX_PER_NODE) + bgx_idx]; | 444 | bgx = get_bgx(node, bgx_idx); |
415 | if (!bgx) | 445 | if (!bgx) |
416 | return; | 446 | return; |
417 | 447 | ||
@@ -1011,12 +1041,6 @@ static void bgx_print_qlm_mode(struct bgx *bgx, u8 lmacid) | |||
1011 | dev_info(dev, "%s: 40G_KR4\n", (char *)str); | 1041 | dev_info(dev, "%s: 40G_KR4\n", (char *)str); |
1012 | break; | 1042 | break; |
1013 | case BGX_MODE_QSGMII: | 1043 | case BGX_MODE_QSGMII: |
1014 | if ((lmacid == 0) && | ||
1015 | (bgx_get_lane2sds_cfg(bgx, lmac) != lmacid)) | ||
1016 | return; | ||
1017 | if ((lmacid == 2) && | ||
1018 | (bgx_get_lane2sds_cfg(bgx, lmac) == lmacid)) | ||
1019 | return; | ||
1020 | dev_info(dev, "%s: QSGMII\n", (char *)str); | 1044 | dev_info(dev, "%s: QSGMII\n", (char *)str); |
1021 | break; | 1045 | break; |
1022 | case BGX_MODE_RGMII: | 1046 | case BGX_MODE_RGMII: |
@@ -1334,11 +1358,13 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1334 | goto err_release_regions; | 1358 | goto err_release_regions; |
1335 | } | 1359 | } |
1336 | 1360 | ||
1361 | set_max_bgx_per_node(pdev); | ||
1362 | |||
1337 | pci_read_config_word(pdev, PCI_DEVICE_ID, &sdevid); | 1363 | pci_read_config_word(pdev, PCI_DEVICE_ID, &sdevid); |
1338 | if (sdevid != PCI_DEVICE_ID_THUNDER_RGX) { | 1364 | if (sdevid != PCI_DEVICE_ID_THUNDER_RGX) { |
1339 | bgx->bgx_id = (pci_resource_start(pdev, | 1365 | bgx->bgx_id = (pci_resource_start(pdev, |
1340 | PCI_CFG_REG_BAR_NUM) >> 24) & BGX_ID_MASK; | 1366 | PCI_CFG_REG_BAR_NUM) >> 24) & BGX_ID_MASK; |
1341 | bgx->bgx_id += nic_get_node_id(pdev) * MAX_BGX_PER_NODE; | 1367 | bgx->bgx_id += nic_get_node_id(pdev) * max_bgx_per_node; |
1342 | bgx->max_lmac = MAX_LMAC_PER_BGX; | 1368 | bgx->max_lmac = MAX_LMAC_PER_BGX; |
1343 | bgx_vnic[bgx->bgx_id] = bgx; | 1369 | bgx_vnic[bgx->bgx_id] = bgx; |
1344 | } else { | 1370 | } else { |
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h index a60f189429bb..c5080f2cead5 100644 --- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h +++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h | |||
@@ -22,7 +22,6 @@ | |||
22 | #define MAX_BGX_PER_CN88XX 2 | 22 | #define MAX_BGX_PER_CN88XX 2 |
23 | #define MAX_BGX_PER_CN81XX 3 /* 2 BGXs + 1 RGX */ | 23 | #define MAX_BGX_PER_CN81XX 3 /* 2 BGXs + 1 RGX */ |
24 | #define MAX_BGX_PER_CN83XX 4 | 24 | #define MAX_BGX_PER_CN83XX 4 |
25 | #define MAX_BGX_PER_NODE 4 | ||
26 | #define MAX_LMAC_PER_BGX 4 | 25 | #define MAX_LMAC_PER_BGX 4 |
27 | #define MAX_BGX_CHANS_PER_LMAC 16 | 26 | #define MAX_BGX_CHANS_PER_LMAC 16 |
28 | #define MAX_DMAC_PER_LMAC 8 | 27 | #define MAX_DMAC_PER_LMAC 8 |
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index 275c2e2349ad..c44036d5761a 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c | |||
@@ -2589,8 +2589,6 @@ static int emac_dt_mdio_probe(struct emac_instance *dev) | |||
2589 | static int emac_dt_phy_connect(struct emac_instance *dev, | 2589 | static int emac_dt_phy_connect(struct emac_instance *dev, |
2590 | struct device_node *phy_handle) | 2590 | struct device_node *phy_handle) |
2591 | { | 2591 | { |
2592 | int res; | ||
2593 | |||
2594 | dev->phy.def = devm_kzalloc(&dev->ofdev->dev, sizeof(*dev->phy.def), | 2592 | dev->phy.def = devm_kzalloc(&dev->ofdev->dev, sizeof(*dev->phy.def), |
2595 | GFP_KERNEL); | 2593 | GFP_KERNEL); |
2596 | if (!dev->phy.def) | 2594 | if (!dev->phy.def) |
@@ -2617,7 +2615,7 @@ static int emac_dt_phy_probe(struct emac_instance *dev) | |||
2617 | { | 2615 | { |
2618 | struct device_node *np = dev->ofdev->dev.of_node; | 2616 | struct device_node *np = dev->ofdev->dev.of_node; |
2619 | struct device_node *phy_handle; | 2617 | struct device_node *phy_handle; |
2620 | int res = 0; | 2618 | int res = 1; |
2621 | 2619 | ||
2622 | phy_handle = of_parse_phandle(np, "phy-handle", 0); | 2620 | phy_handle = of_parse_phandle(np, "phy-handle", 0); |
2623 | 2621 | ||
@@ -2714,13 +2712,24 @@ static int emac_init_phy(struct emac_instance *dev) | |||
2714 | if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII)) { | 2712 | if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII)) { |
2715 | int res = emac_dt_phy_probe(dev); | 2713 | int res = emac_dt_phy_probe(dev); |
2716 | 2714 | ||
2717 | mutex_unlock(&emac_phy_map_lock); | 2715 | switch (res) { |
2718 | if (!res) | 2716 | case 1: |
2717 | /* No phy-handle property configured. | ||
2718 | * Continue with the existing phy probe | ||
2719 | * and setup code. | ||
2720 | */ | ||
2721 | break; | ||
2722 | |||
2723 | case 0: | ||
2724 | mutex_unlock(&emac_phy_map_lock); | ||
2719 | goto init_phy; | 2725 | goto init_phy; |
2720 | 2726 | ||
2721 | dev_err(&dev->ofdev->dev, "failed to attach dt phy (%d).\n", | 2727 | default: |
2722 | res); | 2728 | mutex_unlock(&emac_phy_map_lock); |
2723 | return res; | 2729 | dev_err(&dev->ofdev->dev, "failed to attach dt phy (%d).\n", |
2730 | res); | ||
2731 | return res; | ||
2732 | } | ||
2724 | } | 2733 | } |
2725 | 2734 | ||
2726 | if (dev->phy_address != 0xffffffff) | 2735 | if (dev->phy_address != 0xffffffff) |
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 9198e6bd5160..5f11b4dc95d2 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c | |||
@@ -404,7 +404,7 @@ static int ibmvnic_open(struct net_device *netdev) | |||
404 | send_map_query(adapter); | 404 | send_map_query(adapter); |
405 | for (i = 0; i < rxadd_subcrqs; i++) { | 405 | for (i = 0; i < rxadd_subcrqs; i++) { |
406 | init_rx_pool(adapter, &adapter->rx_pool[i], | 406 | init_rx_pool(adapter, &adapter->rx_pool[i], |
407 | IBMVNIC_BUFFS_PER_POOL, i, | 407 | adapter->req_rx_add_entries_per_subcrq, i, |
408 | be64_to_cpu(size_array[i]), 1); | 408 | be64_to_cpu(size_array[i]), 1); |
409 | if (alloc_rx_pool(adapter, &adapter->rx_pool[i])) { | 409 | if (alloc_rx_pool(adapter, &adapter->rx_pool[i])) { |
410 | dev_err(dev, "Couldn't alloc rx pool\n"); | 410 | dev_err(dev, "Couldn't alloc rx pool\n"); |
@@ -419,23 +419,23 @@ static int ibmvnic_open(struct net_device *netdev) | |||
419 | for (i = 0; i < tx_subcrqs; i++) { | 419 | for (i = 0; i < tx_subcrqs; i++) { |
420 | tx_pool = &adapter->tx_pool[i]; | 420 | tx_pool = &adapter->tx_pool[i]; |
421 | tx_pool->tx_buff = | 421 | tx_pool->tx_buff = |
422 | kcalloc(adapter->max_tx_entries_per_subcrq, | 422 | kcalloc(adapter->req_tx_entries_per_subcrq, |
423 | sizeof(struct ibmvnic_tx_buff), GFP_KERNEL); | 423 | sizeof(struct ibmvnic_tx_buff), GFP_KERNEL); |
424 | if (!tx_pool->tx_buff) | 424 | if (!tx_pool->tx_buff) |
425 | goto tx_pool_alloc_failed; | 425 | goto tx_pool_alloc_failed; |
426 | 426 | ||
427 | if (alloc_long_term_buff(adapter, &tx_pool->long_term_buff, | 427 | if (alloc_long_term_buff(adapter, &tx_pool->long_term_buff, |
428 | adapter->max_tx_entries_per_subcrq * | 428 | adapter->req_tx_entries_per_subcrq * |
429 | adapter->req_mtu)) | 429 | adapter->req_mtu)) |
430 | goto tx_ltb_alloc_failed; | 430 | goto tx_ltb_alloc_failed; |
431 | 431 | ||
432 | tx_pool->free_map = | 432 | tx_pool->free_map = |
433 | kcalloc(adapter->max_tx_entries_per_subcrq, | 433 | kcalloc(adapter->req_tx_entries_per_subcrq, |
434 | sizeof(int), GFP_KERNEL); | 434 | sizeof(int), GFP_KERNEL); |
435 | if (!tx_pool->free_map) | 435 | if (!tx_pool->free_map) |
436 | goto tx_fm_alloc_failed; | 436 | goto tx_fm_alloc_failed; |
437 | 437 | ||
438 | for (j = 0; j < adapter->max_tx_entries_per_subcrq; j++) | 438 | for (j = 0; j < adapter->req_tx_entries_per_subcrq; j++) |
439 | tx_pool->free_map[j] = j; | 439 | tx_pool->free_map[j] = j; |
440 | 440 | ||
441 | tx_pool->consumer_index = 0; | 441 | tx_pool->consumer_index = 0; |
@@ -705,6 +705,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
705 | u8 *hdrs = (u8 *)&adapter->tx_rx_desc_req; | 705 | u8 *hdrs = (u8 *)&adapter->tx_rx_desc_req; |
706 | struct device *dev = &adapter->vdev->dev; | 706 | struct device *dev = &adapter->vdev->dev; |
707 | struct ibmvnic_tx_buff *tx_buff = NULL; | 707 | struct ibmvnic_tx_buff *tx_buff = NULL; |
708 | struct ibmvnic_sub_crq_queue *tx_scrq; | ||
708 | struct ibmvnic_tx_pool *tx_pool; | 709 | struct ibmvnic_tx_pool *tx_pool; |
709 | unsigned int tx_send_failed = 0; | 710 | unsigned int tx_send_failed = 0; |
710 | unsigned int tx_map_failed = 0; | 711 | unsigned int tx_map_failed = 0; |
@@ -724,6 +725,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
724 | int ret = 0; | 725 | int ret = 0; |
725 | 726 | ||
726 | tx_pool = &adapter->tx_pool[queue_num]; | 727 | tx_pool = &adapter->tx_pool[queue_num]; |
728 | tx_scrq = adapter->tx_scrq[queue_num]; | ||
727 | txq = netdev_get_tx_queue(netdev, skb_get_queue_mapping(skb)); | 729 | txq = netdev_get_tx_queue(netdev, skb_get_queue_mapping(skb)); |
728 | handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) + | 730 | handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) + |
729 | be32_to_cpu(adapter->login_rsp_buf-> | 731 | be32_to_cpu(adapter->login_rsp_buf-> |
@@ -744,7 +746,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
744 | 746 | ||
745 | tx_pool->consumer_index = | 747 | tx_pool->consumer_index = |
746 | (tx_pool->consumer_index + 1) % | 748 | (tx_pool->consumer_index + 1) % |
747 | adapter->max_tx_entries_per_subcrq; | 749 | adapter->req_tx_entries_per_subcrq; |
748 | 750 | ||
749 | tx_buff = &tx_pool->tx_buff[index]; | 751 | tx_buff = &tx_pool->tx_buff[index]; |
750 | tx_buff->skb = skb; | 752 | tx_buff->skb = skb; |
@@ -817,7 +819,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
817 | 819 | ||
818 | if (tx_pool->consumer_index == 0) | 820 | if (tx_pool->consumer_index == 0) |
819 | tx_pool->consumer_index = | 821 | tx_pool->consumer_index = |
820 | adapter->max_tx_entries_per_subcrq - 1; | 822 | adapter->req_tx_entries_per_subcrq - 1; |
821 | else | 823 | else |
822 | tx_pool->consumer_index--; | 824 | tx_pool->consumer_index--; |
823 | 825 | ||
@@ -826,6 +828,14 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
826 | ret = NETDEV_TX_BUSY; | 828 | ret = NETDEV_TX_BUSY; |
827 | goto out; | 829 | goto out; |
828 | } | 830 | } |
831 | |||
832 | atomic_inc(&tx_scrq->used); | ||
833 | |||
834 | if (atomic_read(&tx_scrq->used) >= adapter->req_tx_entries_per_subcrq) { | ||
835 | netdev_info(netdev, "Stopping queue %d\n", queue_num); | ||
836 | netif_stop_subqueue(netdev, queue_num); | ||
837 | } | ||
838 | |||
829 | tx_packets++; | 839 | tx_packets++; |
830 | tx_bytes += skb->len; | 840 | tx_bytes += skb->len; |
831 | txq->trans_start = jiffies; | 841 | txq->trans_start = jiffies; |
@@ -1213,6 +1223,7 @@ static struct ibmvnic_sub_crq_queue *init_sub_crq_queue(struct ibmvnic_adapter | |||
1213 | scrq->adapter = adapter; | 1223 | scrq->adapter = adapter; |
1214 | scrq->size = 4 * PAGE_SIZE / sizeof(*scrq->msgs); | 1224 | scrq->size = 4 * PAGE_SIZE / sizeof(*scrq->msgs); |
1215 | scrq->cur = 0; | 1225 | scrq->cur = 0; |
1226 | atomic_set(&scrq->used, 0); | ||
1216 | scrq->rx_skb_top = NULL; | 1227 | scrq->rx_skb_top = NULL; |
1217 | spin_lock_init(&scrq->lock); | 1228 | spin_lock_init(&scrq->lock); |
1218 | 1229 | ||
@@ -1355,14 +1366,28 @@ restart_loop: | |||
1355 | DMA_TO_DEVICE); | 1366 | DMA_TO_DEVICE); |
1356 | } | 1367 | } |
1357 | 1368 | ||
1358 | if (txbuff->last_frag) | 1369 | if (txbuff->last_frag) { |
1370 | atomic_dec(&scrq->used); | ||
1371 | |||
1372 | if (atomic_read(&scrq->used) <= | ||
1373 | (adapter->req_tx_entries_per_subcrq / 2) && | ||
1374 | netif_subqueue_stopped(adapter->netdev, | ||
1375 | txbuff->skb)) { | ||
1376 | netif_wake_subqueue(adapter->netdev, | ||
1377 | scrq->pool_index); | ||
1378 | netdev_dbg(adapter->netdev, | ||
1379 | "Started queue %d\n", | ||
1380 | scrq->pool_index); | ||
1381 | } | ||
1382 | |||
1359 | dev_kfree_skb_any(txbuff->skb); | 1383 | dev_kfree_skb_any(txbuff->skb); |
1384 | } | ||
1360 | 1385 | ||
1361 | adapter->tx_pool[pool].free_map[adapter->tx_pool[pool]. | 1386 | adapter->tx_pool[pool].free_map[adapter->tx_pool[pool]. |
1362 | producer_index] = index; | 1387 | producer_index] = index; |
1363 | adapter->tx_pool[pool].producer_index = | 1388 | adapter->tx_pool[pool].producer_index = |
1364 | (adapter->tx_pool[pool].producer_index + 1) % | 1389 | (adapter->tx_pool[pool].producer_index + 1) % |
1365 | adapter->max_tx_entries_per_subcrq; | 1390 | adapter->req_tx_entries_per_subcrq; |
1366 | } | 1391 | } |
1367 | /* remove tx_comp scrq*/ | 1392 | /* remove tx_comp scrq*/ |
1368 | next->tx_comp.first = 0; | 1393 | next->tx_comp.first = 0; |
diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h index 422824f1f42a..1993b42666f7 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.h +++ b/drivers/net/ethernet/ibm/ibmvnic.h | |||
@@ -863,6 +863,7 @@ struct ibmvnic_sub_crq_queue { | |||
863 | spinlock_t lock; | 863 | spinlock_t lock; |
864 | struct sk_buff *rx_skb_top; | 864 | struct sk_buff *rx_skb_top; |
865 | struct ibmvnic_adapter *adapter; | 865 | struct ibmvnic_adapter *adapter; |
866 | atomic_t used; | ||
866 | }; | 867 | }; |
867 | 868 | ||
868 | struct ibmvnic_long_term_buff { | 869 | struct ibmvnic_long_term_buff { |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig index ddb4ca4ff930..117170014e88 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig +++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig | |||
@@ -14,6 +14,7 @@ config MLX5_CORE | |||
14 | config MLX5_CORE_EN | 14 | config MLX5_CORE_EN |
15 | bool "Mellanox Technologies ConnectX-4 Ethernet support" | 15 | bool "Mellanox Technologies ConnectX-4 Ethernet support" |
16 | depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE | 16 | depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE |
17 | depends on IPV6=y || IPV6=n || MLX5_CORE=m | ||
17 | imply PTP_1588_CLOCK | 18 | imply PTP_1588_CLOCK |
18 | default n | 19 | default n |
19 | ---help--- | 20 | ---help--- |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c index 0523ed47f597..8fa23f6a1f67 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | |||
@@ -302,6 +302,9 @@ static u8 mlx5e_dcbnl_setdcbx(struct net_device *dev, u8 mode) | |||
302 | struct mlx5e_priv *priv = netdev_priv(dev); | 302 | struct mlx5e_priv *priv = netdev_priv(dev); |
303 | struct mlx5e_dcbx *dcbx = &priv->dcbx; | 303 | struct mlx5e_dcbx *dcbx = &priv->dcbx; |
304 | 304 | ||
305 | if (mode & DCB_CAP_DCBX_LLD_MANAGED) | ||
306 | return 1; | ||
307 | |||
305 | if ((!mode) && MLX5_CAP_GEN(priv->mdev, dcbx)) { | 308 | if ((!mode) && MLX5_CAP_GEN(priv->mdev, dcbx)) { |
306 | if (dcbx->mode == MLX5E_DCBX_PARAM_VER_OPER_AUTO) | 309 | if (dcbx->mode == MLX5E_DCBX_PARAM_VER_OPER_AUTO) |
307 | return 0; | 310 | return 0; |
@@ -315,13 +318,10 @@ static u8 mlx5e_dcbnl_setdcbx(struct net_device *dev, u8 mode) | |||
315 | return 1; | 318 | return 1; |
316 | } | 319 | } |
317 | 320 | ||
318 | if (mlx5e_dcbnl_switch_to_host_mode(netdev_priv(dev))) | 321 | if (!(mode & DCB_CAP_DCBX_HOST)) |
319 | return 1; | 322 | return 1; |
320 | 323 | ||
321 | if ((mode & DCB_CAP_DCBX_LLD_MANAGED) || | 324 | if (mlx5e_dcbnl_switch_to_host_mode(netdev_priv(dev))) |
322 | !(mode & DCB_CAP_DCBX_VER_CEE) || | ||
323 | !(mode & DCB_CAP_DCBX_VER_IEEE) || | ||
324 | !(mode & DCB_CAP_DCBX_HOST)) | ||
325 | return 1; | 325 | return 1; |
326 | 326 | ||
327 | return 0; | 327 | return 0; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c index 31e3cb7ee5fe..5621dcfda4f1 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c | |||
@@ -204,9 +204,6 @@ mlx5e_test_loopback_validate(struct sk_buff *skb, | |||
204 | struct iphdr *iph; | 204 | struct iphdr *iph; |
205 | 205 | ||
206 | /* We are only going to peek, no need to clone the SKB */ | 206 | /* We are only going to peek, no need to clone the SKB */ |
207 | if (skb->protocol != htons(ETH_P_IP)) | ||
208 | goto out; | ||
209 | |||
210 | if (MLX5E_TEST_PKT_SIZE - ETH_HLEN > skb_headlen(skb)) | 207 | if (MLX5E_TEST_PKT_SIZE - ETH_HLEN > skb_headlen(skb)) |
211 | goto out; | 208 | goto out; |
212 | 209 | ||
@@ -249,7 +246,7 @@ static int mlx5e_test_loopback_setup(struct mlx5e_priv *priv, | |||
249 | lbtp->loopback_ok = false; | 246 | lbtp->loopback_ok = false; |
250 | init_completion(&lbtp->comp); | 247 | init_completion(&lbtp->comp); |
251 | 248 | ||
252 | lbtp->pt.type = htons(ETH_P_ALL); | 249 | lbtp->pt.type = htons(ETH_P_IP); |
253 | lbtp->pt.func = mlx5e_test_loopback_validate; | 250 | lbtp->pt.func = mlx5e_test_loopback_validate; |
254 | lbtp->pt.dev = priv->netdev; | 251 | lbtp->pt.dev = priv->netdev; |
255 | lbtp->pt.af_packet_priv = lbtp; | 252 | lbtp->pt.af_packet_priv = lbtp; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 44406a5ec15d..79481f4cf264 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | |||
@@ -48,9 +48,14 @@ | |||
48 | #include "eswitch.h" | 48 | #include "eswitch.h" |
49 | #include "vxlan.h" | 49 | #include "vxlan.h" |
50 | 50 | ||
51 | enum { | ||
52 | MLX5E_TC_FLOW_ESWITCH = BIT(0), | ||
53 | }; | ||
54 | |||
51 | struct mlx5e_tc_flow { | 55 | struct mlx5e_tc_flow { |
52 | struct rhash_head node; | 56 | struct rhash_head node; |
53 | u64 cookie; | 57 | u64 cookie; |
58 | u8 flags; | ||
54 | struct mlx5_flow_handle *rule; | 59 | struct mlx5_flow_handle *rule; |
55 | struct list_head encap; /* flows sharing the same encap */ | 60 | struct list_head encap; /* flows sharing the same encap */ |
56 | struct mlx5_esw_flow_attr *attr; | 61 | struct mlx5_esw_flow_attr *attr; |
@@ -177,7 +182,7 @@ static void mlx5e_tc_del_flow(struct mlx5e_priv *priv, | |||
177 | mlx5_fc_destroy(priv->mdev, counter); | 182 | mlx5_fc_destroy(priv->mdev, counter); |
178 | } | 183 | } |
179 | 184 | ||
180 | if (esw && esw->mode == SRIOV_OFFLOADS) { | 185 | if (flow->flags & MLX5E_TC_FLOW_ESWITCH) { |
181 | mlx5_eswitch_del_vlan_action(esw, flow->attr); | 186 | mlx5_eswitch_del_vlan_action(esw, flow->attr); |
182 | if (flow->attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP) | 187 | if (flow->attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP) |
183 | mlx5e_detach_encap(priv, flow); | 188 | mlx5e_detach_encap(priv, flow); |
@@ -598,6 +603,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, | |||
598 | } | 603 | } |
599 | 604 | ||
600 | static int parse_cls_flower(struct mlx5e_priv *priv, | 605 | static int parse_cls_flower(struct mlx5e_priv *priv, |
606 | struct mlx5e_tc_flow *flow, | ||
601 | struct mlx5_flow_spec *spec, | 607 | struct mlx5_flow_spec *spec, |
602 | struct tc_cls_flower_offload *f) | 608 | struct tc_cls_flower_offload *f) |
603 | { | 609 | { |
@@ -609,7 +615,7 @@ static int parse_cls_flower(struct mlx5e_priv *priv, | |||
609 | 615 | ||
610 | err = __parse_cls_flower(priv, spec, f, &min_inline); | 616 | err = __parse_cls_flower(priv, spec, f, &min_inline); |
611 | 617 | ||
612 | if (!err && esw->mode == SRIOV_OFFLOADS && | 618 | if (!err && (flow->flags & MLX5E_TC_FLOW_ESWITCH) && |
613 | rep->vport != FDB_UPLINK_VPORT) { | 619 | rep->vport != FDB_UPLINK_VPORT) { |
614 | if (min_inline > esw->offloads.inline_mode) { | 620 | if (min_inline > esw->offloads.inline_mode) { |
615 | netdev_warn(priv->netdev, | 621 | netdev_warn(priv->netdev, |
@@ -1132,23 +1138,19 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol, | |||
1132 | struct tc_cls_flower_offload *f) | 1138 | struct tc_cls_flower_offload *f) |
1133 | { | 1139 | { |
1134 | struct mlx5e_tc_table *tc = &priv->fs.tc; | 1140 | struct mlx5e_tc_table *tc = &priv->fs.tc; |
1135 | int err = 0; | 1141 | int err, attr_size = 0; |
1136 | bool fdb_flow = false; | ||
1137 | u32 flow_tag, action; | 1142 | u32 flow_tag, action; |
1138 | struct mlx5e_tc_flow *flow; | 1143 | struct mlx5e_tc_flow *flow; |
1139 | struct mlx5_flow_spec *spec; | 1144 | struct mlx5_flow_spec *spec; |
1140 | struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; | 1145 | struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; |
1146 | u8 flow_flags = 0; | ||
1141 | 1147 | ||
1142 | if (esw && esw->mode == SRIOV_OFFLOADS) | 1148 | if (esw && esw->mode == SRIOV_OFFLOADS) { |
1143 | fdb_flow = true; | 1149 | flow_flags = MLX5E_TC_FLOW_ESWITCH; |
1144 | 1150 | attr_size = sizeof(struct mlx5_esw_flow_attr); | |
1145 | if (fdb_flow) | 1151 | } |
1146 | flow = kzalloc(sizeof(*flow) + | ||
1147 | sizeof(struct mlx5_esw_flow_attr), | ||
1148 | GFP_KERNEL); | ||
1149 | else | ||
1150 | flow = kzalloc(sizeof(*flow), GFP_KERNEL); | ||
1151 | 1152 | ||
1153 | flow = kzalloc(sizeof(*flow) + attr_size, GFP_KERNEL); | ||
1152 | spec = mlx5_vzalloc(sizeof(*spec)); | 1154 | spec = mlx5_vzalloc(sizeof(*spec)); |
1153 | if (!spec || !flow) { | 1155 | if (!spec || !flow) { |
1154 | err = -ENOMEM; | 1156 | err = -ENOMEM; |
@@ -1156,12 +1158,13 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol, | |||
1156 | } | 1158 | } |
1157 | 1159 | ||
1158 | flow->cookie = f->cookie; | 1160 | flow->cookie = f->cookie; |
1161 | flow->flags = flow_flags; | ||
1159 | 1162 | ||
1160 | err = parse_cls_flower(priv, spec, f); | 1163 | err = parse_cls_flower(priv, flow, spec, f); |
1161 | if (err < 0) | 1164 | if (err < 0) |
1162 | goto err_free; | 1165 | goto err_free; |
1163 | 1166 | ||
1164 | if (fdb_flow) { | 1167 | if (flow->flags & MLX5E_TC_FLOW_ESWITCH) { |
1165 | flow->attr = (struct mlx5_esw_flow_attr *)(flow + 1); | 1168 | flow->attr = (struct mlx5_esw_flow_attr *)(flow + 1); |
1166 | err = parse_tc_fdb_actions(priv, f->exts, flow); | 1169 | err = parse_tc_fdb_actions(priv, f->exts, flow); |
1167 | if (err < 0) | 1170 | if (err < 0) |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 2478516a61e2..ded27bb9a3b6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | |||
@@ -1136,7 +1136,7 @@ static struct mlx5_flow_group *create_autogroup(struct mlx5_flow_table *ft, | |||
1136 | u32 *match_criteria) | 1136 | u32 *match_criteria) |
1137 | { | 1137 | { |
1138 | int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); | 1138 | int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); |
1139 | struct list_head *prev = ft->node.children.prev; | 1139 | struct list_head *prev = &ft->node.children; |
1140 | unsigned int candidate_index = 0; | 1140 | unsigned int candidate_index = 0; |
1141 | struct mlx5_flow_group *fg; | 1141 | struct mlx5_flow_group *fg; |
1142 | void *match_criteria_addr; | 1142 | void *match_criteria_addr; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index c4242a4e8130..e2bd600d19de 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c | |||
@@ -1352,6 +1352,7 @@ static int init_one(struct pci_dev *pdev, | |||
1352 | if (err) | 1352 | if (err) |
1353 | goto clean_load; | 1353 | goto clean_load; |
1354 | 1354 | ||
1355 | pci_save_state(pdev); | ||
1355 | return 0; | 1356 | return 0; |
1356 | 1357 | ||
1357 | clean_load: | 1358 | clean_load: |
@@ -1407,9 +1408,8 @@ static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev, | |||
1407 | 1408 | ||
1408 | mlx5_enter_error_state(dev); | 1409 | mlx5_enter_error_state(dev); |
1409 | mlx5_unload_one(dev, priv, false); | 1410 | mlx5_unload_one(dev, priv, false); |
1410 | /* In case of kernel call save the pci state and drain the health wq */ | 1411 | /* In case of kernel call drain the health wq */ |
1411 | if (state) { | 1412 | if (state) { |
1412 | pci_save_state(pdev); | ||
1413 | mlx5_drain_health_wq(dev); | 1413 | mlx5_drain_health_wq(dev); |
1414 | mlx5_pci_disable_device(dev); | 1414 | mlx5_pci_disable_device(dev); |
1415 | } | 1415 | } |
@@ -1461,6 +1461,7 @@ static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev) | |||
1461 | 1461 | ||
1462 | pci_set_master(pdev); | 1462 | pci_set_master(pdev); |
1463 | pci_restore_state(pdev); | 1463 | pci_restore_state(pdev); |
1464 | pci_save_state(pdev); | ||
1464 | 1465 | ||
1465 | if (wait_vital(pdev)) { | 1466 | if (wait_vital(pdev)) { |
1466 | dev_err(&pdev->dev, "%s: wait_vital timed out\n", __func__); | 1467 | dev_err(&pdev->dev, "%s: wait_vital timed out\n", __func__); |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index 0899e2d310e2..d9616daf8a70 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h | |||
@@ -769,7 +769,7 @@ static inline void mlxsw_reg_spvid_pack(char *payload, u8 local_port, u16 pvid) | |||
769 | #define MLXSW_REG_SPVM_ID 0x200F | 769 | #define MLXSW_REG_SPVM_ID 0x200F |
770 | #define MLXSW_REG_SPVM_BASE_LEN 0x04 /* base length, without records */ | 770 | #define MLXSW_REG_SPVM_BASE_LEN 0x04 /* base length, without records */ |
771 | #define MLXSW_REG_SPVM_REC_LEN 0x04 /* record length */ | 771 | #define MLXSW_REG_SPVM_REC_LEN 0x04 /* record length */ |
772 | #define MLXSW_REG_SPVM_REC_MAX_COUNT 256 | 772 | #define MLXSW_REG_SPVM_REC_MAX_COUNT 255 |
773 | #define MLXSW_REG_SPVM_LEN (MLXSW_REG_SPVM_BASE_LEN + \ | 773 | #define MLXSW_REG_SPVM_LEN (MLXSW_REG_SPVM_BASE_LEN + \ |
774 | MLXSW_REG_SPVM_REC_LEN * MLXSW_REG_SPVM_REC_MAX_COUNT) | 774 | MLXSW_REG_SPVM_REC_LEN * MLXSW_REG_SPVM_REC_MAX_COUNT) |
775 | 775 | ||
@@ -1702,7 +1702,7 @@ static inline void mlxsw_reg_sfmr_pack(char *payload, | |||
1702 | #define MLXSW_REG_SPVMLR_ID 0x2020 | 1702 | #define MLXSW_REG_SPVMLR_ID 0x2020 |
1703 | #define MLXSW_REG_SPVMLR_BASE_LEN 0x04 /* base length, without records */ | 1703 | #define MLXSW_REG_SPVMLR_BASE_LEN 0x04 /* base length, without records */ |
1704 | #define MLXSW_REG_SPVMLR_REC_LEN 0x04 /* record length */ | 1704 | #define MLXSW_REG_SPVMLR_REC_LEN 0x04 /* record length */ |
1705 | #define MLXSW_REG_SPVMLR_REC_MAX_COUNT 256 | 1705 | #define MLXSW_REG_SPVMLR_REC_MAX_COUNT 255 |
1706 | #define MLXSW_REG_SPVMLR_LEN (MLXSW_REG_SPVMLR_BASE_LEN + \ | 1706 | #define MLXSW_REG_SPVMLR_LEN (MLXSW_REG_SPVMLR_BASE_LEN + \ |
1707 | MLXSW_REG_SPVMLR_REC_LEN * \ | 1707 | MLXSW_REG_SPVMLR_REC_LEN * \ |
1708 | MLXSW_REG_SPVMLR_REC_MAX_COUNT) | 1708 | MLXSW_REG_SPVMLR_REC_MAX_COUNT) |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c index 22ab42925377..ae6cccc666e4 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c | |||
@@ -303,11 +303,11 @@ void mlxsw_sp_flower_destroy(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress, | |||
303 | ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, mlxsw_sp_port->dev, | 303 | ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, mlxsw_sp_port->dev, |
304 | ingress, | 304 | ingress, |
305 | MLXSW_SP_ACL_PROFILE_FLOWER); | 305 | MLXSW_SP_ACL_PROFILE_FLOWER); |
306 | if (WARN_ON(IS_ERR(ruleset))) | 306 | if (IS_ERR(ruleset)) |
307 | return; | 307 | return; |
308 | 308 | ||
309 | rule = mlxsw_sp_acl_rule_lookup(mlxsw_sp, ruleset, f->cookie); | 309 | rule = mlxsw_sp_acl_rule_lookup(mlxsw_sp, ruleset, f->cookie); |
310 | if (!WARN_ON(!rule)) { | 310 | if (rule) { |
311 | mlxsw_sp_acl_rule_del(mlxsw_sp, rule); | 311 | mlxsw_sp_acl_rule_del(mlxsw_sp, rule); |
312 | mlxsw_sp_acl_rule_destroy(mlxsw_sp, rule); | 312 | mlxsw_sp_acl_rule_destroy(mlxsw_sp, rule); |
313 | } | 313 | } |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c b/drivers/net/ethernet/qlogic/qed/qed_cxt.c index d42d03df751a..7e3a6fed3da6 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c +++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c | |||
@@ -422,8 +422,9 @@ static void qed_cxt_set_proto_cid_count(struct qed_hwfn *p_hwfn, | |||
422 | u32 page_sz = p_mgr->clients[ILT_CLI_CDUC].p_size.val; | 422 | u32 page_sz = p_mgr->clients[ILT_CLI_CDUC].p_size.val; |
423 | u32 cxt_size = CONN_CXT_SIZE(p_hwfn); | 423 | u32 cxt_size = CONN_CXT_SIZE(p_hwfn); |
424 | u32 elems_per_page = ILT_PAGE_IN_BYTES(page_sz) / cxt_size; | 424 | u32 elems_per_page = ILT_PAGE_IN_BYTES(page_sz) / cxt_size; |
425 | u32 align = elems_per_page * DQ_RANGE_ALIGN; | ||
425 | 426 | ||
426 | p_conn->cid_count = roundup(p_conn->cid_count, elems_per_page); | 427 | p_conn->cid_count = roundup(p_conn->cid_count, align); |
427 | } | 428 | } |
428 | } | 429 | } |
429 | 430 | ||
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index e2a081ceaf52..e518f914eab1 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c | |||
@@ -2389,9 +2389,8 @@ qed_chain_alloc_sanity_check(struct qed_dev *cdev, | |||
2389 | * size/capacity fields are of a u32 type. | 2389 | * size/capacity fields are of a u32 type. |
2390 | */ | 2390 | */ |
2391 | if ((cnt_type == QED_CHAIN_CNT_TYPE_U16 && | 2391 | if ((cnt_type == QED_CHAIN_CNT_TYPE_U16 && |
2392 | chain_size > 0x10000) || | 2392 | chain_size > ((u32)U16_MAX + 1)) || |
2393 | (cnt_type == QED_CHAIN_CNT_TYPE_U32 && | 2393 | (cnt_type == QED_CHAIN_CNT_TYPE_U32 && chain_size > U32_MAX)) { |
2394 | chain_size > 0x100000000ULL)) { | ||
2395 | DP_NOTICE(cdev, | 2394 | DP_NOTICE(cdev, |
2396 | "The actual chain size (0x%llx) is larger than the maximal possible value\n", | 2395 | "The actual chain size (0x%llx) is larger than the maximal possible value\n", |
2397 | chain_size); | 2396 | chain_size); |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_iscsi.c b/drivers/net/ethernet/qlogic/qed/qed_iscsi.c index 3a44d6b395fa..098766f7fe88 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_iscsi.c +++ b/drivers/net/ethernet/qlogic/qed/qed_iscsi.c | |||
@@ -190,6 +190,9 @@ qed_sp_iscsi_func_start(struct qed_hwfn *p_hwfn, | |||
190 | p_init->num_sq_pages_in_ring = p_params->num_sq_pages_in_ring; | 190 | p_init->num_sq_pages_in_ring = p_params->num_sq_pages_in_ring; |
191 | p_init->num_r2tq_pages_in_ring = p_params->num_r2tq_pages_in_ring; | 191 | p_init->num_r2tq_pages_in_ring = p_params->num_r2tq_pages_in_ring; |
192 | p_init->num_uhq_pages_in_ring = p_params->num_uhq_pages_in_ring; | 192 | p_init->num_uhq_pages_in_ring = p_params->num_uhq_pages_in_ring; |
193 | p_init->ooo_enable = p_params->ooo_enable; | ||
194 | p_init->ll2_rx_queue_id = p_hwfn->hw_info.resc_start[QED_LL2_QUEUE] + | ||
195 | p_params->ll2_ooo_queue_id; | ||
193 | p_init->func_params.log_page_size = p_params->log_page_size; | 196 | p_init->func_params.log_page_size = p_params->log_page_size; |
194 | val = p_params->num_tasks; | 197 | val = p_params->num_tasks; |
195 | p_init->func_params.num_tasks = cpu_to_le16(val); | 198 | p_init->func_params.num_tasks = cpu_to_le16(val); |
@@ -786,6 +789,23 @@ static void qed_iscsi_release_connection(struct qed_hwfn *p_hwfn, | |||
786 | spin_unlock_bh(&p_hwfn->p_iscsi_info->lock); | 789 | spin_unlock_bh(&p_hwfn->p_iscsi_info->lock); |
787 | } | 790 | } |
788 | 791 | ||
792 | void qed_iscsi_free_connection(struct qed_hwfn *p_hwfn, | ||
793 | struct qed_iscsi_conn *p_conn) | ||
794 | { | ||
795 | qed_chain_free(p_hwfn->cdev, &p_conn->xhq); | ||
796 | qed_chain_free(p_hwfn->cdev, &p_conn->uhq); | ||
797 | qed_chain_free(p_hwfn->cdev, &p_conn->r2tq); | ||
798 | dma_free_coherent(&p_hwfn->cdev->pdev->dev, | ||
799 | sizeof(struct tcp_upload_params), | ||
800 | p_conn->tcp_upload_params_virt_addr, | ||
801 | p_conn->tcp_upload_params_phys_addr); | ||
802 | dma_free_coherent(&p_hwfn->cdev->pdev->dev, | ||
803 | sizeof(struct scsi_terminate_extra_params), | ||
804 | p_conn->queue_cnts_virt_addr, | ||
805 | p_conn->queue_cnts_phys_addr); | ||
806 | kfree(p_conn); | ||
807 | } | ||
808 | |||
789 | struct qed_iscsi_info *qed_iscsi_alloc(struct qed_hwfn *p_hwfn) | 809 | struct qed_iscsi_info *qed_iscsi_alloc(struct qed_hwfn *p_hwfn) |
790 | { | 810 | { |
791 | struct qed_iscsi_info *p_iscsi_info; | 811 | struct qed_iscsi_info *p_iscsi_info; |
@@ -807,6 +827,17 @@ void qed_iscsi_setup(struct qed_hwfn *p_hwfn, | |||
807 | void qed_iscsi_free(struct qed_hwfn *p_hwfn, | 827 | void qed_iscsi_free(struct qed_hwfn *p_hwfn, |
808 | struct qed_iscsi_info *p_iscsi_info) | 828 | struct qed_iscsi_info *p_iscsi_info) |
809 | { | 829 | { |
830 | struct qed_iscsi_conn *p_conn = NULL; | ||
831 | |||
832 | while (!list_empty(&p_hwfn->p_iscsi_info->free_list)) { | ||
833 | p_conn = list_first_entry(&p_hwfn->p_iscsi_info->free_list, | ||
834 | struct qed_iscsi_conn, list_entry); | ||
835 | if (p_conn) { | ||
836 | list_del(&p_conn->list_entry); | ||
837 | qed_iscsi_free_connection(p_hwfn, p_conn); | ||
838 | } | ||
839 | } | ||
840 | |||
810 | kfree(p_iscsi_info); | 841 | kfree(p_iscsi_info); |
811 | } | 842 | } |
812 | 843 | ||
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c index 9a0b9af10a57..0d3cef409c96 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c +++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c | |||
@@ -211,6 +211,8 @@ static void qed_ll2b_complete_rx_packet(struct qed_hwfn *p_hwfn, | |||
211 | /* If need to reuse or there's no replacement buffer, repost this */ | 211 | /* If need to reuse or there's no replacement buffer, repost this */ |
212 | if (rc) | 212 | if (rc) |
213 | goto out_post; | 213 | goto out_post; |
214 | dma_unmap_single(&cdev->pdev->dev, buffer->phys_addr, | ||
215 | cdev->ll2->rx_size, DMA_FROM_DEVICE); | ||
214 | 216 | ||
215 | skb = build_skb(buffer->data, 0); | 217 | skb = build_skb(buffer->data, 0); |
216 | if (!skb) { | 218 | if (!skb) { |
@@ -474,7 +476,7 @@ qed_ll2_rxq_completion_gsi(struct qed_hwfn *p_hwfn, | |||
474 | static int qed_ll2_rxq_completion_reg(struct qed_hwfn *p_hwfn, | 476 | static int qed_ll2_rxq_completion_reg(struct qed_hwfn *p_hwfn, |
475 | struct qed_ll2_info *p_ll2_conn, | 477 | struct qed_ll2_info *p_ll2_conn, |
476 | union core_rx_cqe_union *p_cqe, | 478 | union core_rx_cqe_union *p_cqe, |
477 | unsigned long lock_flags, | 479 | unsigned long *p_lock_flags, |
478 | bool b_last_cqe) | 480 | bool b_last_cqe) |
479 | { | 481 | { |
480 | struct qed_ll2_rx_queue *p_rx = &p_ll2_conn->rx_queue; | 482 | struct qed_ll2_rx_queue *p_rx = &p_ll2_conn->rx_queue; |
@@ -495,10 +497,10 @@ static int qed_ll2_rxq_completion_reg(struct qed_hwfn *p_hwfn, | |||
495 | "Mismatch between active_descq and the LL2 Rx chain\n"); | 497 | "Mismatch between active_descq and the LL2 Rx chain\n"); |
496 | list_add_tail(&p_pkt->list_entry, &p_rx->free_descq); | 498 | list_add_tail(&p_pkt->list_entry, &p_rx->free_descq); |
497 | 499 | ||
498 | spin_unlock_irqrestore(&p_rx->lock, lock_flags); | 500 | spin_unlock_irqrestore(&p_rx->lock, *p_lock_flags); |
499 | qed_ll2b_complete_rx_packet(p_hwfn, p_ll2_conn->my_id, | 501 | qed_ll2b_complete_rx_packet(p_hwfn, p_ll2_conn->my_id, |
500 | p_pkt, &p_cqe->rx_cqe_fp, b_last_cqe); | 502 | p_pkt, &p_cqe->rx_cqe_fp, b_last_cqe); |
501 | spin_lock_irqsave(&p_rx->lock, lock_flags); | 503 | spin_lock_irqsave(&p_rx->lock, *p_lock_flags); |
502 | 504 | ||
503 | return 0; | 505 | return 0; |
504 | } | 506 | } |
@@ -538,7 +540,8 @@ static int qed_ll2_rxq_completion(struct qed_hwfn *p_hwfn, void *cookie) | |||
538 | break; | 540 | break; |
539 | case CORE_RX_CQE_TYPE_REGULAR: | 541 | case CORE_RX_CQE_TYPE_REGULAR: |
540 | rc = qed_ll2_rxq_completion_reg(p_hwfn, p_ll2_conn, | 542 | rc = qed_ll2_rxq_completion_reg(p_hwfn, p_ll2_conn, |
541 | cqe, flags, b_last_cqe); | 543 | cqe, &flags, |
544 | b_last_cqe); | ||
542 | break; | 545 | break; |
543 | default: | 546 | default: |
544 | rc = -EIO; | 547 | rc = -EIO; |
@@ -968,7 +971,7 @@ static int qed_ll2_start_ooo(struct qed_dev *cdev, | |||
968 | { | 971 | { |
969 | struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); | 972 | struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); |
970 | u8 *handle = &hwfn->pf_params.iscsi_pf_params.ll2_ooo_queue_id; | 973 | u8 *handle = &hwfn->pf_params.iscsi_pf_params.ll2_ooo_queue_id; |
971 | struct qed_ll2_conn ll2_info; | 974 | struct qed_ll2_conn ll2_info = { 0 }; |
972 | int rc; | 975 | int rc; |
973 | 976 | ||
974 | ll2_info.conn_type = QED_LL2_TYPE_ISCSI_OOO; | 977 | ll2_info.conn_type = QED_LL2_TYPE_ISCSI_OOO; |
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ooo.c b/drivers/net/ethernet/qlogic/qed/qed_ooo.c index 7d731c6cb892..378afce58b3f 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_ooo.c +++ b/drivers/net/ethernet/qlogic/qed/qed_ooo.c | |||
@@ -159,6 +159,8 @@ struct qed_ooo_info *qed_ooo_alloc(struct qed_hwfn *p_hwfn) | |||
159 | if (!p_ooo_info->ooo_history.p_cqes) | 159 | if (!p_ooo_info->ooo_history.p_cqes) |
160 | goto no_history_mem; | 160 | goto no_history_mem; |
161 | 161 | ||
162 | p_ooo_info->ooo_history.num_of_cqes = QED_MAX_NUM_OOO_HISTORY_ENTRIES; | ||
163 | |||
162 | return p_ooo_info; | 164 | return p_ooo_info; |
163 | 165 | ||
164 | no_history_mem: | 166 | no_history_mem: |
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 65077c77082a..91e9bd7159ab 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c | |||
@@ -1535,32 +1535,33 @@ static int smc_close(struct net_device *dev) | |||
1535 | * Ethtool support | 1535 | * Ethtool support |
1536 | */ | 1536 | */ |
1537 | static int | 1537 | static int |
1538 | smc_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) | 1538 | smc_ethtool_get_link_ksettings(struct net_device *dev, |
1539 | struct ethtool_link_ksettings *cmd) | ||
1539 | { | 1540 | { |
1540 | struct smc_local *lp = netdev_priv(dev); | 1541 | struct smc_local *lp = netdev_priv(dev); |
1541 | int ret; | 1542 | int ret; |
1542 | 1543 | ||
1543 | cmd->maxtxpkt = 1; | ||
1544 | cmd->maxrxpkt = 1; | ||
1545 | |||
1546 | if (lp->phy_type != 0) { | 1544 | if (lp->phy_type != 0) { |
1547 | spin_lock_irq(&lp->lock); | 1545 | spin_lock_irq(&lp->lock); |
1548 | ret = mii_ethtool_gset(&lp->mii, cmd); | 1546 | ret = mii_ethtool_get_link_ksettings(&lp->mii, cmd); |
1549 | spin_unlock_irq(&lp->lock); | 1547 | spin_unlock_irq(&lp->lock); |
1550 | } else { | 1548 | } else { |
1551 | cmd->supported = SUPPORTED_10baseT_Half | | 1549 | u32 supported = SUPPORTED_10baseT_Half | |
1552 | SUPPORTED_10baseT_Full | | 1550 | SUPPORTED_10baseT_Full | |
1553 | SUPPORTED_TP | SUPPORTED_AUI; | 1551 | SUPPORTED_TP | SUPPORTED_AUI; |
1554 | 1552 | ||
1555 | if (lp->ctl_rspeed == 10) | 1553 | if (lp->ctl_rspeed == 10) |
1556 | ethtool_cmd_speed_set(cmd, SPEED_10); | 1554 | cmd->base.speed = SPEED_10; |
1557 | else if (lp->ctl_rspeed == 100) | 1555 | else if (lp->ctl_rspeed == 100) |
1558 | ethtool_cmd_speed_set(cmd, SPEED_100); | 1556 | cmd->base.speed = SPEED_100; |
1557 | |||
1558 | cmd->base.autoneg = AUTONEG_DISABLE; | ||
1559 | cmd->base.port = 0; | ||
1560 | cmd->base.duplex = lp->tcr_cur_mode & TCR_SWFDUP ? | ||
1561 | DUPLEX_FULL : DUPLEX_HALF; | ||
1559 | 1562 | ||
1560 | cmd->autoneg = AUTONEG_DISABLE; | 1563 | ethtool_convert_legacy_u32_to_link_mode( |
1561 | cmd->transceiver = XCVR_INTERNAL; | 1564 | cmd->link_modes.supported, supported); |
1562 | cmd->port = 0; | ||
1563 | cmd->duplex = lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF; | ||
1564 | 1565 | ||
1565 | ret = 0; | 1566 | ret = 0; |
1566 | } | 1567 | } |
@@ -1569,24 +1570,26 @@ smc_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
1569 | } | 1570 | } |
1570 | 1571 | ||
1571 | static int | 1572 | static int |
1572 | smc_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd) | 1573 | smc_ethtool_set_link_ksettings(struct net_device *dev, |
1574 | const struct ethtool_link_ksettings *cmd) | ||
1573 | { | 1575 | { |
1574 | struct smc_local *lp = netdev_priv(dev); | 1576 | struct smc_local *lp = netdev_priv(dev); |
1575 | int ret; | 1577 | int ret; |
1576 | 1578 | ||
1577 | if (lp->phy_type != 0) { | 1579 | if (lp->phy_type != 0) { |
1578 | spin_lock_irq(&lp->lock); | 1580 | spin_lock_irq(&lp->lock); |
1579 | ret = mii_ethtool_sset(&lp->mii, cmd); | 1581 | ret = mii_ethtool_set_link_ksettings(&lp->mii, cmd); |
1580 | spin_unlock_irq(&lp->lock); | 1582 | spin_unlock_irq(&lp->lock); |
1581 | } else { | 1583 | } else { |
1582 | if (cmd->autoneg != AUTONEG_DISABLE || | 1584 | if (cmd->base.autoneg != AUTONEG_DISABLE || |
1583 | cmd->speed != SPEED_10 || | 1585 | cmd->base.speed != SPEED_10 || |
1584 | (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) || | 1586 | (cmd->base.duplex != DUPLEX_HALF && |
1585 | (cmd->port != PORT_TP && cmd->port != PORT_AUI)) | 1587 | cmd->base.duplex != DUPLEX_FULL) || |
1588 | (cmd->base.port != PORT_TP && cmd->base.port != PORT_AUI)) | ||
1586 | return -EINVAL; | 1589 | return -EINVAL; |
1587 | 1590 | ||
1588 | // lp->port = cmd->port; | 1591 | // lp->port = cmd->base.port; |
1589 | lp->ctl_rfduplx = cmd->duplex == DUPLEX_FULL; | 1592 | lp->ctl_rfduplx = cmd->base.duplex == DUPLEX_FULL; |
1590 | 1593 | ||
1591 | // if (netif_running(dev)) | 1594 | // if (netif_running(dev)) |
1592 | // smc_set_port(dev); | 1595 | // smc_set_port(dev); |
@@ -1744,8 +1747,6 @@ static int smc_ethtool_seteeprom(struct net_device *dev, | |||
1744 | 1747 | ||
1745 | 1748 | ||
1746 | static const struct ethtool_ops smc_ethtool_ops = { | 1749 | static const struct ethtool_ops smc_ethtool_ops = { |
1747 | .get_settings = smc_ethtool_getsettings, | ||
1748 | .set_settings = smc_ethtool_setsettings, | ||
1749 | .get_drvinfo = smc_ethtool_getdrvinfo, | 1750 | .get_drvinfo = smc_ethtool_getdrvinfo, |
1750 | 1751 | ||
1751 | .get_msglevel = smc_ethtool_getmsglevel, | 1752 | .get_msglevel = smc_ethtool_getmsglevel, |
@@ -1755,6 +1756,8 @@ static const struct ethtool_ops smc_ethtool_ops = { | |||
1755 | .get_eeprom_len = smc_ethtool_geteeprom_len, | 1756 | .get_eeprom_len = smc_ethtool_geteeprom_len, |
1756 | .get_eeprom = smc_ethtool_geteeprom, | 1757 | .get_eeprom = smc_ethtool_geteeprom, |
1757 | .set_eeprom = smc_ethtool_seteeprom, | 1758 | .set_eeprom = smc_ethtool_seteeprom, |
1759 | .get_link_ksettings = smc_ethtool_get_link_ksettings, | ||
1760 | .set_link_ksettings = smc_ethtool_set_link_ksettings, | ||
1758 | }; | 1761 | }; |
1759 | 1762 | ||
1760 | static const struct net_device_ops smc_netdev_ops = { | 1763 | static const struct net_device_ops smc_netdev_ops = { |
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index d3e73ac158ae..f9f3dba7a588 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h | |||
@@ -700,6 +700,8 @@ struct net_device_context { | |||
700 | 700 | ||
701 | u32 tx_checksum_mask; | 701 | u32 tx_checksum_mask; |
702 | 702 | ||
703 | u32 tx_send_table[VRSS_SEND_TAB_SIZE]; | ||
704 | |||
703 | /* Ethtool settings */ | 705 | /* Ethtool settings */ |
704 | u8 duplex; | 706 | u8 duplex; |
705 | u32 speed; | 707 | u32 speed; |
@@ -757,7 +759,6 @@ struct netvsc_device { | |||
757 | 759 | ||
758 | struct nvsp_message revoke_packet; | 760 | struct nvsp_message revoke_packet; |
759 | 761 | ||
760 | u32 send_table[VRSS_SEND_TAB_SIZE]; | ||
761 | u32 max_chn; | 762 | u32 max_chn; |
762 | u32 num_chn; | 763 | u32 num_chn; |
763 | spinlock_t sc_lock; /* Protects num_sc_offered variable */ | 764 | spinlock_t sc_lock; /* Protects num_sc_offered variable */ |
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index d35ebd993b38..4c1d8cca247b 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c | |||
@@ -1136,15 +1136,11 @@ static void netvsc_receive(struct net_device *ndev, | |||
1136 | static void netvsc_send_table(struct hv_device *hdev, | 1136 | static void netvsc_send_table(struct hv_device *hdev, |
1137 | struct nvsp_message *nvmsg) | 1137 | struct nvsp_message *nvmsg) |
1138 | { | 1138 | { |
1139 | struct netvsc_device *nvscdev; | ||
1140 | struct net_device *ndev = hv_get_drvdata(hdev); | 1139 | struct net_device *ndev = hv_get_drvdata(hdev); |
1140 | struct net_device_context *net_device_ctx = netdev_priv(ndev); | ||
1141 | int i; | 1141 | int i; |
1142 | u32 count, *tab; | 1142 | u32 count, *tab; |
1143 | 1143 | ||
1144 | nvscdev = get_outbound_net_device(hdev); | ||
1145 | if (!nvscdev) | ||
1146 | return; | ||
1147 | |||
1148 | count = nvmsg->msg.v5_msg.send_table.count; | 1144 | count = nvmsg->msg.v5_msg.send_table.count; |
1149 | if (count != VRSS_SEND_TAB_SIZE) { | 1145 | if (count != VRSS_SEND_TAB_SIZE) { |
1150 | netdev_err(ndev, "Received wrong send-table size:%u\n", count); | 1146 | netdev_err(ndev, "Received wrong send-table size:%u\n", count); |
@@ -1155,7 +1151,7 @@ static void netvsc_send_table(struct hv_device *hdev, | |||
1155 | nvmsg->msg.v5_msg.send_table.offset); | 1151 | nvmsg->msg.v5_msg.send_table.offset); |
1156 | 1152 | ||
1157 | for (i = 0; i < count; i++) | 1153 | for (i = 0; i < count; i++) |
1158 | nvscdev->send_table[i] = tab[i]; | 1154 | net_device_ctx->tx_send_table[i] = tab[i]; |
1159 | } | 1155 | } |
1160 | 1156 | ||
1161 | static void netvsc_send_vf(struct net_device_context *net_device_ctx, | 1157 | static void netvsc_send_vf(struct net_device_context *net_device_ctx, |
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index bc05c895d958..5ede87f30463 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
@@ -206,17 +206,15 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb, | |||
206 | void *accel_priv, select_queue_fallback_t fallback) | 206 | void *accel_priv, select_queue_fallback_t fallback) |
207 | { | 207 | { |
208 | struct net_device_context *net_device_ctx = netdev_priv(ndev); | 208 | struct net_device_context *net_device_ctx = netdev_priv(ndev); |
209 | struct netvsc_device *nvsc_dev = net_device_ctx->nvdev; | 209 | unsigned int num_tx_queues = ndev->real_num_tx_queues; |
210 | struct sock *sk = skb->sk; | 210 | struct sock *sk = skb->sk; |
211 | int q_idx = sk_tx_queue_get(sk); | 211 | int q_idx = sk_tx_queue_get(sk); |
212 | 212 | ||
213 | if (q_idx < 0 || skb->ooo_okay || | 213 | if (q_idx < 0 || skb->ooo_okay || q_idx >= num_tx_queues) { |
214 | q_idx >= ndev->real_num_tx_queues) { | ||
215 | u16 hash = __skb_tx_hash(ndev, skb, VRSS_SEND_TAB_SIZE); | 214 | u16 hash = __skb_tx_hash(ndev, skb, VRSS_SEND_TAB_SIZE); |
216 | int new_idx; | 215 | int new_idx; |
217 | 216 | ||
218 | new_idx = nvsc_dev->send_table[hash] | 217 | new_idx = net_device_ctx->tx_send_table[hash] % num_tx_queues; |
219 | % nvsc_dev->num_chn; | ||
220 | 218 | ||
221 | if (q_idx != new_idx && sk && | 219 | if (q_idx != new_idx && sk && |
222 | sk_fullsock(sk) && rcu_access_pointer(sk->sk_dst_cache)) | 220 | sk_fullsock(sk) && rcu_access_pointer(sk->sk_dst_cache)) |
@@ -225,9 +223,6 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb, | |||
225 | q_idx = new_idx; | 223 | q_idx = new_idx; |
226 | } | 224 | } |
227 | 225 | ||
228 | if (unlikely(!nvsc_dev->chan_table[q_idx].channel)) | ||
229 | q_idx = 0; | ||
230 | |||
231 | return q_idx; | 226 | return q_idx; |
232 | } | 227 | } |
233 | 228 | ||
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index f9d0fa315a47..272b051a0199 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c | |||
@@ -1883,17 +1883,6 @@ static int m88e1510_probe(struct phy_device *phydev) | |||
1883 | return m88e1510_hwmon_probe(phydev); | 1883 | return m88e1510_hwmon_probe(phydev); |
1884 | } | 1884 | } |
1885 | 1885 | ||
1886 | static void marvell_remove(struct phy_device *phydev) | ||
1887 | { | ||
1888 | #ifdef CONFIG_HWMON | ||
1889 | |||
1890 | struct marvell_priv *priv = phydev->priv; | ||
1891 | |||
1892 | if (priv && priv->hwmon_dev) | ||
1893 | hwmon_device_unregister(priv->hwmon_dev); | ||
1894 | #endif | ||
1895 | } | ||
1896 | |||
1897 | static struct phy_driver marvell_drivers[] = { | 1886 | static struct phy_driver marvell_drivers[] = { |
1898 | { | 1887 | { |
1899 | .phy_id = MARVELL_PHY_ID_88E1101, | 1888 | .phy_id = MARVELL_PHY_ID_88E1101, |
@@ -1974,7 +1963,6 @@ static struct phy_driver marvell_drivers[] = { | |||
1974 | .features = PHY_GBIT_FEATURES, | 1963 | .features = PHY_GBIT_FEATURES, |
1975 | .flags = PHY_HAS_INTERRUPT, | 1964 | .flags = PHY_HAS_INTERRUPT, |
1976 | .probe = &m88e1121_probe, | 1965 | .probe = &m88e1121_probe, |
1977 | .remove = &marvell_remove, | ||
1978 | .config_init = &m88e1121_config_init, | 1966 | .config_init = &m88e1121_config_init, |
1979 | .config_aneg = &m88e1121_config_aneg, | 1967 | .config_aneg = &m88e1121_config_aneg, |
1980 | .read_status = &marvell_read_status, | 1968 | .read_status = &marvell_read_status, |
@@ -2087,7 +2075,6 @@ static struct phy_driver marvell_drivers[] = { | |||
2087 | .features = PHY_GBIT_FEATURES | SUPPORTED_FIBRE, | 2075 | .features = PHY_GBIT_FEATURES | SUPPORTED_FIBRE, |
2088 | .flags = PHY_HAS_INTERRUPT, | 2076 | .flags = PHY_HAS_INTERRUPT, |
2089 | .probe = &m88e1510_probe, | 2077 | .probe = &m88e1510_probe, |
2090 | .remove = &marvell_remove, | ||
2091 | .config_init = &m88e1510_config_init, | 2078 | .config_init = &m88e1510_config_init, |
2092 | .config_aneg = &m88e1510_config_aneg, | 2079 | .config_aneg = &m88e1510_config_aneg, |
2093 | .read_status = &marvell_read_status, | 2080 | .read_status = &marvell_read_status, |
@@ -2109,7 +2096,6 @@ static struct phy_driver marvell_drivers[] = { | |||
2109 | .features = PHY_GBIT_FEATURES, | 2096 | .features = PHY_GBIT_FEATURES, |
2110 | .flags = PHY_HAS_INTERRUPT, | 2097 | .flags = PHY_HAS_INTERRUPT, |
2111 | .probe = m88e1510_probe, | 2098 | .probe = m88e1510_probe, |
2112 | .remove = &marvell_remove, | ||
2113 | .config_init = &marvell_config_init, | 2099 | .config_init = &marvell_config_init, |
2114 | .config_aneg = &m88e1510_config_aneg, | 2100 | .config_aneg = &m88e1510_config_aneg, |
2115 | .read_status = &marvell_read_status, | 2101 | .read_status = &marvell_read_status, |
@@ -2127,7 +2113,6 @@ static struct phy_driver marvell_drivers[] = { | |||
2127 | .phy_id_mask = MARVELL_PHY_ID_MASK, | 2113 | .phy_id_mask = MARVELL_PHY_ID_MASK, |
2128 | .name = "Marvell 88E1545", | 2114 | .name = "Marvell 88E1545", |
2129 | .probe = m88e1510_probe, | 2115 | .probe = m88e1510_probe, |
2130 | .remove = &marvell_remove, | ||
2131 | .features = PHY_GBIT_FEATURES, | 2116 | .features = PHY_GBIT_FEATURES, |
2132 | .flags = PHY_HAS_INTERRUPT, | 2117 | .flags = PHY_HAS_INTERRUPT, |
2133 | .config_init = &marvell_config_init, | 2118 | .config_init = &marvell_config_init, |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index daec6555f3b1..5198ccfa347f 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -1864,7 +1864,7 @@ static struct phy_driver genphy_driver[] = { | |||
1864 | .phy_id = 0xffffffff, | 1864 | .phy_id = 0xffffffff, |
1865 | .phy_id_mask = 0xffffffff, | 1865 | .phy_id_mask = 0xffffffff, |
1866 | .name = "Generic PHY", | 1866 | .name = "Generic PHY", |
1867 | .soft_reset = genphy_soft_reset, | 1867 | .soft_reset = genphy_no_soft_reset, |
1868 | .config_init = genphy_config_init, | 1868 | .config_init = genphy_config_init, |
1869 | .features = PHY_GBIT_FEATURES | SUPPORTED_MII | | 1869 | .features = PHY_GBIT_FEATURES | SUPPORTED_MII | |
1870 | SUPPORTED_AUI | SUPPORTED_FIBRE | | 1870 | SUPPORTED_AUI | SUPPORTED_FIBRE | |
diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c index 93ffedfa2994..1e2d4f1179da 100644 --- a/drivers/net/phy/spi_ks8995.c +++ b/drivers/net/phy/spi_ks8995.c | |||
@@ -491,13 +491,14 @@ static int ks8995_probe(struct spi_device *spi) | |||
491 | if (err) | 491 | if (err) |
492 | return err; | 492 | return err; |
493 | 493 | ||
494 | ks->regs_attr.size = ks->chip->regs_size; | ||
495 | memcpy(&ks->regs_attr, &ks8995_registers_attr, sizeof(ks->regs_attr)); | 494 | memcpy(&ks->regs_attr, &ks8995_registers_attr, sizeof(ks->regs_attr)); |
495 | ks->regs_attr.size = ks->chip->regs_size; | ||
496 | 496 | ||
497 | err = ks8995_reset(ks); | 497 | err = ks8995_reset(ks); |
498 | if (err) | 498 | if (err) |
499 | return err; | 499 | return err; |
500 | 500 | ||
501 | sysfs_attr_init(&ks->regs_attr.attr); | ||
501 | err = sysfs_create_bin_file(&spi->dev.kobj, &ks->regs_attr); | 502 | err = sysfs_create_bin_file(&spi->dev.kobj, &ks->regs_attr); |
502 | if (err) { | 503 | if (err) { |
503 | dev_err(&spi->dev, "unable to create sysfs file, err=%d\n", | 504 | dev_err(&spi->dev, "unable to create sysfs file, err=%d\n", |
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 4a24b5d15f5a..1b52520715ae 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
@@ -2072,6 +2072,7 @@ static int team_dev_type_check_change(struct net_device *dev, | |||
2072 | static void team_setup(struct net_device *dev) | 2072 | static void team_setup(struct net_device *dev) |
2073 | { | 2073 | { |
2074 | ether_setup(dev); | 2074 | ether_setup(dev); |
2075 | dev->max_mtu = ETH_MAX_MTU; | ||
2075 | 2076 | ||
2076 | dev->netdev_ops = &team_netdev_ops; | 2077 | dev->netdev_ops = &team_netdev_ops; |
2077 | dev->ethtool_ops = &team_ethtool_ops; | 2078 | dev->ethtool_ops = &team_ethtool_ops; |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index dc1b1dd9157c..34cc3c590aa5 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -822,7 +822,18 @@ static void tun_net_uninit(struct net_device *dev) | |||
822 | /* Net device open. */ | 822 | /* Net device open. */ |
823 | static int tun_net_open(struct net_device *dev) | 823 | static int tun_net_open(struct net_device *dev) |
824 | { | 824 | { |
825 | struct tun_struct *tun = netdev_priv(dev); | ||
826 | int i; | ||
827 | |||
825 | netif_tx_start_all_queues(dev); | 828 | netif_tx_start_all_queues(dev); |
829 | |||
830 | for (i = 0; i < tun->numqueues; i++) { | ||
831 | struct tun_file *tfile; | ||
832 | |||
833 | tfile = rtnl_dereference(tun->tfiles[i]); | ||
834 | tfile->socket.sk->sk_write_space(tfile->socket.sk); | ||
835 | } | ||
836 | |||
826 | return 0; | 837 | return 0; |
827 | } | 838 | } |
828 | 839 | ||
@@ -1103,9 +1114,10 @@ static unsigned int tun_chr_poll(struct file *file, poll_table *wait) | |||
1103 | if (!skb_array_empty(&tfile->tx_array)) | 1114 | if (!skb_array_empty(&tfile->tx_array)) |
1104 | mask |= POLLIN | POLLRDNORM; | 1115 | mask |= POLLIN | POLLRDNORM; |
1105 | 1116 | ||
1106 | if (sock_writeable(sk) || | 1117 | if (tun->dev->flags & IFF_UP && |
1107 | (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) && | 1118 | (sock_writeable(sk) || |
1108 | sock_writeable(sk))) | 1119 | (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) && |
1120 | sock_writeable(sk)))) | ||
1109 | mask |= POLLOUT | POLLWRNORM; | 1121 | mask |= POLLOUT | POLLWRNORM; |
1110 | 1122 | ||
1111 | if (tun->dev->reg_state != NETREG_REGISTERED) | 1123 | if (tun->dev->reg_state != NETREG_REGISTERED) |
@@ -2570,7 +2582,6 @@ static int __init tun_init(void) | |||
2570 | int ret = 0; | 2582 | int ret = 0; |
2571 | 2583 | ||
2572 | pr_info("%s, %s\n", DRV_DESCRIPTION, DRV_VERSION); | 2584 | pr_info("%s, %s\n", DRV_DESCRIPTION, DRV_VERSION); |
2573 | pr_info("%s\n", DRV_COPYRIGHT); | ||
2574 | 2585 | ||
2575 | ret = rtnl_link_register(&tun_link_ops); | 2586 | ret = rtnl_link_register(&tun_link_ops); |
2576 | if (ret) { | 2587 | if (ret) { |
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index 22379da63400..fea687f35b5a 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c | |||
@@ -340,6 +340,7 @@ static netdev_tx_t is_ip_tx_frame(struct sk_buff *skb, struct net_device *dev) | |||
340 | 340 | ||
341 | static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev) | 341 | static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev) |
342 | { | 342 | { |
343 | int len = skb->len; | ||
343 | netdev_tx_t ret = is_ip_tx_frame(skb, dev); | 344 | netdev_tx_t ret = is_ip_tx_frame(skb, dev); |
344 | 345 | ||
345 | if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { | 346 | if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { |
@@ -347,7 +348,7 @@ static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev) | |||
347 | 348 | ||
348 | u64_stats_update_begin(&dstats->syncp); | 349 | u64_stats_update_begin(&dstats->syncp); |
349 | dstats->tx_pkts++; | 350 | dstats->tx_pkts++; |
350 | dstats->tx_bytes += skb->len; | 351 | dstats->tx_bytes += len; |
351 | u64_stats_update_end(&dstats->syncp); | 352 | u64_stats_update_end(&dstats->syncp); |
352 | } else { | 353 | } else { |
353 | this_cpu_inc(dev->dstats->tx_drps); | 354 | this_cpu_inc(dev->dstats->tx_drps); |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index e375560cc74e..bdb6ae16d4a8 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -2976,6 +2976,44 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev, | |||
2976 | return 0; | 2976 | return 0; |
2977 | } | 2977 | } |
2978 | 2978 | ||
2979 | static int __vxlan_dev_create(struct net *net, struct net_device *dev, | ||
2980 | struct vxlan_config *conf) | ||
2981 | { | ||
2982 | struct vxlan_net *vn = net_generic(net, vxlan_net_id); | ||
2983 | struct vxlan_dev *vxlan = netdev_priv(dev); | ||
2984 | int err; | ||
2985 | |||
2986 | err = vxlan_dev_configure(net, dev, conf, false); | ||
2987 | if (err) | ||
2988 | return err; | ||
2989 | |||
2990 | dev->ethtool_ops = &vxlan_ethtool_ops; | ||
2991 | |||
2992 | /* create an fdb entry for a valid default destination */ | ||
2993 | if (!vxlan_addr_any(&vxlan->default_dst.remote_ip)) { | ||
2994 | err = vxlan_fdb_create(vxlan, all_zeros_mac, | ||
2995 | &vxlan->default_dst.remote_ip, | ||
2996 | NUD_REACHABLE | NUD_PERMANENT, | ||
2997 | NLM_F_EXCL | NLM_F_CREATE, | ||
2998 | vxlan->cfg.dst_port, | ||
2999 | vxlan->default_dst.remote_vni, | ||
3000 | vxlan->default_dst.remote_vni, | ||
3001 | vxlan->default_dst.remote_ifindex, | ||
3002 | NTF_SELF); | ||
3003 | if (err) | ||
3004 | return err; | ||
3005 | } | ||
3006 | |||
3007 | err = register_netdevice(dev); | ||
3008 | if (err) { | ||
3009 | vxlan_fdb_delete_default(vxlan, vxlan->default_dst.remote_vni); | ||
3010 | return err; | ||
3011 | } | ||
3012 | |||
3013 | list_add(&vxlan->next, &vn->vxlan_list); | ||
3014 | return 0; | ||
3015 | } | ||
3016 | |||
2979 | static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[], | 3017 | static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[], |
2980 | struct net_device *dev, struct vxlan_config *conf, | 3018 | struct net_device *dev, struct vxlan_config *conf, |
2981 | bool changelink) | 3019 | bool changelink) |
@@ -3172,8 +3210,6 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct nlattr *data[], | |||
3172 | static int vxlan_newlink(struct net *src_net, struct net_device *dev, | 3210 | static int vxlan_newlink(struct net *src_net, struct net_device *dev, |
3173 | struct nlattr *tb[], struct nlattr *data[]) | 3211 | struct nlattr *tb[], struct nlattr *data[]) |
3174 | { | 3212 | { |
3175 | struct vxlan_net *vn = net_generic(src_net, vxlan_net_id); | ||
3176 | struct vxlan_dev *vxlan = netdev_priv(dev); | ||
3177 | struct vxlan_config conf; | 3213 | struct vxlan_config conf; |
3178 | int err; | 3214 | int err; |
3179 | 3215 | ||
@@ -3181,36 +3217,7 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev, | |||
3181 | if (err) | 3217 | if (err) |
3182 | return err; | 3218 | return err; |
3183 | 3219 | ||
3184 | err = vxlan_dev_configure(src_net, dev, &conf, false); | 3220 | return __vxlan_dev_create(src_net, dev, &conf); |
3185 | if (err) | ||
3186 | return err; | ||
3187 | |||
3188 | dev->ethtool_ops = &vxlan_ethtool_ops; | ||
3189 | |||
3190 | /* create an fdb entry for a valid default destination */ | ||
3191 | if (!vxlan_addr_any(&vxlan->default_dst.remote_ip)) { | ||
3192 | err = vxlan_fdb_create(vxlan, all_zeros_mac, | ||
3193 | &vxlan->default_dst.remote_ip, | ||
3194 | NUD_REACHABLE | NUD_PERMANENT, | ||
3195 | NLM_F_EXCL | NLM_F_CREATE, | ||
3196 | vxlan->cfg.dst_port, | ||
3197 | vxlan->default_dst.remote_vni, | ||
3198 | vxlan->default_dst.remote_vni, | ||
3199 | vxlan->default_dst.remote_ifindex, | ||
3200 | NTF_SELF); | ||
3201 | if (err) | ||
3202 | return err; | ||
3203 | } | ||
3204 | |||
3205 | err = register_netdevice(dev); | ||
3206 | if (err) { | ||
3207 | vxlan_fdb_delete_default(vxlan, vxlan->default_dst.remote_vni); | ||
3208 | return err; | ||
3209 | } | ||
3210 | |||
3211 | list_add(&vxlan->next, &vn->vxlan_list); | ||
3212 | |||
3213 | return 0; | ||
3214 | } | 3221 | } |
3215 | 3222 | ||
3216 | static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], | 3223 | static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], |
@@ -3440,7 +3447,7 @@ struct net_device *vxlan_dev_create(struct net *net, const char *name, | |||
3440 | if (IS_ERR(dev)) | 3447 | if (IS_ERR(dev)) |
3441 | return dev; | 3448 | return dev; |
3442 | 3449 | ||
3443 | err = vxlan_dev_configure(net, dev, conf, false); | 3450 | err = __vxlan_dev_create(net, dev, conf); |
3444 | if (err < 0) { | 3451 | if (err < 0) { |
3445 | free_netdev(dev); | 3452 | free_netdev(dev); |
3446 | return ERR_PTR(err); | 3453 | return ERR_PTR(err); |
diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c index a5045b5279d7..6742ae605660 100644 --- a/drivers/net/wan/fsl_ucc_hdlc.c +++ b/drivers/net/wan/fsl_ucc_hdlc.c | |||
@@ -381,8 +381,8 @@ static netdev_tx_t ucc_hdlc_tx(struct sk_buff *skb, struct net_device *dev) | |||
381 | /* set bd status and length */ | 381 | /* set bd status and length */ |
382 | bd_status = (bd_status & T_W_S) | T_R_S | T_I_S | T_L_S | T_TC_S; | 382 | bd_status = (bd_status & T_W_S) | T_R_S | T_I_S | T_L_S | T_TC_S; |
383 | 383 | ||
384 | iowrite16be(bd_status, &bd->status); | ||
385 | iowrite16be(skb->len, &bd->length); | 384 | iowrite16be(skb->len, &bd->length); |
385 | iowrite16be(bd_status, &bd->status); | ||
386 | 386 | ||
387 | /* Move to next BD in the ring */ | 387 | /* Move to next BD in the ring */ |
388 | if (!(bd_status & T_W_S)) | 388 | if (!(bd_status & T_W_S)) |
@@ -457,7 +457,7 @@ static int hdlc_rx_done(struct ucc_hdlc_private *priv, int rx_work_limit) | |||
457 | struct sk_buff *skb; | 457 | struct sk_buff *skb; |
458 | hdlc_device *hdlc = dev_to_hdlc(dev); | 458 | hdlc_device *hdlc = dev_to_hdlc(dev); |
459 | struct qe_bd *bd; | 459 | struct qe_bd *bd; |
460 | u32 bd_status; | 460 | u16 bd_status; |
461 | u16 length, howmany = 0; | 461 | u16 length, howmany = 0; |
462 | u8 *bdbuffer; | 462 | u8 *bdbuffer; |
463 | int i; | 463 | int i; |
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c index e7f5910a6519..f8eb66ef2944 100644 --- a/drivers/net/wimax/i2400m/usb.c +++ b/drivers/net/wimax/i2400m/usb.c | |||
@@ -467,6 +467,9 @@ int i2400mu_probe(struct usb_interface *iface, | |||
467 | struct i2400mu *i2400mu; | 467 | struct i2400mu *i2400mu; |
468 | struct usb_device *usb_dev = interface_to_usbdev(iface); | 468 | struct usb_device *usb_dev = interface_to_usbdev(iface); |
469 | 469 | ||
470 | if (iface->cur_altsetting->desc.bNumEndpoints < 4) | ||
471 | return -ENODEV; | ||
472 | |||
470 | if (usb_dev->speed != USB_SPEED_HIGH) | 473 | if (usb_dev->speed != USB_SPEED_HIGH) |
471 | dev_err(dev, "device not connected as high speed\n"); | 474 | dev_err(dev, "device not connected as high speed\n"); |
472 | 475 | ||
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 829b26cd4549..8397f6c92451 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
@@ -165,13 +165,17 @@ static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
165 | { | 165 | { |
166 | struct xenvif *vif = netdev_priv(dev); | 166 | struct xenvif *vif = netdev_priv(dev); |
167 | struct xenvif_queue *queue = NULL; | 167 | struct xenvif_queue *queue = NULL; |
168 | unsigned int num_queues = vif->num_queues; | 168 | unsigned int num_queues; |
169 | u16 index; | 169 | u16 index; |
170 | struct xenvif_rx_cb *cb; | 170 | struct xenvif_rx_cb *cb; |
171 | 171 | ||
172 | BUG_ON(skb->dev != dev); | 172 | BUG_ON(skb->dev != dev); |
173 | 173 | ||
174 | /* Drop the packet if queues are not set up */ | 174 | /* Drop the packet if queues are not set up. |
175 | * This handler should be called inside an RCU read section | ||
176 | * so we don't need to enter it here explicitly. | ||
177 | */ | ||
178 | num_queues = READ_ONCE(vif->num_queues); | ||
175 | if (num_queues < 1) | 179 | if (num_queues < 1) |
176 | goto drop; | 180 | goto drop; |
177 | 181 | ||
@@ -222,18 +226,18 @@ static struct net_device_stats *xenvif_get_stats(struct net_device *dev) | |||
222 | { | 226 | { |
223 | struct xenvif *vif = netdev_priv(dev); | 227 | struct xenvif *vif = netdev_priv(dev); |
224 | struct xenvif_queue *queue = NULL; | 228 | struct xenvif_queue *queue = NULL; |
229 | unsigned int num_queues; | ||
225 | u64 rx_bytes = 0; | 230 | u64 rx_bytes = 0; |
226 | u64 rx_packets = 0; | 231 | u64 rx_packets = 0; |
227 | u64 tx_bytes = 0; | 232 | u64 tx_bytes = 0; |
228 | u64 tx_packets = 0; | 233 | u64 tx_packets = 0; |
229 | unsigned int index; | 234 | unsigned int index; |
230 | 235 | ||
231 | spin_lock(&vif->lock); | 236 | rcu_read_lock(); |
232 | if (vif->queues == NULL) | 237 | num_queues = READ_ONCE(vif->num_queues); |
233 | goto out; | ||
234 | 238 | ||
235 | /* Aggregate tx and rx stats from each queue */ | 239 | /* Aggregate tx and rx stats from each queue */ |
236 | for (index = 0; index < vif->num_queues; ++index) { | 240 | for (index = 0; index < num_queues; ++index) { |
237 | queue = &vif->queues[index]; | 241 | queue = &vif->queues[index]; |
238 | rx_bytes += queue->stats.rx_bytes; | 242 | rx_bytes += queue->stats.rx_bytes; |
239 | rx_packets += queue->stats.rx_packets; | 243 | rx_packets += queue->stats.rx_packets; |
@@ -241,8 +245,7 @@ static struct net_device_stats *xenvif_get_stats(struct net_device *dev) | |||
241 | tx_packets += queue->stats.tx_packets; | 245 | tx_packets += queue->stats.tx_packets; |
242 | } | 246 | } |
243 | 247 | ||
244 | out: | 248 | rcu_read_unlock(); |
245 | spin_unlock(&vif->lock); | ||
246 | 249 | ||
247 | vif->dev->stats.rx_bytes = rx_bytes; | 250 | vif->dev->stats.rx_bytes = rx_bytes; |
248 | vif->dev->stats.rx_packets = rx_packets; | 251 | vif->dev->stats.rx_packets = rx_packets; |
@@ -378,10 +381,13 @@ static void xenvif_get_ethtool_stats(struct net_device *dev, | |||
378 | struct ethtool_stats *stats, u64 * data) | 381 | struct ethtool_stats *stats, u64 * data) |
379 | { | 382 | { |
380 | struct xenvif *vif = netdev_priv(dev); | 383 | struct xenvif *vif = netdev_priv(dev); |
381 | unsigned int num_queues = vif->num_queues; | 384 | unsigned int num_queues; |
382 | int i; | 385 | int i; |
383 | unsigned int queue_index; | 386 | unsigned int queue_index; |
384 | 387 | ||
388 | rcu_read_lock(); | ||
389 | num_queues = READ_ONCE(vif->num_queues); | ||
390 | |||
385 | for (i = 0; i < ARRAY_SIZE(xenvif_stats); i++) { | 391 | for (i = 0; i < ARRAY_SIZE(xenvif_stats); i++) { |
386 | unsigned long accum = 0; | 392 | unsigned long accum = 0; |
387 | for (queue_index = 0; queue_index < num_queues; ++queue_index) { | 393 | for (queue_index = 0; queue_index < num_queues; ++queue_index) { |
@@ -390,6 +396,8 @@ static void xenvif_get_ethtool_stats(struct net_device *dev, | |||
390 | } | 396 | } |
391 | data[i] = accum; | 397 | data[i] = accum; |
392 | } | 398 | } |
399 | |||
400 | rcu_read_unlock(); | ||
393 | } | 401 | } |
394 | 402 | ||
395 | static void xenvif_get_strings(struct net_device *dev, u32 stringset, u8 * data) | 403 | static void xenvif_get_strings(struct net_device *dev, u32 stringset, u8 * data) |
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index f9bcf4a665bc..602d408fa25e 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
@@ -214,7 +214,7 @@ static void xenvif_fatal_tx_err(struct xenvif *vif) | |||
214 | netdev_err(vif->dev, "fatal error; disabling device\n"); | 214 | netdev_err(vif->dev, "fatal error; disabling device\n"); |
215 | vif->disabled = true; | 215 | vif->disabled = true; |
216 | /* Disable the vif from queue 0's kthread */ | 216 | /* Disable the vif from queue 0's kthread */ |
217 | if (vif->queues) | 217 | if (vif->num_queues) |
218 | xenvif_kick_thread(&vif->queues[0]); | 218 | xenvif_kick_thread(&vif->queues[0]); |
219 | } | 219 | } |
220 | 220 | ||
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index d2d7cd9145b1..a56d3eab35dd 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c | |||
@@ -495,26 +495,26 @@ static void backend_disconnect(struct backend_info *be) | |||
495 | struct xenvif *vif = be->vif; | 495 | struct xenvif *vif = be->vif; |
496 | 496 | ||
497 | if (vif) { | 497 | if (vif) { |
498 | unsigned int num_queues = vif->num_queues; | ||
498 | unsigned int queue_index; | 499 | unsigned int queue_index; |
499 | struct xenvif_queue *queues; | ||
500 | 500 | ||
501 | xen_unregister_watchers(vif); | 501 | xen_unregister_watchers(vif); |
502 | #ifdef CONFIG_DEBUG_FS | 502 | #ifdef CONFIG_DEBUG_FS |
503 | xenvif_debugfs_delif(vif); | 503 | xenvif_debugfs_delif(vif); |
504 | #endif /* CONFIG_DEBUG_FS */ | 504 | #endif /* CONFIG_DEBUG_FS */ |
505 | xenvif_disconnect_data(vif); | 505 | xenvif_disconnect_data(vif); |
506 | for (queue_index = 0; | ||
507 | queue_index < vif->num_queues; | ||
508 | ++queue_index) | ||
509 | xenvif_deinit_queue(&vif->queues[queue_index]); | ||
510 | 506 | ||
511 | spin_lock(&vif->lock); | 507 | /* At this point some of the handlers may still be active |
512 | queues = vif->queues; | 508 | * so we need to have additional synchronization here. |
509 | */ | ||
513 | vif->num_queues = 0; | 510 | vif->num_queues = 0; |
514 | vif->queues = NULL; | 511 | synchronize_net(); |
515 | spin_unlock(&vif->lock); | ||
516 | 512 | ||
517 | vfree(queues); | 513 | for (queue_index = 0; queue_index < num_queues; ++queue_index) |
514 | xenvif_deinit_queue(&vif->queues[queue_index]); | ||
515 | |||
516 | vfree(vif->queues); | ||
517 | vif->queues = NULL; | ||
518 | 518 | ||
519 | xenvif_disconnect_ctrl(vif); | 519 | xenvif_disconnect_ctrl(vif); |
520 | } | 520 | } |
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index 5be4783e40d4..dea98ffb6f60 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c | |||
@@ -103,15 +103,6 @@ static struct quirk_entry quirk_asus_x200ca = { | |||
103 | .wapf = 2, | 103 | .wapf = 2, |
104 | }; | 104 | }; |
105 | 105 | ||
106 | static struct quirk_entry quirk_no_rfkill = { | ||
107 | .no_rfkill = true, | ||
108 | }; | ||
109 | |||
110 | static struct quirk_entry quirk_no_rfkill_wapf4 = { | ||
111 | .wapf = 4, | ||
112 | .no_rfkill = true, | ||
113 | }; | ||
114 | |||
115 | static struct quirk_entry quirk_asus_ux303ub = { | 106 | static struct quirk_entry quirk_asus_ux303ub = { |
116 | .wmi_backlight_native = true, | 107 | .wmi_backlight_native = true, |
117 | }; | 108 | }; |
@@ -194,7 +185,7 @@ static const struct dmi_system_id asus_quirks[] = { | |||
194 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 185 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
195 | DMI_MATCH(DMI_PRODUCT_NAME, "X456UA"), | 186 | DMI_MATCH(DMI_PRODUCT_NAME, "X456UA"), |
196 | }, | 187 | }, |
197 | .driver_data = &quirk_no_rfkill_wapf4, | 188 | .driver_data = &quirk_asus_wapf4, |
198 | }, | 189 | }, |
199 | { | 190 | { |
200 | .callback = dmi_matched, | 191 | .callback = dmi_matched, |
@@ -203,7 +194,7 @@ static const struct dmi_system_id asus_quirks[] = { | |||
203 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 194 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
204 | DMI_MATCH(DMI_PRODUCT_NAME, "X456UF"), | 195 | DMI_MATCH(DMI_PRODUCT_NAME, "X456UF"), |
205 | }, | 196 | }, |
206 | .driver_data = &quirk_no_rfkill_wapf4, | 197 | .driver_data = &quirk_asus_wapf4, |
207 | }, | 198 | }, |
208 | { | 199 | { |
209 | .callback = dmi_matched, | 200 | .callback = dmi_matched, |
@@ -369,42 +360,6 @@ static const struct dmi_system_id asus_quirks[] = { | |||
369 | }, | 360 | }, |
370 | { | 361 | { |
371 | .callback = dmi_matched, | 362 | .callback = dmi_matched, |
372 | .ident = "ASUSTeK COMPUTER INC. X555UB", | ||
373 | .matches = { | ||
374 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
375 | DMI_MATCH(DMI_PRODUCT_NAME, "X555UB"), | ||
376 | }, | ||
377 | .driver_data = &quirk_no_rfkill, | ||
378 | }, | ||
379 | { | ||
380 | .callback = dmi_matched, | ||
381 | .ident = "ASUSTeK COMPUTER INC. N552VW", | ||
382 | .matches = { | ||
383 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
384 | DMI_MATCH(DMI_PRODUCT_NAME, "N552VW"), | ||
385 | }, | ||
386 | .driver_data = &quirk_no_rfkill, | ||
387 | }, | ||
388 | { | ||
389 | .callback = dmi_matched, | ||
390 | .ident = "ASUSTeK COMPUTER INC. U303LB", | ||
391 | .matches = { | ||
392 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
393 | DMI_MATCH(DMI_PRODUCT_NAME, "U303LB"), | ||
394 | }, | ||
395 | .driver_data = &quirk_no_rfkill, | ||
396 | }, | ||
397 | { | ||
398 | .callback = dmi_matched, | ||
399 | .ident = "ASUSTeK COMPUTER INC. Z550MA", | ||
400 | .matches = { | ||
401 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
402 | DMI_MATCH(DMI_PRODUCT_NAME, "Z550MA"), | ||
403 | }, | ||
404 | .driver_data = &quirk_no_rfkill, | ||
405 | }, | ||
406 | { | ||
407 | .callback = dmi_matched, | ||
408 | .ident = "ASUSTeK COMPUTER INC. UX303UB", | 363 | .ident = "ASUSTeK COMPUTER INC. UX303UB", |
409 | .matches = { | 364 | .matches = { |
410 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 365 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 43cb680adbb4..8fe5890bf539 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
@@ -159,6 +159,8 @@ MODULE_LICENSE("GPL"); | |||
159 | #define USB_INTEL_XUSB2PR 0xD0 | 159 | #define USB_INTEL_XUSB2PR 0xD0 |
160 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 | 160 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 |
161 | 161 | ||
162 | static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL }; | ||
163 | |||
162 | struct bios_args { | 164 | struct bios_args { |
163 | u32 arg0; | 165 | u32 arg0; |
164 | u32 arg1; | 166 | u32 arg1; |
@@ -2051,6 +2053,16 @@ static int asus_wmi_fan_init(struct asus_wmi *asus) | |||
2051 | return 0; | 2053 | return 0; |
2052 | } | 2054 | } |
2053 | 2055 | ||
2056 | static bool ashs_present(void) | ||
2057 | { | ||
2058 | int i = 0; | ||
2059 | while (ashs_ids[i]) { | ||
2060 | if (acpi_dev_found(ashs_ids[i++])) | ||
2061 | return true; | ||
2062 | } | ||
2063 | return false; | ||
2064 | } | ||
2065 | |||
2054 | /* | 2066 | /* |
2055 | * WMI Driver | 2067 | * WMI Driver |
2056 | */ | 2068 | */ |
@@ -2095,7 +2107,11 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
2095 | if (err) | 2107 | if (err) |
2096 | goto fail_leds; | 2108 | goto fail_leds; |
2097 | 2109 | ||
2098 | if (!asus->driver->quirks->no_rfkill) { | 2110 | asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); |
2111 | if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) | ||
2112 | asus->driver->wlan_ctrl_by_user = 1; | ||
2113 | |||
2114 | if (!(asus->driver->wlan_ctrl_by_user && ashs_present())) { | ||
2099 | err = asus_wmi_rfkill_init(asus); | 2115 | err = asus_wmi_rfkill_init(asus); |
2100 | if (err) | 2116 | if (err) |
2101 | goto fail_rfkill; | 2117 | goto fail_rfkill; |
@@ -2134,10 +2150,6 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
2134 | if (err) | 2150 | if (err) |
2135 | goto fail_debugfs; | 2151 | goto fail_debugfs; |
2136 | 2152 | ||
2137 | asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); | ||
2138 | if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) | ||
2139 | asus->driver->wlan_ctrl_by_user = 1; | ||
2140 | |||
2141 | return 0; | 2153 | return 0; |
2142 | 2154 | ||
2143 | fail_debugfs: | 2155 | fail_debugfs: |
diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h index fdff626c3b51..c9589d9342bb 100644 --- a/drivers/platform/x86/asus-wmi.h +++ b/drivers/platform/x86/asus-wmi.h | |||
@@ -39,7 +39,6 @@ struct key_entry; | |||
39 | struct asus_wmi; | 39 | struct asus_wmi; |
40 | 40 | ||
41 | struct quirk_entry { | 41 | struct quirk_entry { |
42 | bool no_rfkill; | ||
43 | bool hotplug_wireless; | 42 | bool hotplug_wireless; |
44 | bool scalar_panel_brightness; | 43 | bool scalar_panel_brightness; |
45 | bool store_backlight_power; | 44 | bool store_backlight_power; |
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 2b218b1d13e5..e12cc3504d48 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c | |||
@@ -78,18 +78,18 @@ | |||
78 | 78 | ||
79 | #define FUJITSU_LCD_N_LEVELS 8 | 79 | #define FUJITSU_LCD_N_LEVELS 8 |
80 | 80 | ||
81 | #define ACPI_FUJITSU_CLASS "fujitsu" | 81 | #define ACPI_FUJITSU_CLASS "fujitsu" |
82 | #define ACPI_FUJITSU_HID "FUJ02B1" | 82 | #define ACPI_FUJITSU_BL_HID "FUJ02B1" |
83 | #define ACPI_FUJITSU_DRIVER_NAME "Fujitsu laptop FUJ02B1 ACPI brightness driver" | 83 | #define ACPI_FUJITSU_BL_DRIVER_NAME "Fujitsu laptop FUJ02B1 ACPI brightness driver" |
84 | #define ACPI_FUJITSU_DEVICE_NAME "Fujitsu FUJ02B1" | 84 | #define ACPI_FUJITSU_BL_DEVICE_NAME "Fujitsu FUJ02B1" |
85 | #define ACPI_FUJITSU_HOTKEY_HID "FUJ02E3" | 85 | #define ACPI_FUJITSU_LAPTOP_HID "FUJ02E3" |
86 | #define ACPI_FUJITSU_HOTKEY_DRIVER_NAME "Fujitsu laptop FUJ02E3 ACPI hotkeys driver" | 86 | #define ACPI_FUJITSU_LAPTOP_DRIVER_NAME "Fujitsu laptop FUJ02E3 ACPI hotkeys driver" |
87 | #define ACPI_FUJITSU_HOTKEY_DEVICE_NAME "Fujitsu FUJ02E3" | 87 | #define ACPI_FUJITSU_LAPTOP_DEVICE_NAME "Fujitsu FUJ02E3" |
88 | 88 | ||
89 | #define ACPI_FUJITSU_NOTIFY_CODE1 0x80 | 89 | #define ACPI_FUJITSU_NOTIFY_CODE1 0x80 |
90 | 90 | ||
91 | /* FUNC interface - command values */ | 91 | /* FUNC interface - command values */ |
92 | #define FUNC_RFKILL 0x1000 | 92 | #define FUNC_FLAGS 0x1000 |
93 | #define FUNC_LEDS 0x1001 | 93 | #define FUNC_LEDS 0x1001 |
94 | #define FUNC_BUTTONS 0x1002 | 94 | #define FUNC_BUTTONS 0x1002 |
95 | #define FUNC_BACKLIGHT 0x1004 | 95 | #define FUNC_BACKLIGHT 0x1004 |
@@ -97,6 +97,11 @@ | |||
97 | /* FUNC interface - responses */ | 97 | /* FUNC interface - responses */ |
98 | #define UNSUPPORTED_CMD 0x80000000 | 98 | #define UNSUPPORTED_CMD 0x80000000 |
99 | 99 | ||
100 | /* FUNC interface - status flags */ | ||
101 | #define FLAG_RFKILL 0x020 | ||
102 | #define FLAG_LID 0x100 | ||
103 | #define FLAG_DOCK 0x200 | ||
104 | |||
100 | #if IS_ENABLED(CONFIG_LEDS_CLASS) | 105 | #if IS_ENABLED(CONFIG_LEDS_CLASS) |
101 | /* FUNC interface - LED control */ | 106 | /* FUNC interface - LED control */ |
102 | #define FUNC_LED_OFF 0x1 | 107 | #define FUNC_LED_OFF 0x1 |
@@ -136,7 +141,7 @@ | |||
136 | #endif | 141 | #endif |
137 | 142 | ||
138 | /* Device controlling the backlight and associated keys */ | 143 | /* Device controlling the backlight and associated keys */ |
139 | struct fujitsu_t { | 144 | struct fujitsu_bl { |
140 | acpi_handle acpi_handle; | 145 | acpi_handle acpi_handle; |
141 | struct acpi_device *dev; | 146 | struct acpi_device *dev; |
142 | struct input_dev *input; | 147 | struct input_dev *input; |
@@ -150,12 +155,12 @@ struct fujitsu_t { | |||
150 | unsigned int brightness_level; | 155 | unsigned int brightness_level; |
151 | }; | 156 | }; |
152 | 157 | ||
153 | static struct fujitsu_t *fujitsu; | 158 | static struct fujitsu_bl *fujitsu_bl; |
154 | static int use_alt_lcd_levels = -1; | 159 | static int use_alt_lcd_levels = -1; |
155 | static int disable_brightness_adjust = -1; | 160 | static int disable_brightness_adjust = -1; |
156 | 161 | ||
157 | /* Device used to access other hotkeys on the laptop */ | 162 | /* Device used to access hotkeys and other features on the laptop */ |
158 | struct fujitsu_hotkey_t { | 163 | struct fujitsu_laptop { |
159 | acpi_handle acpi_handle; | 164 | acpi_handle acpi_handle; |
160 | struct acpi_device *dev; | 165 | struct acpi_device *dev; |
161 | struct input_dev *input; | 166 | struct input_dev *input; |
@@ -163,17 +168,15 @@ struct fujitsu_hotkey_t { | |||
163 | struct platform_device *pf_device; | 168 | struct platform_device *pf_device; |
164 | struct kfifo fifo; | 169 | struct kfifo fifo; |
165 | spinlock_t fifo_lock; | 170 | spinlock_t fifo_lock; |
166 | int rfkill_supported; | 171 | int flags_supported; |
167 | int rfkill_state; | 172 | int flags_state; |
168 | int logolamp_registered; | 173 | int logolamp_registered; |
169 | int kblamps_registered; | 174 | int kblamps_registered; |
170 | int radio_led_registered; | 175 | int radio_led_registered; |
171 | int eco_led_registered; | 176 | int eco_led_registered; |
172 | }; | 177 | }; |
173 | 178 | ||
174 | static struct fujitsu_hotkey_t *fujitsu_hotkey; | 179 | static struct fujitsu_laptop *fujitsu_laptop; |
175 | |||
176 | static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event); | ||
177 | 180 | ||
178 | #if IS_ENABLED(CONFIG_LEDS_CLASS) | 181 | #if IS_ENABLED(CONFIG_LEDS_CLASS) |
179 | static enum led_brightness logolamp_get(struct led_classdev *cdev); | 182 | static enum led_brightness logolamp_get(struct led_classdev *cdev); |
@@ -222,8 +225,6 @@ static struct led_classdev eco_led = { | |||
222 | static u32 dbg_level = 0x03; | 225 | static u32 dbg_level = 0x03; |
223 | #endif | 226 | #endif |
224 | 227 | ||
225 | static void acpi_fujitsu_notify(struct acpi_device *device, u32 event); | ||
226 | |||
227 | /* Fujitsu ACPI interface function */ | 228 | /* Fujitsu ACPI interface function */ |
228 | 229 | ||
229 | static int call_fext_func(int cmd, int arg0, int arg1, int arg2) | 230 | static int call_fext_func(int cmd, int arg0, int arg1, int arg2) |
@@ -239,7 +240,7 @@ static int call_fext_func(int cmd, int arg0, int arg1, int arg2) | |||
239 | unsigned long long value; | 240 | unsigned long long value; |
240 | acpi_handle handle = NULL; | 241 | acpi_handle handle = NULL; |
241 | 242 | ||
242 | status = acpi_get_handle(fujitsu_hotkey->acpi_handle, "FUNC", &handle); | 243 | status = acpi_get_handle(fujitsu_laptop->acpi_handle, "FUNC", &handle); |
243 | if (ACPI_FAILURE(status)) { | 244 | if (ACPI_FAILURE(status)) { |
244 | vdbg_printk(FUJLAPTOP_DBG_ERROR, | 245 | vdbg_printk(FUJLAPTOP_DBG_ERROR, |
245 | "FUNC interface is not present\n"); | 246 | "FUNC interface is not present\n"); |
@@ -300,9 +301,9 @@ static int radio_led_set(struct led_classdev *cdev, | |||
300 | enum led_brightness brightness) | 301 | enum led_brightness brightness) |
301 | { | 302 | { |
302 | if (brightness >= LED_FULL) | 303 | if (brightness >= LED_FULL) |
303 | return call_fext_func(FUNC_RFKILL, 0x5, RADIO_LED_ON, RADIO_LED_ON); | 304 | return call_fext_func(FUNC_FLAGS, 0x5, RADIO_LED_ON, RADIO_LED_ON); |
304 | else | 305 | else |
305 | return call_fext_func(FUNC_RFKILL, 0x5, RADIO_LED_ON, 0x0); | 306 | return call_fext_func(FUNC_FLAGS, 0x5, RADIO_LED_ON, 0x0); |
306 | } | 307 | } |
307 | 308 | ||
308 | static int eco_led_set(struct led_classdev *cdev, | 309 | static int eco_led_set(struct led_classdev *cdev, |
@@ -346,7 +347,7 @@ static enum led_brightness radio_led_get(struct led_classdev *cdev) | |||
346 | { | 347 | { |
347 | enum led_brightness brightness = LED_OFF; | 348 | enum led_brightness brightness = LED_OFF; |
348 | 349 | ||
349 | if (call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0) & RADIO_LED_ON) | 350 | if (call_fext_func(FUNC_FLAGS, 0x4, 0x0, 0x0) & RADIO_LED_ON) |
350 | brightness = LED_FULL; | 351 | brightness = LED_FULL; |
351 | 352 | ||
352 | return brightness; | 353 | return brightness; |
@@ -373,10 +374,10 @@ static int set_lcd_level(int level) | |||
373 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBLL [%d]\n", | 374 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBLL [%d]\n", |
374 | level); | 375 | level); |
375 | 376 | ||
376 | if (level < 0 || level >= fujitsu->max_brightness) | 377 | if (level < 0 || level >= fujitsu_bl->max_brightness) |
377 | return -EINVAL; | 378 | return -EINVAL; |
378 | 379 | ||
379 | status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle); | 380 | status = acpi_get_handle(fujitsu_bl->acpi_handle, "SBLL", &handle); |
380 | if (ACPI_FAILURE(status)) { | 381 | if (ACPI_FAILURE(status)) { |
381 | vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBLL not present\n"); | 382 | vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBLL not present\n"); |
382 | return -ENODEV; | 383 | return -ENODEV; |
@@ -398,10 +399,10 @@ static int set_lcd_level_alt(int level) | |||
398 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBL2 [%d]\n", | 399 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBL2 [%d]\n", |
399 | level); | 400 | level); |
400 | 401 | ||
401 | if (level < 0 || level >= fujitsu->max_brightness) | 402 | if (level < 0 || level >= fujitsu_bl->max_brightness) |
402 | return -EINVAL; | 403 | return -EINVAL; |
403 | 404 | ||
404 | status = acpi_get_handle(fujitsu->acpi_handle, "SBL2", &handle); | 405 | status = acpi_get_handle(fujitsu_bl->acpi_handle, "SBL2", &handle); |
405 | if (ACPI_FAILURE(status)) { | 406 | if (ACPI_FAILURE(status)) { |
406 | vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBL2 not present\n"); | 407 | vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBL2 not present\n"); |
407 | return -ENODEV; | 408 | return -ENODEV; |
@@ -421,19 +422,19 @@ static int get_lcd_level(void) | |||
421 | 422 | ||
422 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLL\n"); | 423 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLL\n"); |
423 | 424 | ||
424 | status = | 425 | status = acpi_evaluate_integer(fujitsu_bl->acpi_handle, "GBLL", NULL, |
425 | acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state); | 426 | &state); |
426 | if (ACPI_FAILURE(status)) | 427 | if (ACPI_FAILURE(status)) |
427 | return 0; | 428 | return 0; |
428 | 429 | ||
429 | fujitsu->brightness_level = state & 0x0fffffff; | 430 | fujitsu_bl->brightness_level = state & 0x0fffffff; |
430 | 431 | ||
431 | if (state & 0x80000000) | 432 | if (state & 0x80000000) |
432 | fujitsu->brightness_changed = 1; | 433 | fujitsu_bl->brightness_changed = 1; |
433 | else | 434 | else |
434 | fujitsu->brightness_changed = 0; | 435 | fujitsu_bl->brightness_changed = 0; |
435 | 436 | ||
436 | return fujitsu->brightness_level; | 437 | return fujitsu_bl->brightness_level; |
437 | } | 438 | } |
438 | 439 | ||
439 | static int get_max_brightness(void) | 440 | static int get_max_brightness(void) |
@@ -443,14 +444,14 @@ static int get_max_brightness(void) | |||
443 | 444 | ||
444 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "get max lcd level via RBLL\n"); | 445 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "get max lcd level via RBLL\n"); |
445 | 446 | ||
446 | status = | 447 | status = acpi_evaluate_integer(fujitsu_bl->acpi_handle, "RBLL", NULL, |
447 | acpi_evaluate_integer(fujitsu->acpi_handle, "RBLL", NULL, &state); | 448 | &state); |
448 | if (ACPI_FAILURE(status)) | 449 | if (ACPI_FAILURE(status)) |
449 | return -1; | 450 | return -1; |
450 | 451 | ||
451 | fujitsu->max_brightness = state; | 452 | fujitsu_bl->max_brightness = state; |
452 | 453 | ||
453 | return fujitsu->max_brightness; | 454 | return fujitsu_bl->max_brightness; |
454 | } | 455 | } |
455 | 456 | ||
456 | /* Backlight device stuff */ | 457 | /* Backlight device stuff */ |
@@ -483,7 +484,7 @@ static int bl_update_status(struct backlight_device *b) | |||
483 | return ret; | 484 | return ret; |
484 | } | 485 | } |
485 | 486 | ||
486 | static const struct backlight_ops fujitsubl_ops = { | 487 | static const struct backlight_ops fujitsu_bl_ops = { |
487 | .get_brightness = bl_get_brightness, | 488 | .get_brightness = bl_get_brightness, |
488 | .update_status = bl_update_status, | 489 | .update_status = bl_update_status, |
489 | }; | 490 | }; |
@@ -511,7 +512,7 @@ show_brightness_changed(struct device *dev, | |||
511 | 512 | ||
512 | int ret; | 513 | int ret; |
513 | 514 | ||
514 | ret = fujitsu->brightness_changed; | 515 | ret = fujitsu_bl->brightness_changed; |
515 | if (ret < 0) | 516 | if (ret < 0) |
516 | return ret; | 517 | return ret; |
517 | 518 | ||
@@ -539,7 +540,7 @@ static ssize_t store_lcd_level(struct device *dev, | |||
539 | int level, ret; | 540 | int level, ret; |
540 | 541 | ||
541 | if (sscanf(buf, "%i", &level) != 1 | 542 | if (sscanf(buf, "%i", &level) != 1 |
542 | || (level < 0 || level >= fujitsu->max_brightness)) | 543 | || (level < 0 || level >= fujitsu_bl->max_brightness)) |
543 | return -EINVAL; | 544 | return -EINVAL; |
544 | 545 | ||
545 | if (use_alt_lcd_levels) | 546 | if (use_alt_lcd_levels) |
@@ -567,9 +568,9 @@ static ssize_t | |||
567 | show_lid_state(struct device *dev, | 568 | show_lid_state(struct device *dev, |
568 | struct device_attribute *attr, char *buf) | 569 | struct device_attribute *attr, char *buf) |
569 | { | 570 | { |
570 | if (!(fujitsu_hotkey->rfkill_supported & 0x100)) | 571 | if (!(fujitsu_laptop->flags_supported & FLAG_LID)) |
571 | return sprintf(buf, "unknown\n"); | 572 | return sprintf(buf, "unknown\n"); |
572 | if (fujitsu_hotkey->rfkill_state & 0x100) | 573 | if (fujitsu_laptop->flags_state & FLAG_LID) |
573 | return sprintf(buf, "open\n"); | 574 | return sprintf(buf, "open\n"); |
574 | else | 575 | else |
575 | return sprintf(buf, "closed\n"); | 576 | return sprintf(buf, "closed\n"); |
@@ -579,9 +580,9 @@ static ssize_t | |||
579 | show_dock_state(struct device *dev, | 580 | show_dock_state(struct device *dev, |
580 | struct device_attribute *attr, char *buf) | 581 | struct device_attribute *attr, char *buf) |
581 | { | 582 | { |
582 | if (!(fujitsu_hotkey->rfkill_supported & 0x200)) | 583 | if (!(fujitsu_laptop->flags_supported & FLAG_DOCK)) |
583 | return sprintf(buf, "unknown\n"); | 584 | return sprintf(buf, "unknown\n"); |
584 | if (fujitsu_hotkey->rfkill_state & 0x200) | 585 | if (fujitsu_laptop->flags_state & FLAG_DOCK) |
585 | return sprintf(buf, "docked\n"); | 586 | return sprintf(buf, "docked\n"); |
586 | else | 587 | else |
587 | return sprintf(buf, "undocked\n"); | 588 | return sprintf(buf, "undocked\n"); |
@@ -591,9 +592,9 @@ static ssize_t | |||
591 | show_radios_state(struct device *dev, | 592 | show_radios_state(struct device *dev, |
592 | struct device_attribute *attr, char *buf) | 593 | struct device_attribute *attr, char *buf) |
593 | { | 594 | { |
594 | if (!(fujitsu_hotkey->rfkill_supported & 0x20)) | 595 | if (!(fujitsu_laptop->flags_supported & FLAG_RFKILL)) |
595 | return sprintf(buf, "unknown\n"); | 596 | return sprintf(buf, "unknown\n"); |
596 | if (fujitsu_hotkey->rfkill_state & 0x20) | 597 | if (fujitsu_laptop->flags_state & FLAG_RFKILL) |
597 | return sprintf(buf, "on\n"); | 598 | return sprintf(buf, "on\n"); |
598 | else | 599 | else |
599 | return sprintf(buf, "killed\n"); | 600 | return sprintf(buf, "killed\n"); |
@@ -607,7 +608,7 @@ static DEVICE_ATTR(lid, 0444, show_lid_state, ignore_store); | |||
607 | static DEVICE_ATTR(dock, 0444, show_dock_state, ignore_store); | 608 | static DEVICE_ATTR(dock, 0444, show_dock_state, ignore_store); |
608 | static DEVICE_ATTR(radios, 0444, show_radios_state, ignore_store); | 609 | static DEVICE_ATTR(radios, 0444, show_radios_state, ignore_store); |
609 | 610 | ||
610 | static struct attribute *fujitsupf_attributes[] = { | 611 | static struct attribute *fujitsu_pf_attributes[] = { |
611 | &dev_attr_brightness_changed.attr, | 612 | &dev_attr_brightness_changed.attr, |
612 | &dev_attr_max_brightness.attr, | 613 | &dev_attr_max_brightness.attr, |
613 | &dev_attr_lcd_level.attr, | 614 | &dev_attr_lcd_level.attr, |
@@ -617,11 +618,11 @@ static struct attribute *fujitsupf_attributes[] = { | |||
617 | NULL | 618 | NULL |
618 | }; | 619 | }; |
619 | 620 | ||
620 | static struct attribute_group fujitsupf_attribute_group = { | 621 | static struct attribute_group fujitsu_pf_attribute_group = { |
621 | .attrs = fujitsupf_attributes | 622 | .attrs = fujitsu_pf_attributes |
622 | }; | 623 | }; |
623 | 624 | ||
624 | static struct platform_driver fujitsupf_driver = { | 625 | static struct platform_driver fujitsu_pf_driver = { |
625 | .driver = { | 626 | .driver = { |
626 | .name = "fujitsu-laptop", | 627 | .name = "fujitsu-laptop", |
627 | } | 628 | } |
@@ -630,39 +631,30 @@ static struct platform_driver fujitsupf_driver = { | |||
630 | static void __init dmi_check_cb_common(const struct dmi_system_id *id) | 631 | static void __init dmi_check_cb_common(const struct dmi_system_id *id) |
631 | { | 632 | { |
632 | pr_info("Identified laptop model '%s'\n", id->ident); | 633 | pr_info("Identified laptop model '%s'\n", id->ident); |
633 | if (use_alt_lcd_levels == -1) { | ||
634 | if (acpi_has_method(NULL, | ||
635 | "\\_SB.PCI0.LPCB.FJEX.SBL2")) | ||
636 | use_alt_lcd_levels = 1; | ||
637 | else | ||
638 | use_alt_lcd_levels = 0; | ||
639 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "auto-detected usealt as " | ||
640 | "%i\n", use_alt_lcd_levels); | ||
641 | } | ||
642 | } | 634 | } |
643 | 635 | ||
644 | static int __init dmi_check_cb_s6410(const struct dmi_system_id *id) | 636 | static int __init dmi_check_cb_s6410(const struct dmi_system_id *id) |
645 | { | 637 | { |
646 | dmi_check_cb_common(id); | 638 | dmi_check_cb_common(id); |
647 | fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */ | 639 | fujitsu_bl->keycode1 = KEY_SCREENLOCK; /* "Lock" */ |
648 | fujitsu->keycode2 = KEY_HELP; /* "Mobility Center" */ | 640 | fujitsu_bl->keycode2 = KEY_HELP; /* "Mobility Center" */ |
649 | return 1; | 641 | return 1; |
650 | } | 642 | } |
651 | 643 | ||
652 | static int __init dmi_check_cb_s6420(const struct dmi_system_id *id) | 644 | static int __init dmi_check_cb_s6420(const struct dmi_system_id *id) |
653 | { | 645 | { |
654 | dmi_check_cb_common(id); | 646 | dmi_check_cb_common(id); |
655 | fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */ | 647 | fujitsu_bl->keycode1 = KEY_SCREENLOCK; /* "Lock" */ |
656 | fujitsu->keycode2 = KEY_HELP; /* "Mobility Center" */ | 648 | fujitsu_bl->keycode2 = KEY_HELP; /* "Mobility Center" */ |
657 | return 1; | 649 | return 1; |
658 | } | 650 | } |
659 | 651 | ||
660 | static int __init dmi_check_cb_p8010(const struct dmi_system_id *id) | 652 | static int __init dmi_check_cb_p8010(const struct dmi_system_id *id) |
661 | { | 653 | { |
662 | dmi_check_cb_common(id); | 654 | dmi_check_cb_common(id); |
663 | fujitsu->keycode1 = KEY_HELP; /* "Support" */ | 655 | fujitsu_bl->keycode1 = KEY_HELP; /* "Support" */ |
664 | fujitsu->keycode3 = KEY_SWITCHVIDEOMODE; /* "Presentation" */ | 656 | fujitsu_bl->keycode3 = KEY_SWITCHVIDEOMODE; /* "Presentation" */ |
665 | fujitsu->keycode4 = KEY_WWW; /* "Internet" */ | 657 | fujitsu_bl->keycode4 = KEY_WWW; /* "Internet" */ |
666 | return 1; | 658 | return 1; |
667 | } | 659 | } |
668 | 660 | ||
@@ -693,7 +685,7 @@ static const struct dmi_system_id fujitsu_dmi_table[] __initconst = { | |||
693 | 685 | ||
694 | /* ACPI device for LCD brightness control */ | 686 | /* ACPI device for LCD brightness control */ |
695 | 687 | ||
696 | static int acpi_fujitsu_add(struct acpi_device *device) | 688 | static int acpi_fujitsu_bl_add(struct acpi_device *device) |
697 | { | 689 | { |
698 | int state = 0; | 690 | int state = 0; |
699 | struct input_dev *input; | 691 | struct input_dev *input; |
@@ -702,22 +694,22 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
702 | if (!device) | 694 | if (!device) |
703 | return -EINVAL; | 695 | return -EINVAL; |
704 | 696 | ||
705 | fujitsu->acpi_handle = device->handle; | 697 | fujitsu_bl->acpi_handle = device->handle; |
706 | sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_DEVICE_NAME); | 698 | sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_BL_DEVICE_NAME); |
707 | sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); | 699 | sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); |
708 | device->driver_data = fujitsu; | 700 | device->driver_data = fujitsu_bl; |
709 | 701 | ||
710 | fujitsu->input = input = input_allocate_device(); | 702 | fujitsu_bl->input = input = input_allocate_device(); |
711 | if (!input) { | 703 | if (!input) { |
712 | error = -ENOMEM; | 704 | error = -ENOMEM; |
713 | goto err_stop; | 705 | goto err_stop; |
714 | } | 706 | } |
715 | 707 | ||
716 | snprintf(fujitsu->phys, sizeof(fujitsu->phys), | 708 | snprintf(fujitsu_bl->phys, sizeof(fujitsu_bl->phys), |
717 | "%s/video/input0", acpi_device_hid(device)); | 709 | "%s/video/input0", acpi_device_hid(device)); |
718 | 710 | ||
719 | input->name = acpi_device_name(device); | 711 | input->name = acpi_device_name(device); |
720 | input->phys = fujitsu->phys; | 712 | input->phys = fujitsu_bl->phys; |
721 | input->id.bustype = BUS_HOST; | 713 | input->id.bustype = BUS_HOST; |
722 | input->id.product = 0x06; | 714 | input->id.product = 0x06; |
723 | input->dev.parent = &device->dev; | 715 | input->dev.parent = &device->dev; |
@@ -730,7 +722,7 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
730 | if (error) | 722 | if (error) |
731 | goto err_free_input_dev; | 723 | goto err_free_input_dev; |
732 | 724 | ||
733 | error = acpi_bus_update_power(fujitsu->acpi_handle, &state); | 725 | error = acpi_bus_update_power(fujitsu_bl->acpi_handle, &state); |
734 | if (error) { | 726 | if (error) { |
735 | pr_err("Error reading power state\n"); | 727 | pr_err("Error reading power state\n"); |
736 | goto err_unregister_input_dev; | 728 | goto err_unregister_input_dev; |
@@ -740,7 +732,7 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
740 | acpi_device_name(device), acpi_device_bid(device), | 732 | acpi_device_name(device), acpi_device_bid(device), |
741 | !device->power.state ? "on" : "off"); | 733 | !device->power.state ? "on" : "off"); |
742 | 734 | ||
743 | fujitsu->dev = device; | 735 | fujitsu_bl->dev = device; |
744 | 736 | ||
745 | if (acpi_has_method(device->handle, METHOD_NAME__INI)) { | 737 | if (acpi_has_method(device->handle, METHOD_NAME__INI)) { |
746 | vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n"); | 738 | vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n"); |
@@ -750,6 +742,15 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
750 | pr_err("_INI Method failed\n"); | 742 | pr_err("_INI Method failed\n"); |
751 | } | 743 | } |
752 | 744 | ||
745 | if (use_alt_lcd_levels == -1) { | ||
746 | if (acpi_has_method(NULL, "\\_SB.PCI0.LPCB.FJEX.SBL2")) | ||
747 | use_alt_lcd_levels = 1; | ||
748 | else | ||
749 | use_alt_lcd_levels = 0; | ||
750 | vdbg_printk(FUJLAPTOP_DBG_TRACE, "auto-detected usealt as %i\n", | ||
751 | use_alt_lcd_levels); | ||
752 | } | ||
753 | |||
753 | /* do config (detect defaults) */ | 754 | /* do config (detect defaults) */ |
754 | use_alt_lcd_levels = use_alt_lcd_levels == 1 ? 1 : 0; | 755 | use_alt_lcd_levels = use_alt_lcd_levels == 1 ? 1 : 0; |
755 | disable_brightness_adjust = disable_brightness_adjust == 1 ? 1 : 0; | 756 | disable_brightness_adjust = disable_brightness_adjust == 1 ? 1 : 0; |
@@ -758,7 +759,7 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
758 | use_alt_lcd_levels, disable_brightness_adjust); | 759 | use_alt_lcd_levels, disable_brightness_adjust); |
759 | 760 | ||
760 | if (get_max_brightness() <= 0) | 761 | if (get_max_brightness() <= 0) |
761 | fujitsu->max_brightness = FUJITSU_LCD_N_LEVELS; | 762 | fujitsu_bl->max_brightness = FUJITSU_LCD_N_LEVELS; |
762 | get_lcd_level(); | 763 | get_lcd_level(); |
763 | 764 | ||
764 | return 0; | 765 | return 0; |
@@ -772,38 +773,38 @@ err_stop: | |||
772 | return error; | 773 | return error; |
773 | } | 774 | } |
774 | 775 | ||
775 | static int acpi_fujitsu_remove(struct acpi_device *device) | 776 | static int acpi_fujitsu_bl_remove(struct acpi_device *device) |
776 | { | 777 | { |
777 | struct fujitsu_t *fujitsu = acpi_driver_data(device); | 778 | struct fujitsu_bl *fujitsu_bl = acpi_driver_data(device); |
778 | struct input_dev *input = fujitsu->input; | 779 | struct input_dev *input = fujitsu_bl->input; |
779 | 780 | ||
780 | input_unregister_device(input); | 781 | input_unregister_device(input); |
781 | 782 | ||
782 | fujitsu->acpi_handle = NULL; | 783 | fujitsu_bl->acpi_handle = NULL; |
783 | 784 | ||
784 | return 0; | 785 | return 0; |
785 | } | 786 | } |
786 | 787 | ||
787 | /* Brightness notify */ | 788 | /* Brightness notify */ |
788 | 789 | ||
789 | static void acpi_fujitsu_notify(struct acpi_device *device, u32 event) | 790 | static void acpi_fujitsu_bl_notify(struct acpi_device *device, u32 event) |
790 | { | 791 | { |
791 | struct input_dev *input; | 792 | struct input_dev *input; |
792 | int keycode; | 793 | int keycode; |
793 | int oldb, newb; | 794 | int oldb, newb; |
794 | 795 | ||
795 | input = fujitsu->input; | 796 | input = fujitsu_bl->input; |
796 | 797 | ||
797 | switch (event) { | 798 | switch (event) { |
798 | case ACPI_FUJITSU_NOTIFY_CODE1: | 799 | case ACPI_FUJITSU_NOTIFY_CODE1: |
799 | keycode = 0; | 800 | keycode = 0; |
800 | oldb = fujitsu->brightness_level; | 801 | oldb = fujitsu_bl->brightness_level; |
801 | get_lcd_level(); | 802 | get_lcd_level(); |
802 | newb = fujitsu->brightness_level; | 803 | newb = fujitsu_bl->brightness_level; |
803 | 804 | ||
804 | vdbg_printk(FUJLAPTOP_DBG_TRACE, | 805 | vdbg_printk(FUJLAPTOP_DBG_TRACE, |
805 | "brightness button event [%i -> %i (%i)]\n", | 806 | "brightness button event [%i -> %i (%i)]\n", |
806 | oldb, newb, fujitsu->brightness_changed); | 807 | oldb, newb, fujitsu_bl->brightness_changed); |
807 | 808 | ||
808 | if (oldb < newb) { | 809 | if (oldb < newb) { |
809 | if (disable_brightness_adjust != 1) { | 810 | if (disable_brightness_adjust != 1) { |
@@ -840,7 +841,7 @@ static void acpi_fujitsu_notify(struct acpi_device *device, u32 event) | |||
840 | 841 | ||
841 | /* ACPI device for hotkey handling */ | 842 | /* ACPI device for hotkey handling */ |
842 | 843 | ||
843 | static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | 844 | static int acpi_fujitsu_laptop_add(struct acpi_device *device) |
844 | { | 845 | { |
845 | int result = 0; | 846 | int result = 0; |
846 | int state = 0; | 847 | int state = 0; |
@@ -851,42 +852,42 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
851 | if (!device) | 852 | if (!device) |
852 | return -EINVAL; | 853 | return -EINVAL; |
853 | 854 | ||
854 | fujitsu_hotkey->acpi_handle = device->handle; | 855 | fujitsu_laptop->acpi_handle = device->handle; |
855 | sprintf(acpi_device_name(device), "%s", | 856 | sprintf(acpi_device_name(device), "%s", |
856 | ACPI_FUJITSU_HOTKEY_DEVICE_NAME); | 857 | ACPI_FUJITSU_LAPTOP_DEVICE_NAME); |
857 | sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); | 858 | sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); |
858 | device->driver_data = fujitsu_hotkey; | 859 | device->driver_data = fujitsu_laptop; |
859 | 860 | ||
860 | /* kfifo */ | 861 | /* kfifo */ |
861 | spin_lock_init(&fujitsu_hotkey->fifo_lock); | 862 | spin_lock_init(&fujitsu_laptop->fifo_lock); |
862 | error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int), | 863 | error = kfifo_alloc(&fujitsu_laptop->fifo, RINGBUFFERSIZE * sizeof(int), |
863 | GFP_KERNEL); | 864 | GFP_KERNEL); |
864 | if (error) { | 865 | if (error) { |
865 | pr_err("kfifo_alloc failed\n"); | 866 | pr_err("kfifo_alloc failed\n"); |
866 | goto err_stop; | 867 | goto err_stop; |
867 | } | 868 | } |
868 | 869 | ||
869 | fujitsu_hotkey->input = input = input_allocate_device(); | 870 | fujitsu_laptop->input = input = input_allocate_device(); |
870 | if (!input) { | 871 | if (!input) { |
871 | error = -ENOMEM; | 872 | error = -ENOMEM; |
872 | goto err_free_fifo; | 873 | goto err_free_fifo; |
873 | } | 874 | } |
874 | 875 | ||
875 | snprintf(fujitsu_hotkey->phys, sizeof(fujitsu_hotkey->phys), | 876 | snprintf(fujitsu_laptop->phys, sizeof(fujitsu_laptop->phys), |
876 | "%s/video/input0", acpi_device_hid(device)); | 877 | "%s/video/input0", acpi_device_hid(device)); |
877 | 878 | ||
878 | input->name = acpi_device_name(device); | 879 | input->name = acpi_device_name(device); |
879 | input->phys = fujitsu_hotkey->phys; | 880 | input->phys = fujitsu_laptop->phys; |
880 | input->id.bustype = BUS_HOST; | 881 | input->id.bustype = BUS_HOST; |
881 | input->id.product = 0x06; | 882 | input->id.product = 0x06; |
882 | input->dev.parent = &device->dev; | 883 | input->dev.parent = &device->dev; |
883 | 884 | ||
884 | set_bit(EV_KEY, input->evbit); | 885 | set_bit(EV_KEY, input->evbit); |
885 | set_bit(fujitsu->keycode1, input->keybit); | 886 | set_bit(fujitsu_bl->keycode1, input->keybit); |
886 | set_bit(fujitsu->keycode2, input->keybit); | 887 | set_bit(fujitsu_bl->keycode2, input->keybit); |
887 | set_bit(fujitsu->keycode3, input->keybit); | 888 | set_bit(fujitsu_bl->keycode3, input->keybit); |
888 | set_bit(fujitsu->keycode4, input->keybit); | 889 | set_bit(fujitsu_bl->keycode4, input->keybit); |
889 | set_bit(fujitsu->keycode5, input->keybit); | 890 | set_bit(fujitsu_bl->keycode5, input->keybit); |
890 | set_bit(KEY_TOUCHPAD_TOGGLE, input->keybit); | 891 | set_bit(KEY_TOUCHPAD_TOGGLE, input->keybit); |
891 | set_bit(KEY_UNKNOWN, input->keybit); | 892 | set_bit(KEY_UNKNOWN, input->keybit); |
892 | 893 | ||
@@ -894,7 +895,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
894 | if (error) | 895 | if (error) |
895 | goto err_free_input_dev; | 896 | goto err_free_input_dev; |
896 | 897 | ||
897 | error = acpi_bus_update_power(fujitsu_hotkey->acpi_handle, &state); | 898 | error = acpi_bus_update_power(fujitsu_laptop->acpi_handle, &state); |
898 | if (error) { | 899 | if (error) { |
899 | pr_err("Error reading power state\n"); | 900 | pr_err("Error reading power state\n"); |
900 | goto err_unregister_input_dev; | 901 | goto err_unregister_input_dev; |
@@ -904,7 +905,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
904 | acpi_device_name(device), acpi_device_bid(device), | 905 | acpi_device_name(device), acpi_device_bid(device), |
905 | !device->power.state ? "on" : "off"); | 906 | !device->power.state ? "on" : "off"); |
906 | 907 | ||
907 | fujitsu_hotkey->dev = device; | 908 | fujitsu_laptop->dev = device; |
908 | 909 | ||
909 | if (acpi_has_method(device->handle, METHOD_NAME__INI)) { | 910 | if (acpi_has_method(device->handle, METHOD_NAME__INI)) { |
910 | vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n"); | 911 | vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n"); |
@@ -920,27 +921,27 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
920 | ; /* No action, result is discarded */ | 921 | ; /* No action, result is discarded */ |
921 | vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i); | 922 | vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i); |
922 | 923 | ||
923 | fujitsu_hotkey->rfkill_supported = | 924 | fujitsu_laptop->flags_supported = |
924 | call_fext_func(FUNC_RFKILL, 0x0, 0x0, 0x0); | 925 | call_fext_func(FUNC_FLAGS, 0x0, 0x0, 0x0); |
925 | 926 | ||
926 | /* Make sure our bitmask of supported functions is cleared if the | 927 | /* Make sure our bitmask of supported functions is cleared if the |
927 | RFKILL function block is not implemented, like on the S7020. */ | 928 | RFKILL function block is not implemented, like on the S7020. */ |
928 | if (fujitsu_hotkey->rfkill_supported == UNSUPPORTED_CMD) | 929 | if (fujitsu_laptop->flags_supported == UNSUPPORTED_CMD) |
929 | fujitsu_hotkey->rfkill_supported = 0; | 930 | fujitsu_laptop->flags_supported = 0; |
930 | 931 | ||
931 | if (fujitsu_hotkey->rfkill_supported) | 932 | if (fujitsu_laptop->flags_supported) |
932 | fujitsu_hotkey->rfkill_state = | 933 | fujitsu_laptop->flags_state = |
933 | call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); | 934 | call_fext_func(FUNC_FLAGS, 0x4, 0x0, 0x0); |
934 | 935 | ||
935 | /* Suspect this is a keymap of the application panel, print it */ | 936 | /* Suspect this is a keymap of the application panel, print it */ |
936 | pr_info("BTNI: [0x%x]\n", call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0)); | 937 | pr_info("BTNI: [0x%x]\n", call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0)); |
937 | 938 | ||
938 | #if IS_ENABLED(CONFIG_LEDS_CLASS) | 939 | #if IS_ENABLED(CONFIG_LEDS_CLASS) |
939 | if (call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) { | 940 | if (call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) { |
940 | result = led_classdev_register(&fujitsu->pf_device->dev, | 941 | result = led_classdev_register(&fujitsu_bl->pf_device->dev, |
941 | &logolamp_led); | 942 | &logolamp_led); |
942 | if (result == 0) { | 943 | if (result == 0) { |
943 | fujitsu_hotkey->logolamp_registered = 1; | 944 | fujitsu_laptop->logolamp_registered = 1; |
944 | } else { | 945 | } else { |
945 | pr_err("Could not register LED handler for logo lamp, error %i\n", | 946 | pr_err("Could not register LED handler for logo lamp, error %i\n", |
946 | result); | 947 | result); |
@@ -949,10 +950,10 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
949 | 950 | ||
950 | if ((call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & KEYBOARD_LAMPS) && | 951 | if ((call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & KEYBOARD_LAMPS) && |
951 | (call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0) == 0x0)) { | 952 | (call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0) == 0x0)) { |
952 | result = led_classdev_register(&fujitsu->pf_device->dev, | 953 | result = led_classdev_register(&fujitsu_bl->pf_device->dev, |
953 | &kblamps_led); | 954 | &kblamps_led); |
954 | if (result == 0) { | 955 | if (result == 0) { |
955 | fujitsu_hotkey->kblamps_registered = 1; | 956 | fujitsu_laptop->kblamps_registered = 1; |
956 | } else { | 957 | } else { |
957 | pr_err("Could not register LED handler for keyboard lamps, error %i\n", | 958 | pr_err("Could not register LED handler for keyboard lamps, error %i\n", |
958 | result); | 959 | result); |
@@ -966,10 +967,10 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
966 | * that an RF LED is present. | 967 | * that an RF LED is present. |
967 | */ | 968 | */ |
968 | if (call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0) & BIT(24)) { | 969 | if (call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0) & BIT(24)) { |
969 | result = led_classdev_register(&fujitsu->pf_device->dev, | 970 | result = led_classdev_register(&fujitsu_bl->pf_device->dev, |
970 | &radio_led); | 971 | &radio_led); |
971 | if (result == 0) { | 972 | if (result == 0) { |
972 | fujitsu_hotkey->radio_led_registered = 1; | 973 | fujitsu_laptop->radio_led_registered = 1; |
973 | } else { | 974 | } else { |
974 | pr_err("Could not register LED handler for radio LED, error %i\n", | 975 | pr_err("Could not register LED handler for radio LED, error %i\n", |
975 | result); | 976 | result); |
@@ -983,10 +984,10 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
983 | */ | 984 | */ |
984 | if ((call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & BIT(14)) && | 985 | if ((call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & BIT(14)) && |
985 | (call_fext_func(FUNC_LEDS, 0x2, ECO_LED, 0x0) != UNSUPPORTED_CMD)) { | 986 | (call_fext_func(FUNC_LEDS, 0x2, ECO_LED, 0x0) != UNSUPPORTED_CMD)) { |
986 | result = led_classdev_register(&fujitsu->pf_device->dev, | 987 | result = led_classdev_register(&fujitsu_bl->pf_device->dev, |
987 | &eco_led); | 988 | &eco_led); |
988 | if (result == 0) { | 989 | if (result == 0) { |
989 | fujitsu_hotkey->eco_led_registered = 1; | 990 | fujitsu_laptop->eco_led_registered = 1; |
990 | } else { | 991 | } else { |
991 | pr_err("Could not register LED handler for eco LED, error %i\n", | 992 | pr_err("Could not register LED handler for eco LED, error %i\n", |
992 | result); | 993 | result); |
@@ -1002,47 +1003,47 @@ err_unregister_input_dev: | |||
1002 | err_free_input_dev: | 1003 | err_free_input_dev: |
1003 | input_free_device(input); | 1004 | input_free_device(input); |
1004 | err_free_fifo: | 1005 | err_free_fifo: |
1005 | kfifo_free(&fujitsu_hotkey->fifo); | 1006 | kfifo_free(&fujitsu_laptop->fifo); |
1006 | err_stop: | 1007 | err_stop: |
1007 | return error; | 1008 | return error; |
1008 | } | 1009 | } |
1009 | 1010 | ||
1010 | static int acpi_fujitsu_hotkey_remove(struct acpi_device *device) | 1011 | static int acpi_fujitsu_laptop_remove(struct acpi_device *device) |
1011 | { | 1012 | { |
1012 | struct fujitsu_hotkey_t *fujitsu_hotkey = acpi_driver_data(device); | 1013 | struct fujitsu_laptop *fujitsu_laptop = acpi_driver_data(device); |
1013 | struct input_dev *input = fujitsu_hotkey->input; | 1014 | struct input_dev *input = fujitsu_laptop->input; |
1014 | 1015 | ||
1015 | #if IS_ENABLED(CONFIG_LEDS_CLASS) | 1016 | #if IS_ENABLED(CONFIG_LEDS_CLASS) |
1016 | if (fujitsu_hotkey->logolamp_registered) | 1017 | if (fujitsu_laptop->logolamp_registered) |
1017 | led_classdev_unregister(&logolamp_led); | 1018 | led_classdev_unregister(&logolamp_led); |
1018 | 1019 | ||
1019 | if (fujitsu_hotkey->kblamps_registered) | 1020 | if (fujitsu_laptop->kblamps_registered) |
1020 | led_classdev_unregister(&kblamps_led); | 1021 | led_classdev_unregister(&kblamps_led); |
1021 | 1022 | ||
1022 | if (fujitsu_hotkey->radio_led_registered) | 1023 | if (fujitsu_laptop->radio_led_registered) |
1023 | led_classdev_unregister(&radio_led); | 1024 | led_classdev_unregister(&radio_led); |
1024 | 1025 | ||
1025 | if (fujitsu_hotkey->eco_led_registered) | 1026 | if (fujitsu_laptop->eco_led_registered) |
1026 | led_classdev_unregister(&eco_led); | 1027 | led_classdev_unregister(&eco_led); |
1027 | #endif | 1028 | #endif |
1028 | 1029 | ||
1029 | input_unregister_device(input); | 1030 | input_unregister_device(input); |
1030 | 1031 | ||
1031 | kfifo_free(&fujitsu_hotkey->fifo); | 1032 | kfifo_free(&fujitsu_laptop->fifo); |
1032 | 1033 | ||
1033 | fujitsu_hotkey->acpi_handle = NULL; | 1034 | fujitsu_laptop->acpi_handle = NULL; |
1034 | 1035 | ||
1035 | return 0; | 1036 | return 0; |
1036 | } | 1037 | } |
1037 | 1038 | ||
1038 | static void acpi_fujitsu_hotkey_press(int keycode) | 1039 | static void acpi_fujitsu_laptop_press(int keycode) |
1039 | { | 1040 | { |
1040 | struct input_dev *input = fujitsu_hotkey->input; | 1041 | struct input_dev *input = fujitsu_laptop->input; |
1041 | int status; | 1042 | int status; |
1042 | 1043 | ||
1043 | status = kfifo_in_locked(&fujitsu_hotkey->fifo, | 1044 | status = kfifo_in_locked(&fujitsu_laptop->fifo, |
1044 | (unsigned char *)&keycode, sizeof(keycode), | 1045 | (unsigned char *)&keycode, sizeof(keycode), |
1045 | &fujitsu_hotkey->fifo_lock); | 1046 | &fujitsu_laptop->fifo_lock); |
1046 | if (status != sizeof(keycode)) { | 1047 | if (status != sizeof(keycode)) { |
1047 | vdbg_printk(FUJLAPTOP_DBG_WARN, | 1048 | vdbg_printk(FUJLAPTOP_DBG_WARN, |
1048 | "Could not push keycode [0x%x]\n", keycode); | 1049 | "Could not push keycode [0x%x]\n", keycode); |
@@ -1054,16 +1055,16 @@ static void acpi_fujitsu_hotkey_press(int keycode) | |||
1054 | "Push keycode into ringbuffer [%d]\n", keycode); | 1055 | "Push keycode into ringbuffer [%d]\n", keycode); |
1055 | } | 1056 | } |
1056 | 1057 | ||
1057 | static void acpi_fujitsu_hotkey_release(void) | 1058 | static void acpi_fujitsu_laptop_release(void) |
1058 | { | 1059 | { |
1059 | struct input_dev *input = fujitsu_hotkey->input; | 1060 | struct input_dev *input = fujitsu_laptop->input; |
1060 | int keycode, status; | 1061 | int keycode, status; |
1061 | 1062 | ||
1062 | while (true) { | 1063 | while (true) { |
1063 | status = kfifo_out_locked(&fujitsu_hotkey->fifo, | 1064 | status = kfifo_out_locked(&fujitsu_laptop->fifo, |
1064 | (unsigned char *)&keycode, | 1065 | (unsigned char *)&keycode, |
1065 | sizeof(keycode), | 1066 | sizeof(keycode), |
1066 | &fujitsu_hotkey->fifo_lock); | 1067 | &fujitsu_laptop->fifo_lock); |
1067 | if (status != sizeof(keycode)) | 1068 | if (status != sizeof(keycode)) |
1068 | return; | 1069 | return; |
1069 | input_report_key(input, keycode, 0); | 1070 | input_report_key(input, keycode, 0); |
@@ -1073,14 +1074,14 @@ static void acpi_fujitsu_hotkey_release(void) | |||
1073 | } | 1074 | } |
1074 | } | 1075 | } |
1075 | 1076 | ||
1076 | static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event) | 1077 | static void acpi_fujitsu_laptop_notify(struct acpi_device *device, u32 event) |
1077 | { | 1078 | { |
1078 | struct input_dev *input; | 1079 | struct input_dev *input; |
1079 | int keycode; | 1080 | int keycode; |
1080 | unsigned int irb = 1; | 1081 | unsigned int irb = 1; |
1081 | int i; | 1082 | int i; |
1082 | 1083 | ||
1083 | input = fujitsu_hotkey->input; | 1084 | input = fujitsu_laptop->input; |
1084 | 1085 | ||
1085 | if (event != ACPI_FUJITSU_NOTIFY_CODE1) { | 1086 | if (event != ACPI_FUJITSU_NOTIFY_CODE1) { |
1086 | keycode = KEY_UNKNOWN; | 1087 | keycode = KEY_UNKNOWN; |
@@ -1093,9 +1094,9 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event) | |||
1093 | return; | 1094 | return; |
1094 | } | 1095 | } |
1095 | 1096 | ||
1096 | if (fujitsu_hotkey->rfkill_supported) | 1097 | if (fujitsu_laptop->flags_supported) |
1097 | fujitsu_hotkey->rfkill_state = | 1098 | fujitsu_laptop->flags_state = |
1098 | call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0); | 1099 | call_fext_func(FUNC_FLAGS, 0x4, 0x0, 0x0); |
1099 | 1100 | ||
1100 | i = 0; | 1101 | i = 0; |
1101 | while ((irb = | 1102 | while ((irb = |
@@ -1103,19 +1104,19 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event) | |||
1103 | && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) { | 1104 | && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) { |
1104 | switch (irb & 0x4ff) { | 1105 | switch (irb & 0x4ff) { |
1105 | case KEY1_CODE: | 1106 | case KEY1_CODE: |
1106 | keycode = fujitsu->keycode1; | 1107 | keycode = fujitsu_bl->keycode1; |
1107 | break; | 1108 | break; |
1108 | case KEY2_CODE: | 1109 | case KEY2_CODE: |
1109 | keycode = fujitsu->keycode2; | 1110 | keycode = fujitsu_bl->keycode2; |
1110 | break; | 1111 | break; |
1111 | case KEY3_CODE: | 1112 | case KEY3_CODE: |
1112 | keycode = fujitsu->keycode3; | 1113 | keycode = fujitsu_bl->keycode3; |
1113 | break; | 1114 | break; |
1114 | case KEY4_CODE: | 1115 | case KEY4_CODE: |
1115 | keycode = fujitsu->keycode4; | 1116 | keycode = fujitsu_bl->keycode4; |
1116 | break; | 1117 | break; |
1117 | case KEY5_CODE: | 1118 | case KEY5_CODE: |
1118 | keycode = fujitsu->keycode5; | 1119 | keycode = fujitsu_bl->keycode5; |
1119 | break; | 1120 | break; |
1120 | case 0: | 1121 | case 0: |
1121 | keycode = 0; | 1122 | keycode = 0; |
@@ -1128,17 +1129,17 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event) | |||
1128 | } | 1129 | } |
1129 | 1130 | ||
1130 | if (keycode > 0) | 1131 | if (keycode > 0) |
1131 | acpi_fujitsu_hotkey_press(keycode); | 1132 | acpi_fujitsu_laptop_press(keycode); |
1132 | else if (keycode == 0) | 1133 | else if (keycode == 0) |
1133 | acpi_fujitsu_hotkey_release(); | 1134 | acpi_fujitsu_laptop_release(); |
1134 | } | 1135 | } |
1135 | 1136 | ||
1136 | /* On some models (first seen on the Skylake-based Lifebook | 1137 | /* On some models (first seen on the Skylake-based Lifebook |
1137 | * E736/E746/E756), the touchpad toggle hotkey (Fn+F4) is | 1138 | * E736/E746/E756), the touchpad toggle hotkey (Fn+F4) is |
1138 | * handled in software; its state is queried using FUNC_RFKILL | 1139 | * handled in software; its state is queried using FUNC_FLAGS |
1139 | */ | 1140 | */ |
1140 | if ((fujitsu_hotkey->rfkill_supported & BIT(26)) && | 1141 | if ((fujitsu_laptop->flags_supported & BIT(26)) && |
1141 | (call_fext_func(FUNC_RFKILL, 0x1, 0x0, 0x0) & BIT(26))) { | 1142 | (call_fext_func(FUNC_FLAGS, 0x1, 0x0, 0x0) & BIT(26))) { |
1142 | keycode = KEY_TOUCHPAD_TOGGLE; | 1143 | keycode = KEY_TOUCHPAD_TOGGLE; |
1143 | input_report_key(input, keycode, 1); | 1144 | input_report_key(input, keycode, 1); |
1144 | input_sync(input); | 1145 | input_sync(input); |
@@ -1150,83 +1151,81 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event) | |||
1150 | 1151 | ||
1151 | /* Initialization */ | 1152 | /* Initialization */ |
1152 | 1153 | ||
1153 | static const struct acpi_device_id fujitsu_device_ids[] = { | 1154 | static const struct acpi_device_id fujitsu_bl_device_ids[] = { |
1154 | {ACPI_FUJITSU_HID, 0}, | 1155 | {ACPI_FUJITSU_BL_HID, 0}, |
1155 | {"", 0}, | 1156 | {"", 0}, |
1156 | }; | 1157 | }; |
1157 | 1158 | ||
1158 | static struct acpi_driver acpi_fujitsu_driver = { | 1159 | static struct acpi_driver acpi_fujitsu_bl_driver = { |
1159 | .name = ACPI_FUJITSU_DRIVER_NAME, | 1160 | .name = ACPI_FUJITSU_BL_DRIVER_NAME, |
1160 | .class = ACPI_FUJITSU_CLASS, | 1161 | .class = ACPI_FUJITSU_CLASS, |
1161 | .ids = fujitsu_device_ids, | 1162 | .ids = fujitsu_bl_device_ids, |
1162 | .ops = { | 1163 | .ops = { |
1163 | .add = acpi_fujitsu_add, | 1164 | .add = acpi_fujitsu_bl_add, |
1164 | .remove = acpi_fujitsu_remove, | 1165 | .remove = acpi_fujitsu_bl_remove, |
1165 | .notify = acpi_fujitsu_notify, | 1166 | .notify = acpi_fujitsu_bl_notify, |
1166 | }, | 1167 | }, |
1167 | }; | 1168 | }; |
1168 | 1169 | ||
1169 | static const struct acpi_device_id fujitsu_hotkey_device_ids[] = { | 1170 | static const struct acpi_device_id fujitsu_laptop_device_ids[] = { |
1170 | {ACPI_FUJITSU_HOTKEY_HID, 0}, | 1171 | {ACPI_FUJITSU_LAPTOP_HID, 0}, |
1171 | {"", 0}, | 1172 | {"", 0}, |
1172 | }; | 1173 | }; |
1173 | 1174 | ||
1174 | static struct acpi_driver acpi_fujitsu_hotkey_driver = { | 1175 | static struct acpi_driver acpi_fujitsu_laptop_driver = { |
1175 | .name = ACPI_FUJITSU_HOTKEY_DRIVER_NAME, | 1176 | .name = ACPI_FUJITSU_LAPTOP_DRIVER_NAME, |
1176 | .class = ACPI_FUJITSU_CLASS, | 1177 | .class = ACPI_FUJITSU_CLASS, |
1177 | .ids = fujitsu_hotkey_device_ids, | 1178 | .ids = fujitsu_laptop_device_ids, |
1178 | .ops = { | 1179 | .ops = { |
1179 | .add = acpi_fujitsu_hotkey_add, | 1180 | .add = acpi_fujitsu_laptop_add, |
1180 | .remove = acpi_fujitsu_hotkey_remove, | 1181 | .remove = acpi_fujitsu_laptop_remove, |
1181 | .notify = acpi_fujitsu_hotkey_notify, | 1182 | .notify = acpi_fujitsu_laptop_notify, |
1182 | }, | 1183 | }, |
1183 | }; | 1184 | }; |
1184 | 1185 | ||
1185 | static const struct acpi_device_id fujitsu_ids[] __used = { | 1186 | static const struct acpi_device_id fujitsu_ids[] __used = { |
1186 | {ACPI_FUJITSU_HID, 0}, | 1187 | {ACPI_FUJITSU_BL_HID, 0}, |
1187 | {ACPI_FUJITSU_HOTKEY_HID, 0}, | 1188 | {ACPI_FUJITSU_LAPTOP_HID, 0}, |
1188 | {"", 0} | 1189 | {"", 0} |
1189 | }; | 1190 | }; |
1190 | MODULE_DEVICE_TABLE(acpi, fujitsu_ids); | 1191 | MODULE_DEVICE_TABLE(acpi, fujitsu_ids); |
1191 | 1192 | ||
1192 | static int __init fujitsu_init(void) | 1193 | static int __init fujitsu_init(void) |
1193 | { | 1194 | { |
1194 | int ret, result, max_brightness; | 1195 | int ret, max_brightness; |
1195 | 1196 | ||
1196 | if (acpi_disabled) | 1197 | if (acpi_disabled) |
1197 | return -ENODEV; | 1198 | return -ENODEV; |
1198 | 1199 | ||
1199 | fujitsu = kzalloc(sizeof(struct fujitsu_t), GFP_KERNEL); | 1200 | fujitsu_bl = kzalloc(sizeof(struct fujitsu_bl), GFP_KERNEL); |
1200 | if (!fujitsu) | 1201 | if (!fujitsu_bl) |
1201 | return -ENOMEM; | 1202 | return -ENOMEM; |
1202 | fujitsu->keycode1 = KEY_PROG1; | 1203 | fujitsu_bl->keycode1 = KEY_PROG1; |
1203 | fujitsu->keycode2 = KEY_PROG2; | 1204 | fujitsu_bl->keycode2 = KEY_PROG2; |
1204 | fujitsu->keycode3 = KEY_PROG3; | 1205 | fujitsu_bl->keycode3 = KEY_PROG3; |
1205 | fujitsu->keycode4 = KEY_PROG4; | 1206 | fujitsu_bl->keycode4 = KEY_PROG4; |
1206 | fujitsu->keycode5 = KEY_RFKILL; | 1207 | fujitsu_bl->keycode5 = KEY_RFKILL; |
1207 | dmi_check_system(fujitsu_dmi_table); | 1208 | dmi_check_system(fujitsu_dmi_table); |
1208 | 1209 | ||
1209 | result = acpi_bus_register_driver(&acpi_fujitsu_driver); | 1210 | ret = acpi_bus_register_driver(&acpi_fujitsu_bl_driver); |
1210 | if (result < 0) { | 1211 | if (ret) |
1211 | ret = -ENODEV; | ||
1212 | goto fail_acpi; | 1212 | goto fail_acpi; |
1213 | } | ||
1214 | 1213 | ||
1215 | /* Register platform stuff */ | 1214 | /* Register platform stuff */ |
1216 | 1215 | ||
1217 | fujitsu->pf_device = platform_device_alloc("fujitsu-laptop", -1); | 1216 | fujitsu_bl->pf_device = platform_device_alloc("fujitsu-laptop", -1); |
1218 | if (!fujitsu->pf_device) { | 1217 | if (!fujitsu_bl->pf_device) { |
1219 | ret = -ENOMEM; | 1218 | ret = -ENOMEM; |
1220 | goto fail_platform_driver; | 1219 | goto fail_platform_driver; |
1221 | } | 1220 | } |
1222 | 1221 | ||
1223 | ret = platform_device_add(fujitsu->pf_device); | 1222 | ret = platform_device_add(fujitsu_bl->pf_device); |
1224 | if (ret) | 1223 | if (ret) |
1225 | goto fail_platform_device1; | 1224 | goto fail_platform_device1; |
1226 | 1225 | ||
1227 | ret = | 1226 | ret = |
1228 | sysfs_create_group(&fujitsu->pf_device->dev.kobj, | 1227 | sysfs_create_group(&fujitsu_bl->pf_device->dev.kobj, |
1229 | &fujitsupf_attribute_group); | 1228 | &fujitsu_pf_attribute_group); |
1230 | if (ret) | 1229 | if (ret) |
1231 | goto fail_platform_device2; | 1230 | goto fail_platform_device2; |
1232 | 1231 | ||
@@ -1236,90 +1235,88 @@ static int __init fujitsu_init(void) | |||
1236 | struct backlight_properties props; | 1235 | struct backlight_properties props; |
1237 | 1236 | ||
1238 | memset(&props, 0, sizeof(struct backlight_properties)); | 1237 | memset(&props, 0, sizeof(struct backlight_properties)); |
1239 | max_brightness = fujitsu->max_brightness; | 1238 | max_brightness = fujitsu_bl->max_brightness; |
1240 | props.type = BACKLIGHT_PLATFORM; | 1239 | props.type = BACKLIGHT_PLATFORM; |
1241 | props.max_brightness = max_brightness - 1; | 1240 | props.max_brightness = max_brightness - 1; |
1242 | fujitsu->bl_device = backlight_device_register("fujitsu-laptop", | 1241 | fujitsu_bl->bl_device = backlight_device_register("fujitsu-laptop", |
1243 | NULL, NULL, | 1242 | NULL, NULL, |
1244 | &fujitsubl_ops, | 1243 | &fujitsu_bl_ops, |
1245 | &props); | 1244 | &props); |
1246 | if (IS_ERR(fujitsu->bl_device)) { | 1245 | if (IS_ERR(fujitsu_bl->bl_device)) { |
1247 | ret = PTR_ERR(fujitsu->bl_device); | 1246 | ret = PTR_ERR(fujitsu_bl->bl_device); |
1248 | fujitsu->bl_device = NULL; | 1247 | fujitsu_bl->bl_device = NULL; |
1249 | goto fail_sysfs_group; | 1248 | goto fail_sysfs_group; |
1250 | } | 1249 | } |
1251 | fujitsu->bl_device->props.brightness = fujitsu->brightness_level; | 1250 | fujitsu_bl->bl_device->props.brightness = fujitsu_bl->brightness_level; |
1252 | } | 1251 | } |
1253 | 1252 | ||
1254 | ret = platform_driver_register(&fujitsupf_driver); | 1253 | ret = platform_driver_register(&fujitsu_pf_driver); |
1255 | if (ret) | 1254 | if (ret) |
1256 | goto fail_backlight; | 1255 | goto fail_backlight; |
1257 | 1256 | ||
1258 | /* Register hotkey driver */ | 1257 | /* Register laptop driver */ |
1259 | 1258 | ||
1260 | fujitsu_hotkey = kzalloc(sizeof(struct fujitsu_hotkey_t), GFP_KERNEL); | 1259 | fujitsu_laptop = kzalloc(sizeof(struct fujitsu_laptop), GFP_KERNEL); |
1261 | if (!fujitsu_hotkey) { | 1260 | if (!fujitsu_laptop) { |
1262 | ret = -ENOMEM; | 1261 | ret = -ENOMEM; |
1263 | goto fail_hotkey; | 1262 | goto fail_laptop; |
1264 | } | 1263 | } |
1265 | 1264 | ||
1266 | result = acpi_bus_register_driver(&acpi_fujitsu_hotkey_driver); | 1265 | ret = acpi_bus_register_driver(&acpi_fujitsu_laptop_driver); |
1267 | if (result < 0) { | 1266 | if (ret) |
1268 | ret = -ENODEV; | 1267 | goto fail_laptop1; |
1269 | goto fail_hotkey1; | ||
1270 | } | ||
1271 | 1268 | ||
1272 | /* Sync backlight power status (needs FUJ02E3 device, hence deferred) */ | 1269 | /* Sync backlight power status (needs FUJ02E3 device, hence deferred) */ |
1273 | if (acpi_video_get_backlight_type() == acpi_backlight_vendor) { | 1270 | if (acpi_video_get_backlight_type() == acpi_backlight_vendor) { |
1274 | if (call_fext_func(FUNC_BACKLIGHT, 0x2, 0x4, 0x0) == 3) | 1271 | if (call_fext_func(FUNC_BACKLIGHT, 0x2, 0x4, 0x0) == 3) |
1275 | fujitsu->bl_device->props.power = FB_BLANK_POWERDOWN; | 1272 | fujitsu_bl->bl_device->props.power = FB_BLANK_POWERDOWN; |
1276 | else | 1273 | else |
1277 | fujitsu->bl_device->props.power = FB_BLANK_UNBLANK; | 1274 | fujitsu_bl->bl_device->props.power = FB_BLANK_UNBLANK; |
1278 | } | 1275 | } |
1279 | 1276 | ||
1280 | pr_info("driver " FUJITSU_DRIVER_VERSION " successfully loaded\n"); | 1277 | pr_info("driver " FUJITSU_DRIVER_VERSION " successfully loaded\n"); |
1281 | 1278 | ||
1282 | return 0; | 1279 | return 0; |
1283 | 1280 | ||
1284 | fail_hotkey1: | 1281 | fail_laptop1: |
1285 | kfree(fujitsu_hotkey); | 1282 | kfree(fujitsu_laptop); |
1286 | fail_hotkey: | 1283 | fail_laptop: |
1287 | platform_driver_unregister(&fujitsupf_driver); | 1284 | platform_driver_unregister(&fujitsu_pf_driver); |
1288 | fail_backlight: | 1285 | fail_backlight: |
1289 | backlight_device_unregister(fujitsu->bl_device); | 1286 | backlight_device_unregister(fujitsu_bl->bl_device); |
1290 | fail_sysfs_group: | 1287 | fail_sysfs_group: |
1291 | sysfs_remove_group(&fujitsu->pf_device->dev.kobj, | 1288 | sysfs_remove_group(&fujitsu_bl->pf_device->dev.kobj, |
1292 | &fujitsupf_attribute_group); | 1289 | &fujitsu_pf_attribute_group); |
1293 | fail_platform_device2: | 1290 | fail_platform_device2: |
1294 | platform_device_del(fujitsu->pf_device); | 1291 | platform_device_del(fujitsu_bl->pf_device); |
1295 | fail_platform_device1: | 1292 | fail_platform_device1: |
1296 | platform_device_put(fujitsu->pf_device); | 1293 | platform_device_put(fujitsu_bl->pf_device); |
1297 | fail_platform_driver: | 1294 | fail_platform_driver: |
1298 | acpi_bus_unregister_driver(&acpi_fujitsu_driver); | 1295 | acpi_bus_unregister_driver(&acpi_fujitsu_bl_driver); |
1299 | fail_acpi: | 1296 | fail_acpi: |
1300 | kfree(fujitsu); | 1297 | kfree(fujitsu_bl); |
1301 | 1298 | ||
1302 | return ret; | 1299 | return ret; |
1303 | } | 1300 | } |
1304 | 1301 | ||
1305 | static void __exit fujitsu_cleanup(void) | 1302 | static void __exit fujitsu_cleanup(void) |
1306 | { | 1303 | { |
1307 | acpi_bus_unregister_driver(&acpi_fujitsu_hotkey_driver); | 1304 | acpi_bus_unregister_driver(&acpi_fujitsu_laptop_driver); |
1308 | 1305 | ||
1309 | kfree(fujitsu_hotkey); | 1306 | kfree(fujitsu_laptop); |
1310 | 1307 | ||
1311 | platform_driver_unregister(&fujitsupf_driver); | 1308 | platform_driver_unregister(&fujitsu_pf_driver); |
1312 | 1309 | ||
1313 | backlight_device_unregister(fujitsu->bl_device); | 1310 | backlight_device_unregister(fujitsu_bl->bl_device); |
1314 | 1311 | ||
1315 | sysfs_remove_group(&fujitsu->pf_device->dev.kobj, | 1312 | sysfs_remove_group(&fujitsu_bl->pf_device->dev.kobj, |
1316 | &fujitsupf_attribute_group); | 1313 | &fujitsu_pf_attribute_group); |
1317 | 1314 | ||
1318 | platform_device_unregister(fujitsu->pf_device); | 1315 | platform_device_unregister(fujitsu_bl->pf_device); |
1319 | 1316 | ||
1320 | acpi_bus_unregister_driver(&acpi_fujitsu_driver); | 1317 | acpi_bus_unregister_driver(&acpi_fujitsu_bl_driver); |
1321 | 1318 | ||
1322 | kfree(fujitsu); | 1319 | kfree(fujitsu_bl); |
1323 | 1320 | ||
1324 | pr_info("driver unloaded\n"); | 1321 | pr_info("driver unloaded\n"); |
1325 | } | 1322 | } |
@@ -1341,7 +1338,3 @@ MODULE_AUTHOR("Jonathan Woithe, Peter Gruber, Tony Vroon"); | |||
1341 | MODULE_DESCRIPTION("Fujitsu laptop extras support"); | 1338 | MODULE_DESCRIPTION("Fujitsu laptop extras support"); |
1342 | MODULE_VERSION(FUJITSU_DRIVER_VERSION); | 1339 | MODULE_VERSION(FUJITSU_DRIVER_VERSION); |
1343 | MODULE_LICENSE("GPL"); | 1340 | MODULE_LICENSE("GPL"); |
1344 | |||
1345 | MODULE_ALIAS("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*"); | ||
1346 | MODULE_ALIAS("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1E6:*:cvrS6420:*"); | ||
1347 | MODULE_ALIAS("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*"); | ||
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 230043c1c90f..4bf55b5d78be 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -1241,19 +1241,32 @@ config SCSI_LPFC | |||
1241 | tristate "Emulex LightPulse Fibre Channel Support" | 1241 | tristate "Emulex LightPulse Fibre Channel Support" |
1242 | depends on PCI && SCSI | 1242 | depends on PCI && SCSI |
1243 | depends on SCSI_FC_ATTRS | 1243 | depends on SCSI_FC_ATTRS |
1244 | depends on NVME_FC && NVME_TARGET_FC | ||
1245 | select CRC_T10DIF | 1244 | select CRC_T10DIF |
1246 | help | 1245 | ---help--- |
1247 | This lpfc driver supports the Emulex LightPulse | 1246 | This lpfc driver supports the Emulex LightPulse |
1248 | Family of Fibre Channel PCI host adapters. | 1247 | Family of Fibre Channel PCI host adapters. |
1249 | 1248 | ||
1250 | config SCSI_LPFC_DEBUG_FS | 1249 | config SCSI_LPFC_DEBUG_FS |
1251 | bool "Emulex LightPulse Fibre Channel debugfs Support" | 1250 | bool "Emulex LightPulse Fibre Channel debugfs Support" |
1252 | depends on SCSI_LPFC && DEBUG_FS | 1251 | depends on SCSI_LPFC && DEBUG_FS |
1253 | help | 1252 | ---help--- |
1254 | This makes debugging information from the lpfc driver | 1253 | This makes debugging information from the lpfc driver |
1255 | available via the debugfs filesystem. | 1254 | available via the debugfs filesystem. |
1256 | 1255 | ||
1256 | config LPFC_NVME_INITIATOR | ||
1257 | bool "Emulex LightPulse Fibre Channel NVME Initiator Support" | ||
1258 | depends on SCSI_LPFC && NVME_FC | ||
1259 | ---help--- | ||
1260 | This enables NVME Initiator support in the Emulex lpfc driver. | ||
1261 | |||
1262 | config LPFC_NVME_TARGET | ||
1263 | bool "Emulex LightPulse Fibre Channel NVME Initiator Support" | ||
1264 | depends on SCSI_LPFC && NVME_TARGET_FC | ||
1265 | ---help--- | ||
1266 | This enables NVME Target support in the Emulex lpfc driver. | ||
1267 | Target enablement must still be enabled on a per adapter | ||
1268 | basis by module parameters. | ||
1269 | |||
1257 | config SCSI_SIM710 | 1270 | config SCSI_SIM710 |
1258 | tristate "Simple 53c710 SCSI support (Compaq, NCR machines)" | 1271 | tristate "Simple 53c710 SCSI support (Compaq, NCR machines)" |
1259 | depends on (EISA || MCA) && SCSI | 1272 | depends on (EISA || MCA) && SCSI |
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index 2e5338dec621..7b0410e0f569 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c | |||
@@ -468,7 +468,7 @@ err_out: | |||
468 | return -1; | 468 | return -1; |
469 | 469 | ||
470 | err_blink: | 470 | err_blink: |
471 | return (status > 16) & 0xFF; | 471 | return (status >> 16) & 0xFF; |
472 | } | 472 | } |
473 | 473 | ||
474 | static inline u32 aac_get_vector(struct aac_dev *dev) | 474 | static inline u32 aac_get_vector(struct aac_dev *dev) |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 07c08ce68d70..894b1e3ebd56 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -561,8 +561,12 @@ static void iscsi_complete_task(struct iscsi_task *task, int state) | |||
561 | WARN_ON_ONCE(task->state == ISCSI_TASK_FREE); | 561 | WARN_ON_ONCE(task->state == ISCSI_TASK_FREE); |
562 | task->state = state; | 562 | task->state = state; |
563 | 563 | ||
564 | if (!list_empty(&task->running)) | 564 | spin_lock_bh(&conn->taskqueuelock); |
565 | if (!list_empty(&task->running)) { | ||
566 | pr_debug_once("%s while task on list", __func__); | ||
565 | list_del_init(&task->running); | 567 | list_del_init(&task->running); |
568 | } | ||
569 | spin_unlock_bh(&conn->taskqueuelock); | ||
566 | 570 | ||
567 | if (conn->task == task) | 571 | if (conn->task == task) |
568 | conn->task = NULL; | 572 | conn->task = NULL; |
@@ -784,7 +788,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
784 | if (session->tt->xmit_task(task)) | 788 | if (session->tt->xmit_task(task)) |
785 | goto free_task; | 789 | goto free_task; |
786 | } else { | 790 | } else { |
791 | spin_lock_bh(&conn->taskqueuelock); | ||
787 | list_add_tail(&task->running, &conn->mgmtqueue); | 792 | list_add_tail(&task->running, &conn->mgmtqueue); |
793 | spin_unlock_bh(&conn->taskqueuelock); | ||
788 | iscsi_conn_queue_work(conn); | 794 | iscsi_conn_queue_work(conn); |
789 | } | 795 | } |
790 | 796 | ||
@@ -1475,8 +1481,10 @@ void iscsi_requeue_task(struct iscsi_task *task) | |||
1475 | * this may be on the requeue list already if the xmit_task callout | 1481 | * this may be on the requeue list already if the xmit_task callout |
1476 | * is handling the r2ts while we are adding new ones | 1482 | * is handling the r2ts while we are adding new ones |
1477 | */ | 1483 | */ |
1484 | spin_lock_bh(&conn->taskqueuelock); | ||
1478 | if (list_empty(&task->running)) | 1485 | if (list_empty(&task->running)) |
1479 | list_add_tail(&task->running, &conn->requeue); | 1486 | list_add_tail(&task->running, &conn->requeue); |
1487 | spin_unlock_bh(&conn->taskqueuelock); | ||
1480 | iscsi_conn_queue_work(conn); | 1488 | iscsi_conn_queue_work(conn); |
1481 | } | 1489 | } |
1482 | EXPORT_SYMBOL_GPL(iscsi_requeue_task); | 1490 | EXPORT_SYMBOL_GPL(iscsi_requeue_task); |
@@ -1513,22 +1521,26 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
1513 | * only have one nop-out as a ping from us and targets should not | 1521 | * only have one nop-out as a ping from us and targets should not |
1514 | * overflow us with nop-ins | 1522 | * overflow us with nop-ins |
1515 | */ | 1523 | */ |
1524 | spin_lock_bh(&conn->taskqueuelock); | ||
1516 | check_mgmt: | 1525 | check_mgmt: |
1517 | while (!list_empty(&conn->mgmtqueue)) { | 1526 | while (!list_empty(&conn->mgmtqueue)) { |
1518 | conn->task = list_entry(conn->mgmtqueue.next, | 1527 | conn->task = list_entry(conn->mgmtqueue.next, |
1519 | struct iscsi_task, running); | 1528 | struct iscsi_task, running); |
1520 | list_del_init(&conn->task->running); | 1529 | list_del_init(&conn->task->running); |
1530 | spin_unlock_bh(&conn->taskqueuelock); | ||
1521 | if (iscsi_prep_mgmt_task(conn, conn->task)) { | 1531 | if (iscsi_prep_mgmt_task(conn, conn->task)) { |
1522 | /* regular RX path uses back_lock */ | 1532 | /* regular RX path uses back_lock */ |
1523 | spin_lock_bh(&conn->session->back_lock); | 1533 | spin_lock_bh(&conn->session->back_lock); |
1524 | __iscsi_put_task(conn->task); | 1534 | __iscsi_put_task(conn->task); |
1525 | spin_unlock_bh(&conn->session->back_lock); | 1535 | spin_unlock_bh(&conn->session->back_lock); |
1526 | conn->task = NULL; | 1536 | conn->task = NULL; |
1537 | spin_lock_bh(&conn->taskqueuelock); | ||
1527 | continue; | 1538 | continue; |
1528 | } | 1539 | } |
1529 | rc = iscsi_xmit_task(conn); | 1540 | rc = iscsi_xmit_task(conn); |
1530 | if (rc) | 1541 | if (rc) |
1531 | goto done; | 1542 | goto done; |
1543 | spin_lock_bh(&conn->taskqueuelock); | ||
1532 | } | 1544 | } |
1533 | 1545 | ||
1534 | /* process pending command queue */ | 1546 | /* process pending command queue */ |
@@ -1536,19 +1548,24 @@ check_mgmt: | |||
1536 | conn->task = list_entry(conn->cmdqueue.next, struct iscsi_task, | 1548 | conn->task = list_entry(conn->cmdqueue.next, struct iscsi_task, |
1537 | running); | 1549 | running); |
1538 | list_del_init(&conn->task->running); | 1550 | list_del_init(&conn->task->running); |
1551 | spin_unlock_bh(&conn->taskqueuelock); | ||
1539 | if (conn->session->state == ISCSI_STATE_LOGGING_OUT) { | 1552 | if (conn->session->state == ISCSI_STATE_LOGGING_OUT) { |
1540 | fail_scsi_task(conn->task, DID_IMM_RETRY); | 1553 | fail_scsi_task(conn->task, DID_IMM_RETRY); |
1554 | spin_lock_bh(&conn->taskqueuelock); | ||
1541 | continue; | 1555 | continue; |
1542 | } | 1556 | } |
1543 | rc = iscsi_prep_scsi_cmd_pdu(conn->task); | 1557 | rc = iscsi_prep_scsi_cmd_pdu(conn->task); |
1544 | if (rc) { | 1558 | if (rc) { |
1545 | if (rc == -ENOMEM || rc == -EACCES) { | 1559 | if (rc == -ENOMEM || rc == -EACCES) { |
1560 | spin_lock_bh(&conn->taskqueuelock); | ||
1546 | list_add_tail(&conn->task->running, | 1561 | list_add_tail(&conn->task->running, |
1547 | &conn->cmdqueue); | 1562 | &conn->cmdqueue); |
1548 | conn->task = NULL; | 1563 | conn->task = NULL; |
1564 | spin_unlock_bh(&conn->taskqueuelock); | ||
1549 | goto done; | 1565 | goto done; |
1550 | } else | 1566 | } else |
1551 | fail_scsi_task(conn->task, DID_ABORT); | 1567 | fail_scsi_task(conn->task, DID_ABORT); |
1568 | spin_lock_bh(&conn->taskqueuelock); | ||
1552 | continue; | 1569 | continue; |
1553 | } | 1570 | } |
1554 | rc = iscsi_xmit_task(conn); | 1571 | rc = iscsi_xmit_task(conn); |
@@ -1559,6 +1576,7 @@ check_mgmt: | |||
1559 | * we need to check the mgmt queue for nops that need to | 1576 | * we need to check the mgmt queue for nops that need to |
1560 | * be sent to aviod starvation | 1577 | * be sent to aviod starvation |
1561 | */ | 1578 | */ |
1579 | spin_lock_bh(&conn->taskqueuelock); | ||
1562 | if (!list_empty(&conn->mgmtqueue)) | 1580 | if (!list_empty(&conn->mgmtqueue)) |
1563 | goto check_mgmt; | 1581 | goto check_mgmt; |
1564 | } | 1582 | } |
@@ -1578,12 +1596,15 @@ check_mgmt: | |||
1578 | conn->task = task; | 1596 | conn->task = task; |
1579 | list_del_init(&conn->task->running); | 1597 | list_del_init(&conn->task->running); |
1580 | conn->task->state = ISCSI_TASK_RUNNING; | 1598 | conn->task->state = ISCSI_TASK_RUNNING; |
1599 | spin_unlock_bh(&conn->taskqueuelock); | ||
1581 | rc = iscsi_xmit_task(conn); | 1600 | rc = iscsi_xmit_task(conn); |
1582 | if (rc) | 1601 | if (rc) |
1583 | goto done; | 1602 | goto done; |
1603 | spin_lock_bh(&conn->taskqueuelock); | ||
1584 | if (!list_empty(&conn->mgmtqueue)) | 1604 | if (!list_empty(&conn->mgmtqueue)) |
1585 | goto check_mgmt; | 1605 | goto check_mgmt; |
1586 | } | 1606 | } |
1607 | spin_unlock_bh(&conn->taskqueuelock); | ||
1587 | spin_unlock_bh(&conn->session->frwd_lock); | 1608 | spin_unlock_bh(&conn->session->frwd_lock); |
1588 | return -ENODATA; | 1609 | return -ENODATA; |
1589 | 1610 | ||
@@ -1739,7 +1760,9 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc) | |||
1739 | goto prepd_reject; | 1760 | goto prepd_reject; |
1740 | } | 1761 | } |
1741 | } else { | 1762 | } else { |
1763 | spin_lock_bh(&conn->taskqueuelock); | ||
1742 | list_add_tail(&task->running, &conn->cmdqueue); | 1764 | list_add_tail(&task->running, &conn->cmdqueue); |
1765 | spin_unlock_bh(&conn->taskqueuelock); | ||
1743 | iscsi_conn_queue_work(conn); | 1766 | iscsi_conn_queue_work(conn); |
1744 | } | 1767 | } |
1745 | 1768 | ||
@@ -2897,6 +2920,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, | |||
2897 | INIT_LIST_HEAD(&conn->mgmtqueue); | 2920 | INIT_LIST_HEAD(&conn->mgmtqueue); |
2898 | INIT_LIST_HEAD(&conn->cmdqueue); | 2921 | INIT_LIST_HEAD(&conn->cmdqueue); |
2899 | INIT_LIST_HEAD(&conn->requeue); | 2922 | INIT_LIST_HEAD(&conn->requeue); |
2923 | spin_lock_init(&conn->taskqueuelock); | ||
2900 | INIT_WORK(&conn->xmitwork, iscsi_xmitworker); | 2924 | INIT_WORK(&conn->xmitwork, iscsi_xmitworker); |
2901 | 2925 | ||
2902 | /* allocate login_task used for the login/text sequences */ | 2926 | /* allocate login_task used for the login/text sequences */ |
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 0bba2e30b4f0..257bbdd0f0b8 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -99,12 +99,13 @@ struct lpfc_sli2_slim; | |||
99 | #define FC_MAX_ADPTMSG 64 | 99 | #define FC_MAX_ADPTMSG 64 |
100 | 100 | ||
101 | #define MAX_HBAEVT 32 | 101 | #define MAX_HBAEVT 32 |
102 | #define MAX_HBAS_NO_RESET 16 | ||
102 | 103 | ||
103 | /* Number of MSI-X vectors the driver uses */ | 104 | /* Number of MSI-X vectors the driver uses */ |
104 | #define LPFC_MSIX_VECTORS 2 | 105 | #define LPFC_MSIX_VECTORS 2 |
105 | 106 | ||
106 | /* lpfc wait event data ready flag */ | 107 | /* lpfc wait event data ready flag */ |
107 | #define LPFC_DATA_READY (1<<0) | 108 | #define LPFC_DATA_READY 0 /* bit 0 */ |
108 | 109 | ||
109 | /* queue dump line buffer size */ | 110 | /* queue dump line buffer size */ |
110 | #define LPFC_LBUF_SZ 128 | 111 | #define LPFC_LBUF_SZ 128 |
@@ -692,6 +693,7 @@ struct lpfc_hba { | |||
692 | * capability | 693 | * capability |
693 | */ | 694 | */ |
694 | #define HBA_NVME_IOQ_FLUSH 0x80000 /* NVME IO queues flushed. */ | 695 | #define HBA_NVME_IOQ_FLUSH 0x80000 /* NVME IO queues flushed. */ |
696 | #define NVME_XRI_ABORT_EVENT 0x100000 | ||
695 | 697 | ||
696 | uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/ | 698 | uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/ |
697 | struct lpfc_dmabuf slim2p; | 699 | struct lpfc_dmabuf slim2p; |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 5c783ef7f260..5c3be3e6f5e2 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -3010,6 +3010,12 @@ MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:" | |||
3010 | static DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR, | 3010 | static DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR, |
3011 | lpfc_poll_show, lpfc_poll_store); | 3011 | lpfc_poll_show, lpfc_poll_store); |
3012 | 3012 | ||
3013 | int lpfc_no_hba_reset_cnt; | ||
3014 | unsigned long lpfc_no_hba_reset[MAX_HBAS_NO_RESET] = { | ||
3015 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | ||
3016 | module_param_array(lpfc_no_hba_reset, ulong, &lpfc_no_hba_reset_cnt, 0444); | ||
3017 | MODULE_PARM_DESC(lpfc_no_hba_reset, "WWPN of HBAs that should not be reset"); | ||
3018 | |||
3013 | LPFC_ATTR(sli_mode, 0, 0, 3, | 3019 | LPFC_ATTR(sli_mode, 0, 0, 3, |
3014 | "SLI mode selector:" | 3020 | "SLI mode selector:" |
3015 | " 0 - auto (SLI-3 if supported)," | 3021 | " 0 - auto (SLI-3 if supported)," |
@@ -4451,7 +4457,8 @@ lpfc_fcp_imax_store(struct device *dev, struct device_attribute *attr, | |||
4451 | return -EINVAL; | 4457 | return -EINVAL; |
4452 | 4458 | ||
4453 | phba->cfg_fcp_imax = (uint32_t)val; | 4459 | phba->cfg_fcp_imax = (uint32_t)val; |
4454 | for (i = 0; i < phba->io_channel_irqs; i++) | 4460 | |
4461 | for (i = 0; i < phba->io_channel_irqs; i += LPFC_MAX_EQ_DELAY_EQID_CNT) | ||
4455 | lpfc_modify_hba_eq_delay(phba, i); | 4462 | lpfc_modify_hba_eq_delay(phba, i); |
4456 | 4463 | ||
4457 | return strlen(buf); | 4464 | return strlen(buf); |
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 843dd73004da..54e6ac42fbcd 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -384,7 +384,7 @@ void lpfc_free_sysfs_attr(struct lpfc_vport *); | |||
384 | extern struct device_attribute *lpfc_hba_attrs[]; | 384 | extern struct device_attribute *lpfc_hba_attrs[]; |
385 | extern struct device_attribute *lpfc_vport_attrs[]; | 385 | extern struct device_attribute *lpfc_vport_attrs[]; |
386 | extern struct scsi_host_template lpfc_template; | 386 | extern struct scsi_host_template lpfc_template; |
387 | extern struct scsi_host_template lpfc_template_s3; | 387 | extern struct scsi_host_template lpfc_template_no_hr; |
388 | extern struct scsi_host_template lpfc_template_nvme; | 388 | extern struct scsi_host_template lpfc_template_nvme; |
389 | extern struct scsi_host_template lpfc_vport_template; | 389 | extern struct scsi_host_template lpfc_vport_template; |
390 | extern struct fc_function_template lpfc_transport_functions; | 390 | extern struct fc_function_template lpfc_transport_functions; |
@@ -554,3 +554,5 @@ void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba, | |||
554 | struct lpfc_wcqe_complete *abts_cmpl); | 554 | struct lpfc_wcqe_complete *abts_cmpl); |
555 | extern int lpfc_enable_nvmet_cnt; | 555 | extern int lpfc_enable_nvmet_cnt; |
556 | extern unsigned long long lpfc_enable_nvmet[]; | 556 | extern unsigned long long lpfc_enable_nvmet[]; |
557 | extern int lpfc_no_hba_reset_cnt; | ||
558 | extern unsigned long lpfc_no_hba_reset[]; | ||
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index c22bb3f887e1..d3e9af983015 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -939,8 +939,8 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
939 | "FC4 x%08x, Data: x%08x x%08x\n", | 939 | "FC4 x%08x, Data: x%08x x%08x\n", |
940 | ndlp, did, ndlp->nlp_fc4_type, | 940 | ndlp, did, ndlp->nlp_fc4_type, |
941 | FC_TYPE_FCP, FC_TYPE_NVME); | 941 | FC_TYPE_FCP, FC_TYPE_NVME); |
942 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | ||
942 | } | 943 | } |
943 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | ||
944 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE); | 944 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE); |
945 | lpfc_issue_els_prli(vport, ndlp, 0); | 945 | lpfc_issue_els_prli(vport, ndlp, 0); |
946 | } else | 946 | } else |
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 9f4798e9d938..913eed822cb8 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c | |||
@@ -3653,17 +3653,6 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf, | |||
3653 | idiag.ptr_private = phba->sli4_hba.nvmels_cq; | 3653 | idiag.ptr_private = phba->sli4_hba.nvmels_cq; |
3654 | goto pass_check; | 3654 | goto pass_check; |
3655 | } | 3655 | } |
3656 | /* NVME LS complete queue */ | ||
3657 | if (phba->sli4_hba.nvmels_cq && | ||
3658 | phba->sli4_hba.nvmels_cq->queue_id == queid) { | ||
3659 | /* Sanity check */ | ||
3660 | rc = lpfc_idiag_que_param_check( | ||
3661 | phba->sli4_hba.nvmels_cq, index, count); | ||
3662 | if (rc) | ||
3663 | goto error_out; | ||
3664 | idiag.ptr_private = phba->sli4_hba.nvmels_cq; | ||
3665 | goto pass_check; | ||
3666 | } | ||
3667 | /* FCP complete queue */ | 3656 | /* FCP complete queue */ |
3668 | if (phba->sli4_hba.fcp_cq) { | 3657 | if (phba->sli4_hba.fcp_cq) { |
3669 | for (qidx = 0; qidx < phba->cfg_fcp_io_channel; | 3658 | for (qidx = 0; qidx < phba->cfg_fcp_io_channel; |
@@ -3738,17 +3727,6 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf, | |||
3738 | idiag.ptr_private = phba->sli4_hba.nvmels_wq; | 3727 | idiag.ptr_private = phba->sli4_hba.nvmels_wq; |
3739 | goto pass_check; | 3728 | goto pass_check; |
3740 | } | 3729 | } |
3741 | /* NVME LS work queue */ | ||
3742 | if (phba->sli4_hba.nvmels_wq && | ||
3743 | phba->sli4_hba.nvmels_wq->queue_id == queid) { | ||
3744 | /* Sanity check */ | ||
3745 | rc = lpfc_idiag_que_param_check( | ||
3746 | phba->sli4_hba.nvmels_wq, index, count); | ||
3747 | if (rc) | ||
3748 | goto error_out; | ||
3749 | idiag.ptr_private = phba->sli4_hba.nvmels_wq; | ||
3750 | goto pass_check; | ||
3751 | } | ||
3752 | /* FCP work queue */ | 3730 | /* FCP work queue */ |
3753 | if (phba->sli4_hba.fcp_wq) { | 3731 | if (phba->sli4_hba.fcp_wq) { |
3754 | for (qidx = 0; qidx < phba->cfg_fcp_io_channel; | 3732 | for (qidx = 0; qidx < phba->cfg_fcp_io_channel; |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 2d26440e6f2f..d9c61d030034 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -5177,15 +5177,15 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba) | |||
5177 | 5177 | ||
5178 | static uint32_t | 5178 | static uint32_t |
5179 | lpfc_rdp_res_diag_port_names(struct fc_rdp_port_name_desc *desc, | 5179 | lpfc_rdp_res_diag_port_names(struct fc_rdp_port_name_desc *desc, |
5180 | struct lpfc_hba *phba) | 5180 | struct lpfc_vport *vport) |
5181 | { | 5181 | { |
5182 | 5182 | ||
5183 | desc->tag = cpu_to_be32(RDP_PORT_NAMES_DESC_TAG); | 5183 | desc->tag = cpu_to_be32(RDP_PORT_NAMES_DESC_TAG); |
5184 | 5184 | ||
5185 | memcpy(desc->port_names.wwnn, phba->wwnn, | 5185 | memcpy(desc->port_names.wwnn, &vport->fc_nodename, |
5186 | sizeof(desc->port_names.wwnn)); | 5186 | sizeof(desc->port_names.wwnn)); |
5187 | 5187 | ||
5188 | memcpy(desc->port_names.wwpn, phba->wwpn, | 5188 | memcpy(desc->port_names.wwpn, &vport->fc_portname, |
5189 | sizeof(desc->port_names.wwpn)); | 5189 | sizeof(desc->port_names.wwpn)); |
5190 | 5190 | ||
5191 | desc->length = cpu_to_be32(sizeof(desc->port_names)); | 5191 | desc->length = cpu_to_be32(sizeof(desc->port_names)); |
@@ -5279,7 +5279,7 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, | |||
5279 | len += lpfc_rdp_res_link_error((struct fc_rdp_link_error_status_desc *) | 5279 | len += lpfc_rdp_res_link_error((struct fc_rdp_link_error_status_desc *) |
5280 | (len + pcmd), &rdp_context->link_stat); | 5280 | (len + pcmd), &rdp_context->link_stat); |
5281 | len += lpfc_rdp_res_diag_port_names((struct fc_rdp_port_name_desc *) | 5281 | len += lpfc_rdp_res_diag_port_names((struct fc_rdp_port_name_desc *) |
5282 | (len + pcmd), phba); | 5282 | (len + pcmd), vport); |
5283 | len += lpfc_rdp_res_attach_port_names((struct fc_rdp_port_name_desc *) | 5283 | len += lpfc_rdp_res_attach_port_names((struct fc_rdp_port_name_desc *) |
5284 | (len + pcmd), vport, ndlp); | 5284 | (len + pcmd), vport, ndlp); |
5285 | len += lpfc_rdp_res_fec_desc((struct fc_fec_rdp_desc *)(len + pcmd), | 5285 | len += lpfc_rdp_res_fec_desc((struct fc_fec_rdp_desc *)(len + pcmd), |
@@ -8371,11 +8371,17 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
8371 | spin_lock_irq(shost->host_lock); | 8371 | spin_lock_irq(shost->host_lock); |
8372 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 8372 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
8373 | spin_unlock_irq(shost->host_lock); | 8373 | spin_unlock_irq(shost->host_lock); |
8374 | if (vport->port_type == LPFC_PHYSICAL_PORT | 8374 | if (mb->mbxStatus == MBX_NOT_FINISHED) |
8375 | && !(vport->fc_flag & FC_LOGO_RCVD_DID_CHNG)) | 8375 | break; |
8376 | lpfc_issue_init_vfi(vport); | 8376 | if ((vport->port_type == LPFC_PHYSICAL_PORT) && |
8377 | else | 8377 | !(vport->fc_flag & FC_LOGO_RCVD_DID_CHNG)) { |
8378 | if (phba->sli_rev == LPFC_SLI_REV4) | ||
8379 | lpfc_issue_init_vfi(vport); | ||
8380 | else | ||
8381 | lpfc_initial_flogi(vport); | ||
8382 | } else { | ||
8378 | lpfc_initial_fdisc(vport); | 8383 | lpfc_initial_fdisc(vport); |
8384 | } | ||
8379 | break; | 8385 | break; |
8380 | } | 8386 | } |
8381 | } else { | 8387 | } else { |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 194a14d5f8a9..180b072beef6 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -313,8 +313,7 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
313 | ndlp->nlp_state, ndlp->nlp_rpi); | 313 | ndlp->nlp_state, ndlp->nlp_rpi); |
314 | } | 314 | } |
315 | 315 | ||
316 | if (!(vport->load_flag & FC_UNLOADING) && | 316 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO) && |
317 | !(ndlp->nlp_flag & NLP_DELAY_TMO) && | ||
318 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && | 317 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && |
319 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) && | 318 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) && |
320 | (ndlp->nlp_state != NLP_STE_REG_LOGIN_ISSUE) && | 319 | (ndlp->nlp_state != NLP_STE_REG_LOGIN_ISSUE) && |
@@ -641,6 +640,8 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
641 | lpfc_handle_rrq_active(phba); | 640 | lpfc_handle_rrq_active(phba); |
642 | if (phba->hba_flag & FCP_XRI_ABORT_EVENT) | 641 | if (phba->hba_flag & FCP_XRI_ABORT_EVENT) |
643 | lpfc_sli4_fcp_xri_abort_event_proc(phba); | 642 | lpfc_sli4_fcp_xri_abort_event_proc(phba); |
643 | if (phba->hba_flag & NVME_XRI_ABORT_EVENT) | ||
644 | lpfc_sli4_nvme_xri_abort_event_proc(phba); | ||
644 | if (phba->hba_flag & ELS_XRI_ABORT_EVENT) | 645 | if (phba->hba_flag & ELS_XRI_ABORT_EVENT) |
645 | lpfc_sli4_els_xri_abort_event_proc(phba); | 646 | lpfc_sli4_els_xri_abort_event_proc(phba); |
646 | if (phba->hba_flag & ASYNC_EVENT) | 647 | if (phba->hba_flag & ASYNC_EVENT) |
@@ -2173,7 +2174,7 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
2173 | uint32_t boot_flag, addr_mode; | 2174 | uint32_t boot_flag, addr_mode; |
2174 | uint16_t fcf_index, next_fcf_index; | 2175 | uint16_t fcf_index, next_fcf_index; |
2175 | struct lpfc_fcf_rec *fcf_rec = NULL; | 2176 | struct lpfc_fcf_rec *fcf_rec = NULL; |
2176 | uint16_t vlan_id; | 2177 | uint16_t vlan_id = LPFC_FCOE_NULL_VID; |
2177 | bool select_new_fcf; | 2178 | bool select_new_fcf; |
2178 | int rc; | 2179 | int rc; |
2179 | 2180 | ||
@@ -4020,9 +4021,11 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
4020 | rdata = rport->dd_data; | 4021 | rdata = rport->dd_data; |
4021 | /* break the link before dropping the ref */ | 4022 | /* break the link before dropping the ref */ |
4022 | ndlp->rport = NULL; | 4023 | ndlp->rport = NULL; |
4023 | if (rdata && rdata->pnode == ndlp) | 4024 | if (rdata) { |
4024 | lpfc_nlp_put(ndlp); | 4025 | if (rdata->pnode == ndlp) |
4025 | rdata->pnode = NULL; | 4026 | lpfc_nlp_put(ndlp); |
4027 | rdata->pnode = NULL; | ||
4028 | } | ||
4026 | /* drop reference for earlier registeration */ | 4029 | /* drop reference for earlier registeration */ |
4027 | put_device(&rport->dev); | 4030 | put_device(&rport->dev); |
4028 | } | 4031 | } |
@@ -4344,9 +4347,8 @@ lpfc_initialize_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
4344 | { | 4347 | { |
4345 | INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp); | 4348 | INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp); |
4346 | INIT_LIST_HEAD(&ndlp->dev_loss_evt.evt_listp); | 4349 | INIT_LIST_HEAD(&ndlp->dev_loss_evt.evt_listp); |
4347 | init_timer(&ndlp->nlp_delayfunc); | 4350 | setup_timer(&ndlp->nlp_delayfunc, lpfc_els_retry_delay, |
4348 | ndlp->nlp_delayfunc.function = lpfc_els_retry_delay; | 4351 | (unsigned long)ndlp); |
4349 | ndlp->nlp_delayfunc.data = (unsigned long)ndlp; | ||
4350 | ndlp->nlp_DID = did; | 4352 | ndlp->nlp_DID = did; |
4351 | ndlp->vport = vport; | 4353 | ndlp->vport = vport; |
4352 | ndlp->phba = vport->phba; | 4354 | ndlp->phba = vport->phba; |
@@ -4606,9 +4608,9 @@ lpfc_sli4_dequeue_nport_iocbs(struct lpfc_hba *phba, | |||
4606 | pring = qp->pring; | 4608 | pring = qp->pring; |
4607 | if (!pring) | 4609 | if (!pring) |
4608 | continue; | 4610 | continue; |
4609 | spin_lock_irq(&pring->ring_lock); | 4611 | spin_lock(&pring->ring_lock); |
4610 | __lpfc_dequeue_nport_iocbs(phba, ndlp, pring, dequeue_list); | 4612 | __lpfc_dequeue_nport_iocbs(phba, ndlp, pring, dequeue_list); |
4611 | spin_unlock_irq(&pring->ring_lock); | 4613 | spin_unlock(&pring->ring_lock); |
4612 | } | 4614 | } |
4613 | spin_unlock_irq(&phba->hbalock); | 4615 | spin_unlock_irq(&phba->hbalock); |
4614 | } | 4616 | } |
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index cfdb068a3bfc..15277705cb6b 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
@@ -1001,7 +1001,7 @@ struct eq_delay_info { | |||
1001 | uint32_t phase; | 1001 | uint32_t phase; |
1002 | uint32_t delay_multi; | 1002 | uint32_t delay_multi; |
1003 | }; | 1003 | }; |
1004 | #define LPFC_MAX_EQ_DELAY 8 | 1004 | #define LPFC_MAX_EQ_DELAY_EQID_CNT 8 |
1005 | 1005 | ||
1006 | struct sgl_page_pairs { | 1006 | struct sgl_page_pairs { |
1007 | uint32_t sgl_pg0_addr_lo; | 1007 | uint32_t sgl_pg0_addr_lo; |
@@ -1070,7 +1070,7 @@ struct lpfc_mbx_modify_eq_delay { | |||
1070 | union { | 1070 | union { |
1071 | struct { | 1071 | struct { |
1072 | uint32_t num_eq; | 1072 | uint32_t num_eq; |
1073 | struct eq_delay_info eq[LPFC_MAX_EQ_DELAY]; | 1073 | struct eq_delay_info eq[LPFC_MAX_EQ_DELAY_EQID_CNT]; |
1074 | } request; | 1074 | } request; |
1075 | struct { | 1075 | struct { |
1076 | uint32_t word0; | 1076 | uint32_t word0; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 0ee429d773f3..2697d49da4d7 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -3555,6 +3555,44 @@ out_free_mem: | |||
3555 | return rc; | 3555 | return rc; |
3556 | } | 3556 | } |
3557 | 3557 | ||
3558 | static uint64_t | ||
3559 | lpfc_get_wwpn(struct lpfc_hba *phba) | ||
3560 | { | ||
3561 | uint64_t wwn; | ||
3562 | int rc; | ||
3563 | LPFC_MBOXQ_t *mboxq; | ||
3564 | MAILBOX_t *mb; | ||
3565 | |||
3566 | |||
3567 | mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, | ||
3568 | GFP_KERNEL); | ||
3569 | if (!mboxq) | ||
3570 | return (uint64_t)-1; | ||
3571 | |||
3572 | /* First get WWN of HBA instance */ | ||
3573 | lpfc_read_nv(phba, mboxq); | ||
3574 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
3575 | if (rc != MBX_SUCCESS) { | ||
3576 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
3577 | "6019 Mailbox failed , mbxCmd x%x " | ||
3578 | "READ_NV, mbxStatus x%x\n", | ||
3579 | bf_get(lpfc_mqe_command, &mboxq->u.mqe), | ||
3580 | bf_get(lpfc_mqe_status, &mboxq->u.mqe)); | ||
3581 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
3582 | return (uint64_t) -1; | ||
3583 | } | ||
3584 | mb = &mboxq->u.mb; | ||
3585 | memcpy(&wwn, (char *)mb->un.varRDnvp.portname, sizeof(uint64_t)); | ||
3586 | /* wwn is WWPN of HBA instance */ | ||
3587 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
3588 | if (phba->sli_rev == LPFC_SLI_REV4) | ||
3589 | return be64_to_cpu(wwn); | ||
3590 | else | ||
3591 | return (((wwn & 0xffffffff00000000) >> 32) | | ||
3592 | ((wwn & 0x00000000ffffffff) << 32)); | ||
3593 | |||
3594 | } | ||
3595 | |||
3558 | /** | 3596 | /** |
3559 | * lpfc_sli4_nvme_sgl_update - update xri-sgl sizing and mapping | 3597 | * lpfc_sli4_nvme_sgl_update - update xri-sgl sizing and mapping |
3560 | * @phba: pointer to lpfc hba data structure. | 3598 | * @phba: pointer to lpfc hba data structure. |
@@ -3676,17 +3714,32 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) | |||
3676 | struct lpfc_vport *vport; | 3714 | struct lpfc_vport *vport; |
3677 | struct Scsi_Host *shost = NULL; | 3715 | struct Scsi_Host *shost = NULL; |
3678 | int error = 0; | 3716 | int error = 0; |
3717 | int i; | ||
3718 | uint64_t wwn; | ||
3719 | bool use_no_reset_hba = false; | ||
3720 | |||
3721 | wwn = lpfc_get_wwpn(phba); | ||
3722 | |||
3723 | for (i = 0; i < lpfc_no_hba_reset_cnt; i++) { | ||
3724 | if (wwn == lpfc_no_hba_reset[i]) { | ||
3725 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
3726 | "6020 Setting use_no_reset port=%llx\n", | ||
3727 | wwn); | ||
3728 | use_no_reset_hba = true; | ||
3729 | break; | ||
3730 | } | ||
3731 | } | ||
3679 | 3732 | ||
3680 | if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP) { | 3733 | if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP) { |
3681 | if (dev != &phba->pcidev->dev) { | 3734 | if (dev != &phba->pcidev->dev) { |
3682 | shost = scsi_host_alloc(&lpfc_vport_template, | 3735 | shost = scsi_host_alloc(&lpfc_vport_template, |
3683 | sizeof(struct lpfc_vport)); | 3736 | sizeof(struct lpfc_vport)); |
3684 | } else { | 3737 | } else { |
3685 | if (phba->sli_rev == LPFC_SLI_REV4) | 3738 | if (!use_no_reset_hba) |
3686 | shost = scsi_host_alloc(&lpfc_template, | 3739 | shost = scsi_host_alloc(&lpfc_template, |
3687 | sizeof(struct lpfc_vport)); | 3740 | sizeof(struct lpfc_vport)); |
3688 | else | 3741 | else |
3689 | shost = scsi_host_alloc(&lpfc_template_s3, | 3742 | shost = scsi_host_alloc(&lpfc_template_no_hr, |
3690 | sizeof(struct lpfc_vport)); | 3743 | sizeof(struct lpfc_vport)); |
3691 | } | 3744 | } |
3692 | } else if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { | 3745 | } else if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { |
@@ -3734,17 +3787,14 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) | |||
3734 | INIT_LIST_HEAD(&vport->rcv_buffer_list); | 3787 | INIT_LIST_HEAD(&vport->rcv_buffer_list); |
3735 | spin_lock_init(&vport->work_port_lock); | 3788 | spin_lock_init(&vport->work_port_lock); |
3736 | 3789 | ||
3737 | init_timer(&vport->fc_disctmo); | 3790 | setup_timer(&vport->fc_disctmo, lpfc_disc_timeout, |
3738 | vport->fc_disctmo.function = lpfc_disc_timeout; | 3791 | (unsigned long)vport); |
3739 | vport->fc_disctmo.data = (unsigned long)vport; | ||
3740 | 3792 | ||
3741 | init_timer(&vport->els_tmofunc); | 3793 | setup_timer(&vport->els_tmofunc, lpfc_els_timeout, |
3742 | vport->els_tmofunc.function = lpfc_els_timeout; | 3794 | (unsigned long)vport); |
3743 | vport->els_tmofunc.data = (unsigned long)vport; | ||
3744 | 3795 | ||
3745 | init_timer(&vport->delayed_disc_tmo); | 3796 | setup_timer(&vport->delayed_disc_tmo, lpfc_delayed_disc_tmo, |
3746 | vport->delayed_disc_tmo.function = lpfc_delayed_disc_tmo; | 3797 | (unsigned long)vport); |
3747 | vport->delayed_disc_tmo.data = (unsigned long)vport; | ||
3748 | 3798 | ||
3749 | error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev); | 3799 | error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev); |
3750 | if (error) | 3800 | if (error) |
@@ -5406,21 +5456,15 @@ lpfc_setup_driver_resource_phase1(struct lpfc_hba *phba) | |||
5406 | INIT_LIST_HEAD(&phba->luns); | 5456 | INIT_LIST_HEAD(&phba->luns); |
5407 | 5457 | ||
5408 | /* MBOX heartbeat timer */ | 5458 | /* MBOX heartbeat timer */ |
5409 | init_timer(&psli->mbox_tmo); | 5459 | setup_timer(&psli->mbox_tmo, lpfc_mbox_timeout, (unsigned long)phba); |
5410 | psli->mbox_tmo.function = lpfc_mbox_timeout; | ||
5411 | psli->mbox_tmo.data = (unsigned long) phba; | ||
5412 | /* Fabric block timer */ | 5460 | /* Fabric block timer */ |
5413 | init_timer(&phba->fabric_block_timer); | 5461 | setup_timer(&phba->fabric_block_timer, lpfc_fabric_block_timeout, |
5414 | phba->fabric_block_timer.function = lpfc_fabric_block_timeout; | 5462 | (unsigned long)phba); |
5415 | phba->fabric_block_timer.data = (unsigned long) phba; | ||
5416 | /* EA polling mode timer */ | 5463 | /* EA polling mode timer */ |
5417 | init_timer(&phba->eratt_poll); | 5464 | setup_timer(&phba->eratt_poll, lpfc_poll_eratt, |
5418 | phba->eratt_poll.function = lpfc_poll_eratt; | 5465 | (unsigned long)phba); |
5419 | phba->eratt_poll.data = (unsigned long) phba; | ||
5420 | /* Heartbeat timer */ | 5466 | /* Heartbeat timer */ |
5421 | init_timer(&phba->hb_tmofunc); | 5467 | setup_timer(&phba->hb_tmofunc, lpfc_hb_timeout, (unsigned long)phba); |
5422 | phba->hb_tmofunc.function = lpfc_hb_timeout; | ||
5423 | phba->hb_tmofunc.data = (unsigned long)phba; | ||
5424 | 5468 | ||
5425 | return 0; | 5469 | return 0; |
5426 | } | 5470 | } |
@@ -5446,9 +5490,8 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) | |||
5446 | */ | 5490 | */ |
5447 | 5491 | ||
5448 | /* FCP polling mode timer */ | 5492 | /* FCP polling mode timer */ |
5449 | init_timer(&phba->fcp_poll_timer); | 5493 | setup_timer(&phba->fcp_poll_timer, lpfc_poll_timeout, |
5450 | phba->fcp_poll_timer.function = lpfc_poll_timeout; | 5494 | (unsigned long)phba); |
5451 | phba->fcp_poll_timer.data = (unsigned long) phba; | ||
5452 | 5495 | ||
5453 | /* Host attention work mask setup */ | 5496 | /* Host attention work mask setup */ |
5454 | phba->work_ha_mask = (HA_ERATT | HA_MBATT | HA_LATT); | 5497 | phba->work_ha_mask = (HA_ERATT | HA_MBATT | HA_LATT); |
@@ -5482,7 +5525,8 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) | |||
5482 | 5525 | ||
5483 | /* Initialize the host templates the configured values. */ | 5526 | /* Initialize the host templates the configured values. */ |
5484 | lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt; | 5527 | lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt; |
5485 | lpfc_template_s3.sg_tablesize = phba->cfg_sg_seg_cnt; | 5528 | lpfc_template_no_hr.sg_tablesize = phba->cfg_sg_seg_cnt; |
5529 | lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt; | ||
5486 | 5530 | ||
5487 | /* There are going to be 2 reserved BDEs: 1 FCP cmnd + 1 FCP rsp */ | 5531 | /* There are going to be 2 reserved BDEs: 1 FCP cmnd + 1 FCP rsp */ |
5488 | if (phba->cfg_enable_bg) { | 5532 | if (phba->cfg_enable_bg) { |
@@ -5617,14 +5661,11 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
5617 | * Initialize timers used by driver | 5661 | * Initialize timers used by driver |
5618 | */ | 5662 | */ |
5619 | 5663 | ||
5620 | init_timer(&phba->rrq_tmr); | 5664 | setup_timer(&phba->rrq_tmr, lpfc_rrq_timeout, (unsigned long)phba); |
5621 | phba->rrq_tmr.function = lpfc_rrq_timeout; | ||
5622 | phba->rrq_tmr.data = (unsigned long)phba; | ||
5623 | 5665 | ||
5624 | /* FCF rediscover timer */ | 5666 | /* FCF rediscover timer */ |
5625 | init_timer(&phba->fcf.redisc_wait); | 5667 | setup_timer(&phba->fcf.redisc_wait, lpfc_sli4_fcf_redisc_wait_tmo, |
5626 | phba->fcf.redisc_wait.function = lpfc_sli4_fcf_redisc_wait_tmo; | 5668 | (unsigned long)phba); |
5627 | phba->fcf.redisc_wait.data = (unsigned long)phba; | ||
5628 | 5669 | ||
5629 | /* | 5670 | /* |
5630 | * Control structure for handling external multi-buffer mailbox | 5671 | * Control structure for handling external multi-buffer mailbox |
@@ -5706,6 +5747,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
5706 | /* Initialize the host templates with the updated values. */ | 5747 | /* Initialize the host templates with the updated values. */ |
5707 | lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt; | 5748 | lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt; |
5708 | lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt; | 5749 | lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt; |
5750 | lpfc_template_no_hr.sg_tablesize = phba->cfg_sg_seg_cnt; | ||
5709 | 5751 | ||
5710 | if (phba->cfg_sg_dma_buf_size <= LPFC_MIN_SG_SLI4_BUF_SZ) | 5752 | if (phba->cfg_sg_dma_buf_size <= LPFC_MIN_SG_SLI4_BUF_SZ) |
5711 | phba->cfg_sg_dma_buf_size = LPFC_MIN_SG_SLI4_BUF_SZ; | 5753 | phba->cfg_sg_dma_buf_size = LPFC_MIN_SG_SLI4_BUF_SZ; |
@@ -5736,6 +5778,8 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
5736 | /* Initialize the Abort nvme buffer list used by driver */ | 5778 | /* Initialize the Abort nvme buffer list used by driver */ |
5737 | spin_lock_init(&phba->sli4_hba.abts_nvme_buf_list_lock); | 5779 | spin_lock_init(&phba->sli4_hba.abts_nvme_buf_list_lock); |
5738 | INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_nvme_buf_list); | 5780 | INIT_LIST_HEAD(&phba->sli4_hba.lpfc_abts_nvme_buf_list); |
5781 | /* Fast-path XRI aborted CQ Event work queue list */ | ||
5782 | INIT_LIST_HEAD(&phba->sli4_hba.sp_nvme_xri_aborted_work_queue); | ||
5739 | } | 5783 | } |
5740 | 5784 | ||
5741 | /* This abort list used by worker thread */ | 5785 | /* This abort list used by worker thread */ |
@@ -8712,12 +8756,9 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) | |||
8712 | } | 8756 | } |
8713 | } | 8757 | } |
8714 | 8758 | ||
8715 | /* | 8759 | for (qidx = 0; qidx < io_channel; qidx += LPFC_MAX_EQ_DELAY_EQID_CNT) |
8716 | * Configure EQ delay multipier for interrupt coalescing using | ||
8717 | * MODIFY_EQ_DELAY for all EQs created, LPFC_MAX_EQ_DELAY at a time. | ||
8718 | */ | ||
8719 | for (qidx = 0; qidx < io_channel; qidx += LPFC_MAX_EQ_DELAY) | ||
8720 | lpfc_modify_hba_eq_delay(phba, qidx); | 8760 | lpfc_modify_hba_eq_delay(phba, qidx); |
8761 | |||
8721 | return 0; | 8762 | return 0; |
8722 | 8763 | ||
8723 | out_destroy: | 8764 | out_destroy: |
@@ -8973,6 +9014,11 @@ lpfc_sli4_cq_event_release_all(struct lpfc_hba *phba) | |||
8973 | /* Pending ELS XRI abort events */ | 9014 | /* Pending ELS XRI abort events */ |
8974 | list_splice_init(&phba->sli4_hba.sp_els_xri_aborted_work_queue, | 9015 | list_splice_init(&phba->sli4_hba.sp_els_xri_aborted_work_queue, |
8975 | &cqelist); | 9016 | &cqelist); |
9017 | if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { | ||
9018 | /* Pending NVME XRI abort events */ | ||
9019 | list_splice_init(&phba->sli4_hba.sp_nvme_xri_aborted_work_queue, | ||
9020 | &cqelist); | ||
9021 | } | ||
8976 | /* Pending asynnc events */ | 9022 | /* Pending asynnc events */ |
8977 | list_splice_init(&phba->sli4_hba.sp_asynce_work_queue, | 9023 | list_splice_init(&phba->sli4_hba.sp_asynce_work_queue, |
8978 | &cqelist); | 9024 | &cqelist); |
@@ -10400,12 +10446,7 @@ lpfc_pci_remove_one_s3(struct pci_dev *pdev) | |||
10400 | fc_remove_host(shost); | 10446 | fc_remove_host(shost); |
10401 | scsi_remove_host(shost); | 10447 | scsi_remove_host(shost); |
10402 | 10448 | ||
10403 | /* Perform ndlp cleanup on the physical port. The nvme and nvmet | ||
10404 | * localports are destroyed after to cleanup all transport memory. | ||
10405 | */ | ||
10406 | lpfc_cleanup(vport); | 10449 | lpfc_cleanup(vport); |
10407 | lpfc_nvmet_destroy_targetport(phba); | ||
10408 | lpfc_nvme_destroy_localport(vport); | ||
10409 | 10450 | ||
10410 | /* | 10451 | /* |
10411 | * Bring down the SLI Layer. This step disable all interrupts, | 10452 | * Bring down the SLI Layer. This step disable all interrupts, |
@@ -12018,6 +12059,7 @@ static struct pci_driver lpfc_driver = { | |||
12018 | .id_table = lpfc_id_table, | 12059 | .id_table = lpfc_id_table, |
12019 | .probe = lpfc_pci_probe_one, | 12060 | .probe = lpfc_pci_probe_one, |
12020 | .remove = lpfc_pci_remove_one, | 12061 | .remove = lpfc_pci_remove_one, |
12062 | .shutdown = lpfc_pci_remove_one, | ||
12021 | .suspend = lpfc_pci_suspend_one, | 12063 | .suspend = lpfc_pci_suspend_one, |
12022 | .resume = lpfc_pci_resume_one, | 12064 | .resume = lpfc_pci_resume_one, |
12023 | .err_handler = &lpfc_err_handler, | 12065 | .err_handler = &lpfc_err_handler, |
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index c61d8d692ede..5986c7957199 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c | |||
@@ -646,7 +646,6 @@ lpfc_sli4_nvmet_alloc(struct lpfc_hba *phba) | |||
646 | } | 646 | } |
647 | 647 | ||
648 | dma_buf->iocbq = lpfc_sli_get_iocbq(phba); | 648 | dma_buf->iocbq = lpfc_sli_get_iocbq(phba); |
649 | dma_buf->iocbq->iocb_flag = LPFC_IO_NVMET; | ||
650 | if (!dma_buf->iocbq) { | 649 | if (!dma_buf->iocbq) { |
651 | kfree(dma_buf->context); | 650 | kfree(dma_buf->context); |
652 | pci_pool_free(phba->lpfc_drb_pool, dma_buf->dbuf.virt, | 651 | pci_pool_free(phba->lpfc_drb_pool, dma_buf->dbuf.virt, |
@@ -658,6 +657,7 @@ lpfc_sli4_nvmet_alloc(struct lpfc_hba *phba) | |||
658 | "2621 Ran out of nvmet iocb/WQEs\n"); | 657 | "2621 Ran out of nvmet iocb/WQEs\n"); |
659 | return NULL; | 658 | return NULL; |
660 | } | 659 | } |
660 | dma_buf->iocbq->iocb_flag = LPFC_IO_NVMET; | ||
661 | nvmewqe = dma_buf->iocbq; | 661 | nvmewqe = dma_buf->iocbq; |
662 | wqe = (union lpfc_wqe128 *)&nvmewqe->wqe; | 662 | wqe = (union lpfc_wqe128 *)&nvmewqe->wqe; |
663 | /* Initialize WQE */ | 663 | /* Initialize WQE */ |
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 609a908ea9db..0a4c19081409 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c | |||
@@ -316,7 +316,7 @@ lpfc_nvme_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, | |||
316 | bf_set(wqe_dfctl, &wqe->gen_req.wge_ctl, 0); | 316 | bf_set(wqe_dfctl, &wqe->gen_req.wge_ctl, 0); |
317 | bf_set(wqe_si, &wqe->gen_req.wge_ctl, 1); | 317 | bf_set(wqe_si, &wqe->gen_req.wge_ctl, 1); |
318 | bf_set(wqe_la, &wqe->gen_req.wge_ctl, 1); | 318 | bf_set(wqe_la, &wqe->gen_req.wge_ctl, 1); |
319 | bf_set(wqe_rctl, &wqe->gen_req.wge_ctl, FC_RCTL_DD_UNSOL_CTL); | 319 | bf_set(wqe_rctl, &wqe->gen_req.wge_ctl, FC_RCTL_ELS4_REQ); |
320 | bf_set(wqe_type, &wqe->gen_req.wge_ctl, FC_TYPE_NVME); | 320 | bf_set(wqe_type, &wqe->gen_req.wge_ctl, FC_TYPE_NVME); |
321 | 321 | ||
322 | /* Word 6 */ | 322 | /* Word 6 */ |
@@ -620,15 +620,15 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport, | |||
620 | * Embed the payload in the last half of the WQE | 620 | * Embed the payload in the last half of the WQE |
621 | * WQE words 16-30 get the NVME CMD IU payload | 621 | * WQE words 16-30 get the NVME CMD IU payload |
622 | * | 622 | * |
623 | * WQE Word 16 is already setup with flags | 623 | * WQE words 16-19 get payload Words 1-4 |
624 | * WQE words 17-19 get payload Words 2-4 | ||
625 | * WQE words 20-21 get payload Words 6-7 | 624 | * WQE words 20-21 get payload Words 6-7 |
626 | * WQE words 22-29 get payload Words 16-23 | 625 | * WQE words 22-29 get payload Words 16-23 |
627 | */ | 626 | */ |
628 | wptr = &wqe->words[17]; /* WQE ptr */ | 627 | wptr = &wqe->words[16]; /* WQE ptr */ |
629 | dptr = (uint32_t *)nCmd->cmdaddr; /* payload ptr */ | 628 | dptr = (uint32_t *)nCmd->cmdaddr; /* payload ptr */ |
630 | dptr += 2; /* Skip Words 0-1 in payload */ | 629 | dptr++; /* Skip Word 0 in payload */ |
631 | 630 | ||
631 | *wptr++ = *dptr++; /* Word 1 */ | ||
632 | *wptr++ = *dptr++; /* Word 2 */ | 632 | *wptr++ = *dptr++; /* Word 2 */ |
633 | *wptr++ = *dptr++; /* Word 3 */ | 633 | *wptr++ = *dptr++; /* Word 3 */ |
634 | *wptr++ = *dptr++; /* Word 4 */ | 634 | *wptr++ = *dptr++; /* Word 4 */ |
@@ -978,9 +978,6 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport, | |||
978 | bf_set(wqe_cmd_type, &wqe->generic.wqe_com, | 978 | bf_set(wqe_cmd_type, &wqe->generic.wqe_com, |
979 | NVME_WRITE_CMD); | 979 | NVME_WRITE_CMD); |
980 | 980 | ||
981 | /* Word 16 */ | ||
982 | wqe->words[16] = LPFC_NVME_EMBED_WRITE; | ||
983 | |||
984 | phba->fc4NvmeOutputRequests++; | 981 | phba->fc4NvmeOutputRequests++; |
985 | } else { | 982 | } else { |
986 | /* Word 7 */ | 983 | /* Word 7 */ |
@@ -1002,9 +999,6 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport, | |||
1002 | bf_set(wqe_cmd_type, &wqe->generic.wqe_com, | 999 | bf_set(wqe_cmd_type, &wqe->generic.wqe_com, |
1003 | NVME_READ_CMD); | 1000 | NVME_READ_CMD); |
1004 | 1001 | ||
1005 | /* Word 16 */ | ||
1006 | wqe->words[16] = LPFC_NVME_EMBED_READ; | ||
1007 | |||
1008 | phba->fc4NvmeInputRequests++; | 1002 | phba->fc4NvmeInputRequests++; |
1009 | } | 1003 | } |
1010 | } else { | 1004 | } else { |
@@ -1026,9 +1020,6 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport, | |||
1026 | /* Word 11 */ | 1020 | /* Word 11 */ |
1027 | bf_set(wqe_cmd_type, &wqe->generic.wqe_com, NVME_READ_CMD); | 1021 | bf_set(wqe_cmd_type, &wqe->generic.wqe_com, NVME_READ_CMD); |
1028 | 1022 | ||
1029 | /* Word 16 */ | ||
1030 | wqe->words[16] = LPFC_NVME_EMBED_CMD; | ||
1031 | |||
1032 | phba->fc4NvmeControlRequests++; | 1023 | phba->fc4NvmeControlRequests++; |
1033 | } | 1024 | } |
1034 | /* | 1025 | /* |
@@ -1286,6 +1277,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, | |||
1286 | pnvme_fcreq->private = (void *)lpfc_ncmd; | 1277 | pnvme_fcreq->private = (void *)lpfc_ncmd; |
1287 | lpfc_ncmd->nvmeCmd = pnvme_fcreq; | 1278 | lpfc_ncmd->nvmeCmd = pnvme_fcreq; |
1288 | lpfc_ncmd->nrport = rport; | 1279 | lpfc_ncmd->nrport = rport; |
1280 | lpfc_ncmd->ndlp = ndlp; | ||
1289 | lpfc_ncmd->start_time = jiffies; | 1281 | lpfc_ncmd->start_time = jiffies; |
1290 | 1282 | ||
1291 | lpfc_nvme_prep_io_cmd(vport, lpfc_ncmd, ndlp); | 1283 | lpfc_nvme_prep_io_cmd(vport, lpfc_ncmd, ndlp); |
@@ -1319,7 +1311,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, | |||
1319 | "sid: x%x did: x%x oxid: x%x\n", | 1311 | "sid: x%x did: x%x oxid: x%x\n", |
1320 | ret, vport->fc_myDID, ndlp->nlp_DID, | 1312 | ret, vport->fc_myDID, ndlp->nlp_DID, |
1321 | lpfc_ncmd->cur_iocbq.sli4_xritag); | 1313 | lpfc_ncmd->cur_iocbq.sli4_xritag); |
1322 | ret = -EINVAL; | 1314 | ret = -EBUSY; |
1323 | goto out_free_nvme_buf; | 1315 | goto out_free_nvme_buf; |
1324 | } | 1316 | } |
1325 | 1317 | ||
@@ -1821,10 +1813,10 @@ lpfc_post_nvme_sgl_list(struct lpfc_hba *phba, | |||
1821 | pdma_phys_sgl1, cur_xritag); | 1813 | pdma_phys_sgl1, cur_xritag); |
1822 | if (status) { | 1814 | if (status) { |
1823 | /* failure, put on abort nvme list */ | 1815 | /* failure, put on abort nvme list */ |
1824 | lpfc_ncmd->exch_busy = 1; | 1816 | lpfc_ncmd->flags |= LPFC_SBUF_XBUSY; |
1825 | } else { | 1817 | } else { |
1826 | /* success, put on NVME buffer list */ | 1818 | /* success, put on NVME buffer list */ |
1827 | lpfc_ncmd->exch_busy = 0; | 1819 | lpfc_ncmd->flags &= ~LPFC_SBUF_XBUSY; |
1828 | lpfc_ncmd->status = IOSTAT_SUCCESS; | 1820 | lpfc_ncmd->status = IOSTAT_SUCCESS; |
1829 | num_posted++; | 1821 | num_posted++; |
1830 | } | 1822 | } |
@@ -1854,10 +1846,10 @@ lpfc_post_nvme_sgl_list(struct lpfc_hba *phba, | |||
1854 | struct lpfc_nvme_buf, list); | 1846 | struct lpfc_nvme_buf, list); |
1855 | if (status) { | 1847 | if (status) { |
1856 | /* failure, put on abort nvme list */ | 1848 | /* failure, put on abort nvme list */ |
1857 | lpfc_ncmd->exch_busy = 1; | 1849 | lpfc_ncmd->flags |= LPFC_SBUF_XBUSY; |
1858 | } else { | 1850 | } else { |
1859 | /* success, put on NVME buffer list */ | 1851 | /* success, put on NVME buffer list */ |
1860 | lpfc_ncmd->exch_busy = 0; | 1852 | lpfc_ncmd->flags &= ~LPFC_SBUF_XBUSY; |
1861 | lpfc_ncmd->status = IOSTAT_SUCCESS; | 1853 | lpfc_ncmd->status = IOSTAT_SUCCESS; |
1862 | num_posted++; | 1854 | num_posted++; |
1863 | } | 1855 | } |
@@ -2099,7 +2091,7 @@ lpfc_release_nvme_buf(struct lpfc_hba *phba, struct lpfc_nvme_buf *lpfc_ncmd) | |||
2099 | unsigned long iflag = 0; | 2091 | unsigned long iflag = 0; |
2100 | 2092 | ||
2101 | lpfc_ncmd->nonsg_phys = 0; | 2093 | lpfc_ncmd->nonsg_phys = 0; |
2102 | if (lpfc_ncmd->exch_busy) { | 2094 | if (lpfc_ncmd->flags & LPFC_SBUF_XBUSY) { |
2103 | spin_lock_irqsave(&phba->sli4_hba.abts_nvme_buf_list_lock, | 2095 | spin_lock_irqsave(&phba->sli4_hba.abts_nvme_buf_list_lock, |
2104 | iflag); | 2096 | iflag); |
2105 | lpfc_ncmd->nvmeCmd = NULL; | 2097 | lpfc_ncmd->nvmeCmd = NULL; |
@@ -2135,11 +2127,12 @@ lpfc_release_nvme_buf(struct lpfc_hba *phba, struct lpfc_nvme_buf *lpfc_ncmd) | |||
2135 | int | 2127 | int |
2136 | lpfc_nvme_create_localport(struct lpfc_vport *vport) | 2128 | lpfc_nvme_create_localport(struct lpfc_vport *vport) |
2137 | { | 2129 | { |
2130 | int ret = 0; | ||
2138 | struct lpfc_hba *phba = vport->phba; | 2131 | struct lpfc_hba *phba = vport->phba; |
2139 | struct nvme_fc_port_info nfcp_info; | 2132 | struct nvme_fc_port_info nfcp_info; |
2140 | struct nvme_fc_local_port *localport; | 2133 | struct nvme_fc_local_port *localport; |
2141 | struct lpfc_nvme_lport *lport; | 2134 | struct lpfc_nvme_lport *lport; |
2142 | int len, ret = 0; | 2135 | int len; |
2143 | 2136 | ||
2144 | /* Initialize this localport instance. The vport wwn usage ensures | 2137 | /* Initialize this localport instance. The vport wwn usage ensures |
2145 | * that NPIV is accounted for. | 2138 | * that NPIV is accounted for. |
@@ -2156,8 +2149,12 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport) | |||
2156 | /* localport is allocated from the stack, but the registration | 2149 | /* localport is allocated from the stack, but the registration |
2157 | * call allocates heap memory as well as the private area. | 2150 | * call allocates heap memory as well as the private area. |
2158 | */ | 2151 | */ |
2152 | #ifdef CONFIG_LPFC_NVME_INITIATOR | ||
2159 | ret = nvme_fc_register_localport(&nfcp_info, &lpfc_nvme_template, | 2153 | ret = nvme_fc_register_localport(&nfcp_info, &lpfc_nvme_template, |
2160 | &vport->phba->pcidev->dev, &localport); | 2154 | &vport->phba->pcidev->dev, &localport); |
2155 | #else | ||
2156 | ret = -ENOMEM; | ||
2157 | #endif | ||
2161 | if (!ret) { | 2158 | if (!ret) { |
2162 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME | LOG_NVME_DISC, | 2159 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME | LOG_NVME_DISC, |
2163 | "6005 Successfully registered local " | 2160 | "6005 Successfully registered local " |
@@ -2173,10 +2170,10 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport) | |||
2173 | lport->vport = vport; | 2170 | lport->vport = vport; |
2174 | INIT_LIST_HEAD(&lport->rport_list); | 2171 | INIT_LIST_HEAD(&lport->rport_list); |
2175 | vport->nvmei_support = 1; | 2172 | vport->nvmei_support = 1; |
2173 | len = lpfc_new_nvme_buf(vport, phba->sli4_hba.nvme_xri_max); | ||
2174 | vport->phba->total_nvme_bufs += len; | ||
2176 | } | 2175 | } |
2177 | 2176 | ||
2178 | len = lpfc_new_nvme_buf(vport, phba->sli4_hba.nvme_xri_max); | ||
2179 | vport->phba->total_nvme_bufs += len; | ||
2180 | return ret; | 2177 | return ret; |
2181 | } | 2178 | } |
2182 | 2179 | ||
@@ -2193,6 +2190,7 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport) | |||
2193 | void | 2190 | void |
2194 | lpfc_nvme_destroy_localport(struct lpfc_vport *vport) | 2191 | lpfc_nvme_destroy_localport(struct lpfc_vport *vport) |
2195 | { | 2192 | { |
2193 | #ifdef CONFIG_LPFC_NVME_INITIATOR | ||
2196 | struct nvme_fc_local_port *localport; | 2194 | struct nvme_fc_local_port *localport; |
2197 | struct lpfc_nvme_lport *lport; | 2195 | struct lpfc_nvme_lport *lport; |
2198 | struct lpfc_nvme_rport *rport = NULL, *rport_next = NULL; | 2196 | struct lpfc_nvme_rport *rport = NULL, *rport_next = NULL; |
@@ -2208,7 +2206,6 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport) | |||
2208 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME, | 2206 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME, |
2209 | "6011 Destroying NVME localport %p\n", | 2207 | "6011 Destroying NVME localport %p\n", |
2210 | localport); | 2208 | localport); |
2211 | |||
2212 | list_for_each_entry_safe(rport, rport_next, &lport->rport_list, list) { | 2209 | list_for_each_entry_safe(rport, rport_next, &lport->rport_list, list) { |
2213 | /* The last node ref has to get released now before the rport | 2210 | /* The last node ref has to get released now before the rport |
2214 | * private memory area is released by the transport. | 2211 | * private memory area is released by the transport. |
@@ -2222,6 +2219,7 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport) | |||
2222 | "6008 rport fail destroy %x\n", ret); | 2219 | "6008 rport fail destroy %x\n", ret); |
2223 | wait_for_completion_timeout(&rport->rport_unreg_done, 5); | 2220 | wait_for_completion_timeout(&rport->rport_unreg_done, 5); |
2224 | } | 2221 | } |
2222 | |||
2225 | /* lport's rport list is clear. Unregister | 2223 | /* lport's rport list is clear. Unregister |
2226 | * lport and release resources. | 2224 | * lport and release resources. |
2227 | */ | 2225 | */ |
@@ -2245,6 +2243,7 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport) | |||
2245 | "Failed, status x%x\n", | 2243 | "Failed, status x%x\n", |
2246 | ret); | 2244 | ret); |
2247 | } | 2245 | } |
2246 | #endif | ||
2248 | } | 2247 | } |
2249 | 2248 | ||
2250 | void | 2249 | void |
@@ -2275,6 +2274,7 @@ lpfc_nvme_update_localport(struct lpfc_vport *vport) | |||
2275 | int | 2274 | int |
2276 | lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | 2275 | lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
2277 | { | 2276 | { |
2277 | #ifdef CONFIG_LPFC_NVME_INITIATOR | ||
2278 | int ret = 0; | 2278 | int ret = 0; |
2279 | struct nvme_fc_local_port *localport; | 2279 | struct nvme_fc_local_port *localport; |
2280 | struct lpfc_nvme_lport *lport; | 2280 | struct lpfc_nvme_lport *lport; |
@@ -2348,7 +2348,6 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
2348 | rpinfo.port_role |= FC_PORT_ROLE_NVME_INITIATOR; | 2348 | rpinfo.port_role |= FC_PORT_ROLE_NVME_INITIATOR; |
2349 | rpinfo.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn); | 2349 | rpinfo.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn); |
2350 | rpinfo.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn); | 2350 | rpinfo.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn); |
2351 | |||
2352 | ret = nvme_fc_register_remoteport(localport, &rpinfo, | 2351 | ret = nvme_fc_register_remoteport(localport, &rpinfo, |
2353 | &remote_port); | 2352 | &remote_port); |
2354 | if (!ret) { | 2353 | if (!ret) { |
@@ -2384,6 +2383,9 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
2384 | ndlp->nlp_type, ndlp->nlp_DID, ndlp); | 2383 | ndlp->nlp_type, ndlp->nlp_DID, ndlp); |
2385 | } | 2384 | } |
2386 | return ret; | 2385 | return ret; |
2386 | #else | ||
2387 | return 0; | ||
2388 | #endif | ||
2387 | } | 2389 | } |
2388 | 2390 | ||
2389 | /* lpfc_nvme_unregister_port - unbind the DID and port_role from this rport. | 2391 | /* lpfc_nvme_unregister_port - unbind the DID and port_role from this rport. |
@@ -2401,6 +2403,7 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
2401 | void | 2403 | void |
2402 | lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | 2404 | lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
2403 | { | 2405 | { |
2406 | #ifdef CONFIG_LPFC_NVME_INITIATOR | ||
2404 | int ret; | 2407 | int ret; |
2405 | struct nvme_fc_local_port *localport; | 2408 | struct nvme_fc_local_port *localport; |
2406 | struct lpfc_nvme_lport *lport; | 2409 | struct lpfc_nvme_lport *lport; |
@@ -2458,7 +2461,61 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
2458 | return; | 2461 | return; |
2459 | 2462 | ||
2460 | input_err: | 2463 | input_err: |
2464 | #endif | ||
2461 | lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC, | 2465 | lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC, |
2462 | "6168: State error: lport %p, rport%p FCID x%06x\n", | 2466 | "6168: State error: lport %p, rport%p FCID x%06x\n", |
2463 | vport->localport, ndlp->rport, ndlp->nlp_DID); | 2467 | vport->localport, ndlp->rport, ndlp->nlp_DID); |
2464 | } | 2468 | } |
2469 | |||
2470 | /** | ||
2471 | * lpfc_sli4_nvme_xri_aborted - Fast-path process of NVME xri abort | ||
2472 | * @phba: pointer to lpfc hba data structure. | ||
2473 | * @axri: pointer to the fcp xri abort wcqe structure. | ||
2474 | * | ||
2475 | * This routine is invoked by the worker thread to process a SLI4 fast-path | ||
2476 | * FCP aborted xri. | ||
2477 | **/ | ||
2478 | void | ||
2479 | lpfc_sli4_nvme_xri_aborted(struct lpfc_hba *phba, | ||
2480 | struct sli4_wcqe_xri_aborted *axri) | ||
2481 | { | ||
2482 | uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri); | ||
2483 | uint16_t rxid = bf_get(lpfc_wcqe_xa_remote_xid, axri); | ||
2484 | struct lpfc_nvme_buf *lpfc_ncmd, *next_lpfc_ncmd; | ||
2485 | struct lpfc_nodelist *ndlp; | ||
2486 | unsigned long iflag = 0; | ||
2487 | int rrq_empty = 0; | ||
2488 | |||
2489 | if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) | ||
2490 | return; | ||
2491 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
2492 | spin_lock(&phba->sli4_hba.abts_nvme_buf_list_lock); | ||
2493 | list_for_each_entry_safe(lpfc_ncmd, next_lpfc_ncmd, | ||
2494 | &phba->sli4_hba.lpfc_abts_nvme_buf_list, | ||
2495 | list) { | ||
2496 | if (lpfc_ncmd->cur_iocbq.sli4_xritag == xri) { | ||
2497 | list_del(&lpfc_ncmd->list); | ||
2498 | lpfc_ncmd->flags &= ~LPFC_SBUF_XBUSY; | ||
2499 | lpfc_ncmd->status = IOSTAT_SUCCESS; | ||
2500 | spin_unlock( | ||
2501 | &phba->sli4_hba.abts_nvme_buf_list_lock); | ||
2502 | |||
2503 | rrq_empty = list_empty(&phba->active_rrq_list); | ||
2504 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
2505 | ndlp = lpfc_ncmd->ndlp; | ||
2506 | if (ndlp) { | ||
2507 | lpfc_set_rrq_active( | ||
2508 | phba, ndlp, | ||
2509 | lpfc_ncmd->cur_iocbq.sli4_lxritag, | ||
2510 | rxid, 1); | ||
2511 | lpfc_sli4_abts_err_handler(phba, ndlp, axri); | ||
2512 | } | ||
2513 | lpfc_release_nvme_buf(phba, lpfc_ncmd); | ||
2514 | if (rrq_empty) | ||
2515 | lpfc_worker_wake_up(phba); | ||
2516 | return; | ||
2517 | } | ||
2518 | } | ||
2519 | spin_unlock(&phba->sli4_hba.abts_nvme_buf_list_lock); | ||
2520 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
2521 | } | ||
diff --git a/drivers/scsi/lpfc/lpfc_nvme.h b/drivers/scsi/lpfc/lpfc_nvme.h index b2fae5e813f8..1347deb8dd6c 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.h +++ b/drivers/scsi/lpfc/lpfc_nvme.h | |||
@@ -57,6 +57,7 @@ struct lpfc_nvme_buf { | |||
57 | struct list_head list; | 57 | struct list_head list; |
58 | struct nvmefc_fcp_req *nvmeCmd; | 58 | struct nvmefc_fcp_req *nvmeCmd; |
59 | struct lpfc_nvme_rport *nrport; | 59 | struct lpfc_nvme_rport *nrport; |
60 | struct lpfc_nodelist *ndlp; | ||
60 | 61 | ||
61 | uint32_t timeout; | 62 | uint32_t timeout; |
62 | 63 | ||
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index c421e1738ee9..b7739a554fe0 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c | |||
@@ -571,6 +571,7 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport, | |||
571 | lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, | 571 | lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, |
572 | "6102 Bad state IO x%x aborted\n", | 572 | "6102 Bad state IO x%x aborted\n", |
573 | ctxp->oxid); | 573 | ctxp->oxid); |
574 | rc = -ENXIO; | ||
574 | goto aerr; | 575 | goto aerr; |
575 | } | 576 | } |
576 | 577 | ||
@@ -580,6 +581,7 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport, | |||
580 | lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, | 581 | lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, |
581 | "6152 FCP Drop IO x%x: Prep\n", | 582 | "6152 FCP Drop IO x%x: Prep\n", |
582 | ctxp->oxid); | 583 | ctxp->oxid); |
584 | rc = -ENXIO; | ||
583 | goto aerr; | 585 | goto aerr; |
584 | } | 586 | } |
585 | 587 | ||
@@ -618,8 +620,9 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport, | |||
618 | ctxp->wqeq->hba_wqidx = 0; | 620 | ctxp->wqeq->hba_wqidx = 0; |
619 | nvmewqeq->context2 = NULL; | 621 | nvmewqeq->context2 = NULL; |
620 | nvmewqeq->context3 = NULL; | 622 | nvmewqeq->context3 = NULL; |
623 | rc = -EBUSY; | ||
621 | aerr: | 624 | aerr: |
622 | return -ENXIO; | 625 | return rc; |
623 | } | 626 | } |
624 | 627 | ||
625 | static void | 628 | static void |
@@ -668,9 +671,13 @@ lpfc_nvmet_create_targetport(struct lpfc_hba *phba) | |||
668 | lpfc_tgttemplate.target_features = NVMET_FCTGTFEAT_READDATA_RSP | | 671 | lpfc_tgttemplate.target_features = NVMET_FCTGTFEAT_READDATA_RSP | |
669 | NVMET_FCTGTFEAT_NEEDS_CMD_CPUSCHED; | 672 | NVMET_FCTGTFEAT_NEEDS_CMD_CPUSCHED; |
670 | 673 | ||
674 | #ifdef CONFIG_LPFC_NVME_TARGET | ||
671 | error = nvmet_fc_register_targetport(&pinfo, &lpfc_tgttemplate, | 675 | error = nvmet_fc_register_targetport(&pinfo, &lpfc_tgttemplate, |
672 | &phba->pcidev->dev, | 676 | &phba->pcidev->dev, |
673 | &phba->targetport); | 677 | &phba->targetport); |
678 | #else | ||
679 | error = -ENOMEM; | ||
680 | #endif | ||
674 | if (error) { | 681 | if (error) { |
675 | lpfc_printf_log(phba, KERN_ERR, LOG_NVME_DISC, | 682 | lpfc_printf_log(phba, KERN_ERR, LOG_NVME_DISC, |
676 | "6025 Cannot register NVME targetport " | 683 | "6025 Cannot register NVME targetport " |
@@ -731,9 +738,25 @@ lpfc_nvmet_update_targetport(struct lpfc_hba *phba) | |||
731 | return 0; | 738 | return 0; |
732 | } | 739 | } |
733 | 740 | ||
741 | /** | ||
742 | * lpfc_sli4_nvmet_xri_aborted - Fast-path process of nvmet xri abort | ||
743 | * @phba: pointer to lpfc hba data structure. | ||
744 | * @axri: pointer to the nvmet xri abort wcqe structure. | ||
745 | * | ||
746 | * This routine is invoked by the worker thread to process a SLI4 fast-path | ||
747 | * NVMET aborted xri. | ||
748 | **/ | ||
749 | void | ||
750 | lpfc_sli4_nvmet_xri_aborted(struct lpfc_hba *phba, | ||
751 | struct sli4_wcqe_xri_aborted *axri) | ||
752 | { | ||
753 | /* TODO: work in progress */ | ||
754 | } | ||
755 | |||
734 | void | 756 | void |
735 | lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba) | 757 | lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba) |
736 | { | 758 | { |
759 | #ifdef CONFIG_LPFC_NVME_TARGET | ||
737 | struct lpfc_nvmet_tgtport *tgtp; | 760 | struct lpfc_nvmet_tgtport *tgtp; |
738 | 761 | ||
739 | if (phba->nvmet_support == 0) | 762 | if (phba->nvmet_support == 0) |
@@ -745,6 +768,7 @@ lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba) | |||
745 | wait_for_completion_timeout(&tgtp->tport_unreg_done, 5); | 768 | wait_for_completion_timeout(&tgtp->tport_unreg_done, 5); |
746 | } | 769 | } |
747 | phba->targetport = NULL; | 770 | phba->targetport = NULL; |
771 | #endif | ||
748 | } | 772 | } |
749 | 773 | ||
750 | /** | 774 | /** |
@@ -764,6 +788,7 @@ static void | |||
764 | lpfc_nvmet_unsol_ls_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 788 | lpfc_nvmet_unsol_ls_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
765 | struct hbq_dmabuf *nvmebuf) | 789 | struct hbq_dmabuf *nvmebuf) |
766 | { | 790 | { |
791 | #ifdef CONFIG_LPFC_NVME_TARGET | ||
767 | struct lpfc_nvmet_tgtport *tgtp; | 792 | struct lpfc_nvmet_tgtport *tgtp; |
768 | struct fc_frame_header *fc_hdr; | 793 | struct fc_frame_header *fc_hdr; |
769 | struct lpfc_nvmet_rcv_ctx *ctxp; | 794 | struct lpfc_nvmet_rcv_ctx *ctxp; |
@@ -844,6 +869,7 @@ dropit: | |||
844 | 869 | ||
845 | atomic_inc(&tgtp->xmt_ls_abort); | 870 | atomic_inc(&tgtp->xmt_ls_abort); |
846 | lpfc_nvmet_unsol_ls_issue_abort(phba, ctxp, sid, oxid); | 871 | lpfc_nvmet_unsol_ls_issue_abort(phba, ctxp, sid, oxid); |
872 | #endif | ||
847 | } | 873 | } |
848 | 874 | ||
849 | /** | 875 | /** |
@@ -865,6 +891,7 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba, | |||
865 | struct rqb_dmabuf *nvmebuf, | 891 | struct rqb_dmabuf *nvmebuf, |
866 | uint64_t isr_timestamp) | 892 | uint64_t isr_timestamp) |
867 | { | 893 | { |
894 | #ifdef CONFIG_LPFC_NVME_TARGET | ||
868 | struct lpfc_nvmet_rcv_ctx *ctxp; | 895 | struct lpfc_nvmet_rcv_ctx *ctxp; |
869 | struct lpfc_nvmet_tgtport *tgtp; | 896 | struct lpfc_nvmet_tgtport *tgtp; |
870 | struct fc_frame_header *fc_hdr; | 897 | struct fc_frame_header *fc_hdr; |
@@ -955,7 +982,7 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba, | |||
955 | 982 | ||
956 | atomic_inc(&tgtp->rcv_fcp_cmd_drop); | 983 | atomic_inc(&tgtp->rcv_fcp_cmd_drop); |
957 | lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, | 984 | lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, |
958 | "6159 FCP Drop IO x%x: nvmet_fc_rcv_fcp_req x%x\n", | 985 | "6159 FCP Drop IO x%x: err x%x\n", |
959 | ctxp->oxid, rc); | 986 | ctxp->oxid, rc); |
960 | dropit: | 987 | dropit: |
961 | lpfc_nvmeio_data(phba, "NVMET FCP DROP: xri x%x sz %d from %06x\n", | 988 | lpfc_nvmeio_data(phba, "NVMET FCP DROP: xri x%x sz %d from %06x\n", |
@@ -970,6 +997,7 @@ dropit: | |||
970 | /* We assume a rcv'ed cmd ALWAYs fits into 1 buffer */ | 997 | /* We assume a rcv'ed cmd ALWAYs fits into 1 buffer */ |
971 | lpfc_nvmet_rq_post(phba, NULL, &nvmebuf->hbuf); | 998 | lpfc_nvmet_rq_post(phba, NULL, &nvmebuf->hbuf); |
972 | } | 999 | } |
1000 | #endif | ||
973 | } | 1001 | } |
974 | 1002 | ||
975 | /** | 1003 | /** |
@@ -1114,7 +1142,7 @@ lpfc_nvmet_prep_ls_wqe(struct lpfc_hba *phba, | |||
1114 | bf_set(wqe_dfctl, &wqe->xmit_sequence.wge_ctl, 0); | 1142 | bf_set(wqe_dfctl, &wqe->xmit_sequence.wge_ctl, 0); |
1115 | bf_set(wqe_ls, &wqe->xmit_sequence.wge_ctl, 1); | 1143 | bf_set(wqe_ls, &wqe->xmit_sequence.wge_ctl, 1); |
1116 | bf_set(wqe_la, &wqe->xmit_sequence.wge_ctl, 0); | 1144 | bf_set(wqe_la, &wqe->xmit_sequence.wge_ctl, 0); |
1117 | bf_set(wqe_rctl, &wqe->xmit_sequence.wge_ctl, FC_RCTL_DD_SOL_CTL); | 1145 | bf_set(wqe_rctl, &wqe->xmit_sequence.wge_ctl, FC_RCTL_ELS4_REP); |
1118 | bf_set(wqe_type, &wqe->xmit_sequence.wge_ctl, FC_TYPE_NVME); | 1146 | bf_set(wqe_type, &wqe->xmit_sequence.wge_ctl, FC_TYPE_NVME); |
1119 | 1147 | ||
1120 | /* Word 6 */ | 1148 | /* Word 6 */ |
@@ -1445,7 +1473,6 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
1445 | 1473 | ||
1446 | case NVMET_FCOP_RSP: | 1474 | case NVMET_FCOP_RSP: |
1447 | /* Words 0 - 2 */ | 1475 | /* Words 0 - 2 */ |
1448 | sgel = &rsp->sg[0]; | ||
1449 | physaddr = rsp->rspdma; | 1476 | physaddr = rsp->rspdma; |
1450 | wqe->fcp_trsp.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64; | 1477 | wqe->fcp_trsp.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64; |
1451 | wqe->fcp_trsp.bde.tus.f.bdeSize = rsp->rsplen; | 1478 | wqe->fcp_trsp.bde.tus.f.bdeSize = rsp->rsplen; |
@@ -1681,8 +1708,8 @@ lpfc_nvmet_unsol_issue_abort(struct lpfc_hba *phba, | |||
1681 | struct lpfc_nodelist *ndlp; | 1708 | struct lpfc_nodelist *ndlp; |
1682 | 1709 | ||
1683 | lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, | 1710 | lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, |
1684 | "6067 %s: Entrypoint: sid %x xri %x\n", __func__, | 1711 | "6067 Abort: sid %x xri x%x/x%x\n", |
1685 | sid, xri); | 1712 | sid, xri, ctxp->wqeq->sli4_xritag); |
1686 | 1713 | ||
1687 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; | 1714 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; |
1688 | 1715 | ||
@@ -1693,7 +1720,7 @@ lpfc_nvmet_unsol_issue_abort(struct lpfc_hba *phba, | |||
1693 | atomic_inc(&tgtp->xmt_abort_rsp_error); | 1720 | atomic_inc(&tgtp->xmt_abort_rsp_error); |
1694 | lpfc_printf_log(phba, KERN_WARNING, LOG_NVME_ABTS, | 1721 | lpfc_printf_log(phba, KERN_WARNING, LOG_NVME_ABTS, |
1695 | "6134 Drop ABTS - wrong NDLP state x%x.\n", | 1722 | "6134 Drop ABTS - wrong NDLP state x%x.\n", |
1696 | ndlp->nlp_state); | 1723 | (ndlp) ? ndlp->nlp_state : NLP_STE_MAX_STATE); |
1697 | 1724 | ||
1698 | /* No failure to an ABTS request. */ | 1725 | /* No failure to an ABTS request. */ |
1699 | return 0; | 1726 | return 0; |
@@ -1791,7 +1818,7 @@ lpfc_nvmet_sol_fcp_issue_abort(struct lpfc_hba *phba, | |||
1791 | atomic_inc(&tgtp->xmt_abort_rsp_error); | 1818 | atomic_inc(&tgtp->xmt_abort_rsp_error); |
1792 | lpfc_printf_log(phba, KERN_WARNING, LOG_NVME_ABTS, | 1819 | lpfc_printf_log(phba, KERN_WARNING, LOG_NVME_ABTS, |
1793 | "6160 Drop ABTS - wrong NDLP state x%x.\n", | 1820 | "6160 Drop ABTS - wrong NDLP state x%x.\n", |
1794 | ndlp->nlp_state); | 1821 | (ndlp) ? ndlp->nlp_state : NLP_STE_MAX_STATE); |
1795 | 1822 | ||
1796 | /* No failure to an ABTS request. */ | 1823 | /* No failure to an ABTS request. */ |
1797 | return 0; | 1824 | return 0; |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 9d6384af9fce..54fd0c81ceaf 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -5953,12 +5953,13 @@ struct scsi_host_template lpfc_template_nvme = { | |||
5953 | .track_queue_depth = 0, | 5953 | .track_queue_depth = 0, |
5954 | }; | 5954 | }; |
5955 | 5955 | ||
5956 | struct scsi_host_template lpfc_template_s3 = { | 5956 | struct scsi_host_template lpfc_template_no_hr = { |
5957 | .module = THIS_MODULE, | 5957 | .module = THIS_MODULE, |
5958 | .name = LPFC_DRIVER_NAME, | 5958 | .name = LPFC_DRIVER_NAME, |
5959 | .proc_name = LPFC_DRIVER_NAME, | 5959 | .proc_name = LPFC_DRIVER_NAME, |
5960 | .info = lpfc_info, | 5960 | .info = lpfc_info, |
5961 | .queuecommand = lpfc_queuecommand, | 5961 | .queuecommand = lpfc_queuecommand, |
5962 | .eh_timed_out = fc_eh_timed_out, | ||
5962 | .eh_abort_handler = lpfc_abort_handler, | 5963 | .eh_abort_handler = lpfc_abort_handler, |
5963 | .eh_device_reset_handler = lpfc_device_reset_handler, | 5964 | .eh_device_reset_handler = lpfc_device_reset_handler, |
5964 | .eh_target_reset_handler = lpfc_target_reset_handler, | 5965 | .eh_target_reset_handler = lpfc_target_reset_handler, |
@@ -6015,7 +6016,6 @@ struct scsi_host_template lpfc_vport_template = { | |||
6015 | .eh_abort_handler = lpfc_abort_handler, | 6016 | .eh_abort_handler = lpfc_abort_handler, |
6016 | .eh_device_reset_handler = lpfc_device_reset_handler, | 6017 | .eh_device_reset_handler = lpfc_device_reset_handler, |
6017 | .eh_target_reset_handler = lpfc_target_reset_handler, | 6018 | .eh_target_reset_handler = lpfc_target_reset_handler, |
6018 | .eh_bus_reset_handler = lpfc_bus_reset_handler, | ||
6019 | .slave_alloc = lpfc_slave_alloc, | 6019 | .slave_alloc = lpfc_slave_alloc, |
6020 | .slave_configure = lpfc_slave_configure, | 6020 | .slave_configure = lpfc_slave_configure, |
6021 | .slave_destroy = lpfc_slave_destroy, | 6021 | .slave_destroy = lpfc_slave_destroy, |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index e43e5e23c24b..1c9fa45df7eb 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -1,3 +1,4 @@ | |||
1 | |||
1 | /******************************************************************* | 2 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 3 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 4 | * Fibre Channel Host Bus Adapters. * |
@@ -952,7 +953,7 @@ __lpfc_sli_get_els_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq) | |||
952 | start_sglq = sglq; | 953 | start_sglq = sglq; |
953 | while (!found) { | 954 | while (!found) { |
954 | if (!sglq) | 955 | if (!sglq) |
955 | return NULL; | 956 | break; |
956 | if (ndlp && ndlp->active_rrqs_xri_bitmap && | 957 | if (ndlp && ndlp->active_rrqs_xri_bitmap && |
957 | test_bit(sglq->sli4_lxritag, | 958 | test_bit(sglq->sli4_lxritag, |
958 | ndlp->active_rrqs_xri_bitmap)) { | 959 | ndlp->active_rrqs_xri_bitmap)) { |
@@ -12213,6 +12214,41 @@ void lpfc_sli4_fcp_xri_abort_event_proc(struct lpfc_hba *phba) | |||
12213 | } | 12214 | } |
12214 | 12215 | ||
12215 | /** | 12216 | /** |
12217 | * lpfc_sli4_nvme_xri_abort_event_proc - Process nvme xri abort event | ||
12218 | * @phba: pointer to lpfc hba data structure. | ||
12219 | * | ||
12220 | * This routine is invoked by the worker thread to process all the pending | ||
12221 | * SLI4 NVME abort XRI events. | ||
12222 | **/ | ||
12223 | void lpfc_sli4_nvme_xri_abort_event_proc(struct lpfc_hba *phba) | ||
12224 | { | ||
12225 | struct lpfc_cq_event *cq_event; | ||
12226 | |||
12227 | /* First, declare the fcp xri abort event has been handled */ | ||
12228 | spin_lock_irq(&phba->hbalock); | ||
12229 | phba->hba_flag &= ~NVME_XRI_ABORT_EVENT; | ||
12230 | spin_unlock_irq(&phba->hbalock); | ||
12231 | /* Now, handle all the fcp xri abort events */ | ||
12232 | while (!list_empty(&phba->sli4_hba.sp_nvme_xri_aborted_work_queue)) { | ||
12233 | /* Get the first event from the head of the event queue */ | ||
12234 | spin_lock_irq(&phba->hbalock); | ||
12235 | list_remove_head(&phba->sli4_hba.sp_nvme_xri_aborted_work_queue, | ||
12236 | cq_event, struct lpfc_cq_event, list); | ||
12237 | spin_unlock_irq(&phba->hbalock); | ||
12238 | /* Notify aborted XRI for NVME work queue */ | ||
12239 | if (phba->nvmet_support) { | ||
12240 | lpfc_sli4_nvmet_xri_aborted(phba, | ||
12241 | &cq_event->cqe.wcqe_axri); | ||
12242 | } else { | ||
12243 | lpfc_sli4_nvme_xri_aborted(phba, | ||
12244 | &cq_event->cqe.wcqe_axri); | ||
12245 | } | ||
12246 | /* Free the event processed back to the free pool */ | ||
12247 | lpfc_sli4_cq_event_release(phba, cq_event); | ||
12248 | } | ||
12249 | } | ||
12250 | |||
12251 | /** | ||
12216 | * lpfc_sli4_els_xri_abort_event_proc - Process els xri abort event | 12252 | * lpfc_sli4_els_xri_abort_event_proc - Process els xri abort event |
12217 | * @phba: pointer to lpfc hba data structure. | 12253 | * @phba: pointer to lpfc hba data structure. |
12218 | * | 12254 | * |
@@ -12709,10 +12745,22 @@ lpfc_sli4_sp_handle_abort_xri_wcqe(struct lpfc_hba *phba, | |||
12709 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 12745 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
12710 | workposted = true; | 12746 | workposted = true; |
12711 | break; | 12747 | break; |
12748 | case LPFC_NVME: | ||
12749 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
12750 | list_add_tail(&cq_event->list, | ||
12751 | &phba->sli4_hba.sp_nvme_xri_aborted_work_queue); | ||
12752 | /* Set the nvme xri abort event flag */ | ||
12753 | phba->hba_flag |= NVME_XRI_ABORT_EVENT; | ||
12754 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
12755 | workposted = true; | ||
12756 | break; | ||
12712 | default: | 12757 | default: |
12713 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | 12758 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
12714 | "0603 Invalid work queue CQE subtype (x%x)\n", | 12759 | "0603 Invalid CQ subtype %d: " |
12715 | cq->subtype); | 12760 | "%08x %08x %08x %08x\n", |
12761 | cq->subtype, wcqe->word0, wcqe->parameter, | ||
12762 | wcqe->word2, wcqe->word3); | ||
12763 | lpfc_sli4_cq_event_release(phba, cq_event); | ||
12716 | workposted = false; | 12764 | workposted = false; |
12717 | break; | 12765 | break; |
12718 | } | 12766 | } |
@@ -13827,6 +13875,8 @@ lpfc_dual_chute_pci_bar_map(struct lpfc_hba *phba, uint16_t pci_barset) | |||
13827 | * @startq: The starting FCP EQ to modify | 13875 | * @startq: The starting FCP EQ to modify |
13828 | * | 13876 | * |
13829 | * This function sends an MODIFY_EQ_DELAY mailbox command to the HBA. | 13877 | * This function sends an MODIFY_EQ_DELAY mailbox command to the HBA. |
13878 | * The command allows up to LPFC_MAX_EQ_DELAY_EQID_CNT EQ ID's to be | ||
13879 | * updated in one mailbox command. | ||
13830 | * | 13880 | * |
13831 | * The @phba struct is used to send mailbox command to HBA. The @startq | 13881 | * The @phba struct is used to send mailbox command to HBA. The @startq |
13832 | * is used to get the starting FCP EQ to change. | 13882 | * is used to get the starting FCP EQ to change. |
@@ -13879,7 +13929,7 @@ lpfc_modify_hba_eq_delay(struct lpfc_hba *phba, uint32_t startq) | |||
13879 | eq_delay->u.request.eq[cnt].phase = 0; | 13929 | eq_delay->u.request.eq[cnt].phase = 0; |
13880 | eq_delay->u.request.eq[cnt].delay_multi = dmult; | 13930 | eq_delay->u.request.eq[cnt].delay_multi = dmult; |
13881 | cnt++; | 13931 | cnt++; |
13882 | if (cnt >= LPFC_MAX_EQ_DELAY) | 13932 | if (cnt >= LPFC_MAX_EQ_DELAY_EQID_CNT) |
13883 | break; | 13933 | break; |
13884 | } | 13934 | } |
13885 | eq_delay->u.request.num_eq = cnt; | 13935 | eq_delay->u.request.num_eq = cnt; |
@@ -15185,17 +15235,17 @@ lpfc_mrq_create(struct lpfc_hba *phba, struct lpfc_queue **hrqp, | |||
15185 | drq = drqp[idx]; | 15235 | drq = drqp[idx]; |
15186 | cq = cqp[idx]; | 15236 | cq = cqp[idx]; |
15187 | 15237 | ||
15188 | if (hrq->entry_count != drq->entry_count) { | ||
15189 | status = -EINVAL; | ||
15190 | goto out; | ||
15191 | } | ||
15192 | |||
15193 | /* sanity check on queue memory */ | 15238 | /* sanity check on queue memory */ |
15194 | if (!hrq || !drq || !cq) { | 15239 | if (!hrq || !drq || !cq) { |
15195 | status = -ENODEV; | 15240 | status = -ENODEV; |
15196 | goto out; | 15241 | goto out; |
15197 | } | 15242 | } |
15198 | 15243 | ||
15244 | if (hrq->entry_count != drq->entry_count) { | ||
15245 | status = -EINVAL; | ||
15246 | goto out; | ||
15247 | } | ||
15248 | |||
15199 | if (idx == 0) { | 15249 | if (idx == 0) { |
15200 | bf_set(lpfc_mbx_rq_create_num_pages, | 15250 | bf_set(lpfc_mbx_rq_create_num_pages, |
15201 | &rq_create->u.request, | 15251 | &rq_create->u.request, |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 91153c9f6d18..710458cf11d6 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
@@ -642,6 +642,7 @@ struct lpfc_sli4_hba { | |||
642 | struct list_head sp_asynce_work_queue; | 642 | struct list_head sp_asynce_work_queue; |
643 | struct list_head sp_fcp_xri_aborted_work_queue; | 643 | struct list_head sp_fcp_xri_aborted_work_queue; |
644 | struct list_head sp_els_xri_aborted_work_queue; | 644 | struct list_head sp_els_xri_aborted_work_queue; |
645 | struct list_head sp_nvme_xri_aborted_work_queue; | ||
645 | struct list_head sp_unsol_work_queue; | 646 | struct list_head sp_unsol_work_queue; |
646 | struct lpfc_sli4_link link_state; | 647 | struct lpfc_sli4_link link_state; |
647 | struct lpfc_sli4_lnk_info lnk_info; | 648 | struct lpfc_sli4_lnk_info lnk_info; |
@@ -794,9 +795,14 @@ void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *); | |||
794 | int lpfc_sli4_resume_rpi(struct lpfc_nodelist *, | 795 | int lpfc_sli4_resume_rpi(struct lpfc_nodelist *, |
795 | void (*)(struct lpfc_hba *, LPFC_MBOXQ_t *), void *); | 796 | void (*)(struct lpfc_hba *, LPFC_MBOXQ_t *), void *); |
796 | void lpfc_sli4_fcp_xri_abort_event_proc(struct lpfc_hba *); | 797 | void lpfc_sli4_fcp_xri_abort_event_proc(struct lpfc_hba *); |
798 | void lpfc_sli4_nvme_xri_abort_event_proc(struct lpfc_hba *phba); | ||
797 | void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *); | 799 | void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *); |
798 | void lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *, | 800 | void lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *, |
799 | struct sli4_wcqe_xri_aborted *); | 801 | struct sli4_wcqe_xri_aborted *); |
802 | void lpfc_sli4_nvme_xri_aborted(struct lpfc_hba *phba, | ||
803 | struct sli4_wcqe_xri_aborted *axri); | ||
804 | void lpfc_sli4_nvmet_xri_aborted(struct lpfc_hba *phba, | ||
805 | struct sli4_wcqe_xri_aborted *axri); | ||
800 | void lpfc_sli4_els_xri_aborted(struct lpfc_hba *, | 806 | void lpfc_sli4_els_xri_aborted(struct lpfc_hba *, |
801 | struct sli4_wcqe_xri_aborted *); | 807 | struct sli4_wcqe_xri_aborted *); |
802 | void lpfc_sli4_vport_delete_els_xri_aborted(struct lpfc_vport *); | 808 | void lpfc_sli4_vport_delete_els_xri_aborted(struct lpfc_vport *); |
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 86c6c9b26b82..d4e95e28f4e3 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h | |||
@@ -20,7 +20,7 @@ | |||
20 | * included with this package. * | 20 | * included with this package. * |
21 | *******************************************************************/ | 21 | *******************************************************************/ |
22 | 22 | ||
23 | #define LPFC_DRIVER_VERSION "11.2.0.7" | 23 | #define LPFC_DRIVER_VERSION "11.2.0.10" |
24 | #define LPFC_DRIVER_NAME "lpfc" | 24 | #define LPFC_DRIVER_NAME "lpfc" |
25 | 25 | ||
26 | /* Used for SLI 2/3 */ | 26 | /* Used for SLI 2/3 */ |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index 7fe7e6ed595b..8981806fb13f 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h | |||
@@ -1442,9 +1442,6 @@ void mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc, | |||
1442 | u64 sas_address, u16 handle, u8 phy_number, u8 link_rate); | 1442 | u64 sas_address, u16 handle, u8 phy_number, u8 link_rate); |
1443 | extern struct sas_function_template mpt3sas_transport_functions; | 1443 | extern struct sas_function_template mpt3sas_transport_functions; |
1444 | extern struct scsi_transport_template *mpt3sas_transport_template; | 1444 | extern struct scsi_transport_template *mpt3sas_transport_template; |
1445 | extern int scsi_internal_device_block(struct scsi_device *sdev); | ||
1446 | extern int scsi_internal_device_unblock(struct scsi_device *sdev, | ||
1447 | enum scsi_device_state new_state); | ||
1448 | /* trigger data externs */ | 1445 | /* trigger data externs */ |
1449 | void mpt3sas_send_trigger_data_event(struct MPT3SAS_ADAPTER *ioc, | 1446 | void mpt3sas_send_trigger_data_event(struct MPT3SAS_ADAPTER *ioc, |
1450 | struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data); | 1447 | struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data); |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 46e866c36c8a..919ba2bb15f1 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c | |||
@@ -2859,7 +2859,7 @@ _scsih_internal_device_block(struct scsi_device *sdev, | |||
2859 | sas_device_priv_data->sas_target->handle); | 2859 | sas_device_priv_data->sas_target->handle); |
2860 | sas_device_priv_data->block = 1; | 2860 | sas_device_priv_data->block = 1; |
2861 | 2861 | ||
2862 | r = scsi_internal_device_block(sdev); | 2862 | r = scsi_internal_device_block(sdev, false); |
2863 | if (r == -EINVAL) | 2863 | if (r == -EINVAL) |
2864 | sdev_printk(KERN_WARNING, sdev, | 2864 | sdev_printk(KERN_WARNING, sdev, |
2865 | "device_block failed with return(%d) for handle(0x%04x)\n", | 2865 | "device_block failed with return(%d) for handle(0x%04x)\n", |
@@ -2895,7 +2895,7 @@ _scsih_internal_device_unblock(struct scsi_device *sdev, | |||
2895 | "performing a block followed by an unblock\n", | 2895 | "performing a block followed by an unblock\n", |
2896 | r, sas_device_priv_data->sas_target->handle); | 2896 | r, sas_device_priv_data->sas_target->handle); |
2897 | sas_device_priv_data->block = 1; | 2897 | sas_device_priv_data->block = 1; |
2898 | r = scsi_internal_device_block(sdev); | 2898 | r = scsi_internal_device_block(sdev, false); |
2899 | if (r) | 2899 | if (r) |
2900 | sdev_printk(KERN_WARNING, sdev, "retried device_block " | 2900 | sdev_printk(KERN_WARNING, sdev, "retried device_block " |
2901 | "failed with return(%d) for handle(0x%04x)\n", | 2901 | "failed with return(%d) for handle(0x%04x)\n", |
@@ -4677,7 +4677,6 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
4677 | struct MPT3SAS_DEVICE *sas_device_priv_data; | 4677 | struct MPT3SAS_DEVICE *sas_device_priv_data; |
4678 | u32 response_code = 0; | 4678 | u32 response_code = 0; |
4679 | unsigned long flags; | 4679 | unsigned long flags; |
4680 | unsigned int sector_sz; | ||
4681 | 4680 | ||
4682 | mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); | 4681 | mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); |
4683 | 4682 | ||
@@ -4742,20 +4741,6 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
4742 | } | 4741 | } |
4743 | 4742 | ||
4744 | xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); | 4743 | xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); |
4745 | |||
4746 | /* In case of bogus fw or device, we could end up having | ||
4747 | * unaligned partial completion. We can force alignment here, | ||
4748 | * then scsi-ml does not need to handle this misbehavior. | ||
4749 | */ | ||
4750 | sector_sz = scmd->device->sector_size; | ||
4751 | if (unlikely(!blk_rq_is_passthrough(scmd->request) && sector_sz && | ||
4752 | xfer_cnt % sector_sz)) { | ||
4753 | sdev_printk(KERN_INFO, scmd->device, | ||
4754 | "unaligned partial completion avoided (xfer_cnt=%u, sector_sz=%u)\n", | ||
4755 | xfer_cnt, sector_sz); | ||
4756 | xfer_cnt = round_down(xfer_cnt, sector_sz); | ||
4757 | } | ||
4758 | |||
4759 | scsi_set_resid(scmd, scsi_bufflen(scmd) - xfer_cnt); | 4744 | scsi_set_resid(scmd, scsi_bufflen(scmd) - xfer_cnt); |
4760 | if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) | 4745 | if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) |
4761 | log_info = le32_to_cpu(mpi_reply->IOCLogInfo); | 4746 | log_info = le32_to_cpu(mpi_reply->IOCLogInfo); |
diff --git a/drivers/scsi/qedf/qedf_dbg.h b/drivers/scsi/qedf/qedf_dbg.h index 23bd70628a2f..7d173f48a81e 100644 --- a/drivers/scsi/qedf/qedf_dbg.h +++ b/drivers/scsi/qedf/qedf_dbg.h | |||
@@ -81,14 +81,17 @@ struct qedf_dbg_ctx { | |||
81 | #define QEDF_INFO(pdev, level, fmt, ...) \ | 81 | #define QEDF_INFO(pdev, level, fmt, ...) \ |
82 | qedf_dbg_info(pdev, __func__, __LINE__, level, fmt, \ | 82 | qedf_dbg_info(pdev, __func__, __LINE__, level, fmt, \ |
83 | ## __VA_ARGS__) | 83 | ## __VA_ARGS__) |
84 | 84 | __printf(4, 5) | |
85 | extern void qedf_dbg_err(struct qedf_dbg_ctx *qedf, const char *func, u32 line, | 85 | void qedf_dbg_err(struct qedf_dbg_ctx *qedf, const char *func, u32 line, |
86 | const char *fmt, ...); | 86 | const char *fmt, ...); |
87 | extern void qedf_dbg_warn(struct qedf_dbg_ctx *qedf, const char *func, u32 line, | 87 | __printf(4, 5) |
88 | void qedf_dbg_warn(struct qedf_dbg_ctx *qedf, const char *func, u32 line, | ||
88 | const char *, ...); | 89 | const char *, ...); |
89 | extern void qedf_dbg_notice(struct qedf_dbg_ctx *qedf, const char *func, | 90 | __printf(4, 5) |
91 | void qedf_dbg_notice(struct qedf_dbg_ctx *qedf, const char *func, | ||
90 | u32 line, const char *, ...); | 92 | u32 line, const char *, ...); |
91 | extern void qedf_dbg_info(struct qedf_dbg_ctx *qedf, const char *func, u32 line, | 93 | __printf(5, 6) |
94 | void qedf_dbg_info(struct qedf_dbg_ctx *qedf, const char *func, u32 line, | ||
92 | u32 info, const char *fmt, ...); | 95 | u32 info, const char *fmt, ...); |
93 | 96 | ||
94 | /* GRC Dump related defines */ | 97 | /* GRC Dump related defines */ |
diff --git a/drivers/scsi/qedf/qedf_fip.c b/drivers/scsi/qedf/qedf_fip.c index 868d423380d1..ed58b9104f58 100644 --- a/drivers/scsi/qedf/qedf_fip.c +++ b/drivers/scsi/qedf/qedf_fip.c | |||
@@ -203,7 +203,7 @@ void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb) | |||
203 | case FIP_DT_MAC: | 203 | case FIP_DT_MAC: |
204 | mp = (struct fip_mac_desc *)desc; | 204 | mp = (struct fip_mac_desc *)desc; |
205 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2, | 205 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2, |
206 | "fd_mac=%pM.\n", __func__, mp->fd_mac); | 206 | "fd_mac=%pM\n", mp->fd_mac); |
207 | ether_addr_copy(cvl_mac, mp->fd_mac); | 207 | ether_addr_copy(cvl_mac, mp->fd_mac); |
208 | break; | 208 | break; |
209 | case FIP_DT_NAME: | 209 | case FIP_DT_NAME: |
diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c index ee0dcf9d3aba..46debe5034af 100644 --- a/drivers/scsi/qedf/qedf_io.c +++ b/drivers/scsi/qedf/qedf_io.c | |||
@@ -1342,7 +1342,7 @@ void qedf_scsi_completion(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, | |||
1342 | } else { | 1342 | } else { |
1343 | refcount = kref_read(&io_req->refcount); | 1343 | refcount = kref_read(&io_req->refcount); |
1344 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO, | 1344 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO, |
1345 | "%d:0:%d:%d xid=0x%0x op=0x%02x " | 1345 | "%d:0:%d:%lld xid=0x%0x op=0x%02x " |
1346 | "lba=%02x%02x%02x%02x cdb_status=%d " | 1346 | "lba=%02x%02x%02x%02x cdb_status=%d " |
1347 | "fcp_resid=0x%x refcount=%d.\n", | 1347 | "fcp_resid=0x%x refcount=%d.\n", |
1348 | qedf->lport->host->host_no, sc_cmd->device->id, | 1348 | qedf->lport->host->host_no, sc_cmd->device->id, |
@@ -1426,7 +1426,7 @@ void qedf_scsi_done(struct qedf_ctx *qedf, struct qedf_ioreq *io_req, | |||
1426 | 1426 | ||
1427 | sc_cmd->result = result << 16; | 1427 | sc_cmd->result = result << 16; |
1428 | refcount = kref_read(&io_req->refcount); | 1428 | refcount = kref_read(&io_req->refcount); |
1429 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO, "%d:0:%d:%d: Completing " | 1429 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO, "%d:0:%d:%lld: Completing " |
1430 | "sc_cmd=%p result=0x%08x op=0x%02x lba=0x%02x%02x%02x%02x, " | 1430 | "sc_cmd=%p result=0x%08x op=0x%02x lba=0x%02x%02x%02x%02x, " |
1431 | "allowed=%d retries=%d refcount=%d.\n", | 1431 | "allowed=%d retries=%d refcount=%d.\n", |
1432 | qedf->lport->host->host_no, sc_cmd->device->id, | 1432 | qedf->lport->host->host_no, sc_cmd->device->id, |
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index d9d7a86b5f8b..8e2a160490e6 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c | |||
@@ -2456,8 +2456,8 @@ static int qedf_alloc_bdq(struct qedf_ctx *qedf) | |||
2456 | } | 2456 | } |
2457 | 2457 | ||
2458 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, | 2458 | QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, |
2459 | "BDQ PBL addr=0x%p dma=0x%llx.\n", qedf->bdq_pbl, | 2459 | "BDQ PBL addr=0x%p dma=%pad\n", |
2460 | qedf->bdq_pbl_dma); | 2460 | qedf->bdq_pbl, &qedf->bdq_pbl_dma); |
2461 | 2461 | ||
2462 | /* | 2462 | /* |
2463 | * Populate BDQ PBL with physical and virtual address of individual | 2463 | * Populate BDQ PBL with physical and virtual address of individual |
diff --git a/drivers/scsi/qedi/qedi_debugfs.c b/drivers/scsi/qedi/qedi_debugfs.c index 955936274241..59417199bf36 100644 --- a/drivers/scsi/qedi/qedi_debugfs.c +++ b/drivers/scsi/qedi/qedi_debugfs.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/debugfs.h> | 14 | #include <linux/debugfs.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | 16 | ||
17 | int do_not_recover; | 17 | int qedi_do_not_recover; |
18 | static struct dentry *qedi_dbg_root; | 18 | static struct dentry *qedi_dbg_root; |
19 | 19 | ||
20 | void | 20 | void |
@@ -74,22 +74,22 @@ qedi_dbg_exit(void) | |||
74 | static ssize_t | 74 | static ssize_t |
75 | qedi_dbg_do_not_recover_enable(struct qedi_dbg_ctx *qedi_dbg) | 75 | qedi_dbg_do_not_recover_enable(struct qedi_dbg_ctx *qedi_dbg) |
76 | { | 76 | { |
77 | if (!do_not_recover) | 77 | if (!qedi_do_not_recover) |
78 | do_not_recover = 1; | 78 | qedi_do_not_recover = 1; |
79 | 79 | ||
80 | QEDI_INFO(qedi_dbg, QEDI_LOG_DEBUGFS, "do_not_recover=%d\n", | 80 | QEDI_INFO(qedi_dbg, QEDI_LOG_DEBUGFS, "do_not_recover=%d\n", |
81 | do_not_recover); | 81 | qedi_do_not_recover); |
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
84 | 84 | ||
85 | static ssize_t | 85 | static ssize_t |
86 | qedi_dbg_do_not_recover_disable(struct qedi_dbg_ctx *qedi_dbg) | 86 | qedi_dbg_do_not_recover_disable(struct qedi_dbg_ctx *qedi_dbg) |
87 | { | 87 | { |
88 | if (do_not_recover) | 88 | if (qedi_do_not_recover) |
89 | do_not_recover = 0; | 89 | qedi_do_not_recover = 0; |
90 | 90 | ||
91 | QEDI_INFO(qedi_dbg, QEDI_LOG_DEBUGFS, "do_not_recover=%d\n", | 91 | QEDI_INFO(qedi_dbg, QEDI_LOG_DEBUGFS, "do_not_recover=%d\n", |
92 | do_not_recover); | 92 | qedi_do_not_recover); |
93 | return 0; | 93 | return 0; |
94 | } | 94 | } |
95 | 95 | ||
@@ -141,7 +141,7 @@ qedi_dbg_do_not_recover_cmd_read(struct file *filp, char __user *buffer, | |||
141 | if (*ppos) | 141 | if (*ppos) |
142 | return 0; | 142 | return 0; |
143 | 143 | ||
144 | cnt = sprintf(buffer, "do_not_recover=%d\n", do_not_recover); | 144 | cnt = sprintf(buffer, "do_not_recover=%d\n", qedi_do_not_recover); |
145 | cnt = min_t(int, count, cnt - *ppos); | 145 | cnt = min_t(int, count, cnt - *ppos); |
146 | *ppos += cnt; | 146 | *ppos += cnt; |
147 | return cnt; | 147 | return cnt; |
diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c index c9f0ef4e11b3..2bce3efc66a4 100644 --- a/drivers/scsi/qedi/qedi_fw.c +++ b/drivers/scsi/qedi/qedi_fw.c | |||
@@ -1461,9 +1461,9 @@ static void qedi_tmf_work(struct work_struct *work) | |||
1461 | get_itt(tmf_hdr->rtt), get_itt(ctask->itt), cmd->task_id, | 1461 | get_itt(tmf_hdr->rtt), get_itt(ctask->itt), cmd->task_id, |
1462 | qedi_conn->iscsi_conn_id); | 1462 | qedi_conn->iscsi_conn_id); |
1463 | 1463 | ||
1464 | if (do_not_recover) { | 1464 | if (qedi_do_not_recover) { |
1465 | QEDI_ERR(&qedi->dbg_ctx, "DONT SEND CLEANUP/ABORT %d\n", | 1465 | QEDI_ERR(&qedi->dbg_ctx, "DONT SEND CLEANUP/ABORT %d\n", |
1466 | do_not_recover); | 1466 | qedi_do_not_recover); |
1467 | goto abort_ret; | 1467 | goto abort_ret; |
1468 | } | 1468 | } |
1469 | 1469 | ||
diff --git a/drivers/scsi/qedi/qedi_gbl.h b/drivers/scsi/qedi/qedi_gbl.h index 8e488de88ece..63d793f46064 100644 --- a/drivers/scsi/qedi/qedi_gbl.h +++ b/drivers/scsi/qedi/qedi_gbl.h | |||
@@ -12,8 +12,14 @@ | |||
12 | 12 | ||
13 | #include "qedi_iscsi.h" | 13 | #include "qedi_iscsi.h" |
14 | 14 | ||
15 | #ifdef CONFIG_DEBUG_FS | ||
16 | extern int qedi_do_not_recover; | ||
17 | #else | ||
18 | #define qedi_do_not_recover (0) | ||
19 | #endif | ||
20 | |||
15 | extern uint qedi_io_tracing; | 21 | extern uint qedi_io_tracing; |
16 | extern int do_not_recover; | 22 | |
17 | extern struct scsi_host_template qedi_host_template; | 23 | extern struct scsi_host_template qedi_host_template; |
18 | extern struct iscsi_transport qedi_iscsi_transport; | 24 | extern struct iscsi_transport qedi_iscsi_transport; |
19 | extern const struct qed_iscsi_ops *qedi_ops; | 25 | extern const struct qed_iscsi_ops *qedi_ops; |
diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c index b9f79d36142d..4cc474364c50 100644 --- a/drivers/scsi/qedi/qedi_iscsi.c +++ b/drivers/scsi/qedi/qedi_iscsi.c | |||
@@ -833,7 +833,7 @@ qedi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, | |||
833 | return ERR_PTR(ret); | 833 | return ERR_PTR(ret); |
834 | } | 834 | } |
835 | 835 | ||
836 | if (do_not_recover) { | 836 | if (qedi_do_not_recover) { |
837 | ret = -ENOMEM; | 837 | ret = -ENOMEM; |
838 | return ERR_PTR(ret); | 838 | return ERR_PTR(ret); |
839 | } | 839 | } |
@@ -957,7 +957,7 @@ static int qedi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) | |||
957 | struct qedi_endpoint *qedi_ep; | 957 | struct qedi_endpoint *qedi_ep; |
958 | int ret = 0; | 958 | int ret = 0; |
959 | 959 | ||
960 | if (do_not_recover) | 960 | if (qedi_do_not_recover) |
961 | return 1; | 961 | return 1; |
962 | 962 | ||
963 | qedi_ep = ep->dd_data; | 963 | qedi_ep = ep->dd_data; |
@@ -1025,7 +1025,7 @@ static void qedi_ep_disconnect(struct iscsi_endpoint *ep) | |||
1025 | } | 1025 | } |
1026 | 1026 | ||
1027 | if (test_bit(QEDI_IN_RECOVERY, &qedi->flags)) { | 1027 | if (test_bit(QEDI_IN_RECOVERY, &qedi->flags)) { |
1028 | if (do_not_recover) { | 1028 | if (qedi_do_not_recover) { |
1029 | QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO, | 1029 | QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO, |
1030 | "Do not recover cid=0x%x\n", | 1030 | "Do not recover cid=0x%x\n", |
1031 | qedi_ep->iscsi_cid); | 1031 | qedi_ep->iscsi_cid); |
@@ -1039,7 +1039,7 @@ static void qedi_ep_disconnect(struct iscsi_endpoint *ep) | |||
1039 | } | 1039 | } |
1040 | } | 1040 | } |
1041 | 1041 | ||
1042 | if (do_not_recover) | 1042 | if (qedi_do_not_recover) |
1043 | goto ep_exit_recover; | 1043 | goto ep_exit_recover; |
1044 | 1044 | ||
1045 | switch (qedi_ep->state) { | 1045 | switch (qedi_ep->state) { |
diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c index 5eda21d903e9..8e3d92807cb8 100644 --- a/drivers/scsi/qedi/qedi_main.c +++ b/drivers/scsi/qedi/qedi_main.c | |||
@@ -1805,7 +1805,7 @@ static int __qedi_probe(struct pci_dev *pdev, int mode) | |||
1805 | */ | 1805 | */ |
1806 | qedi_ops->common->update_pf_params(qedi->cdev, &qedi->pf_params); | 1806 | qedi_ops->common->update_pf_params(qedi->cdev, &qedi->pf_params); |
1807 | 1807 | ||
1808 | qedi_setup_int(qedi); | 1808 | rc = qedi_setup_int(qedi); |
1809 | if (rc) | 1809 | if (rc) |
1810 | goto stop_iscsi_func; | 1810 | goto stop_iscsi_func; |
1811 | 1811 | ||
diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig index 67c0d5aa3212..de952935b5d2 100644 --- a/drivers/scsi/qla2xxx/Kconfig +++ b/drivers/scsi/qla2xxx/Kconfig | |||
@@ -3,6 +3,7 @@ config SCSI_QLA_FC | |||
3 | depends on PCI && SCSI | 3 | depends on PCI && SCSI |
4 | depends on SCSI_FC_ATTRS | 4 | depends on SCSI_FC_ATTRS |
5 | select FW_LOADER | 5 | select FW_LOADER |
6 | select BTREE | ||
6 | ---help--- | 7 | ---help--- |
7 | This qla2xxx driver supports all QLogic Fibre Channel | 8 | This qla2xxx driver supports all QLogic Fibre Channel |
8 | PCI and PCIe host adapters. | 9 | PCI and PCIe host adapters. |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index f610103994af..435ff7fd6384 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -2154,8 +2154,6 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) | |||
2154 | "Timer for the VP[%d] has stopped\n", vha->vp_idx); | 2154 | "Timer for the VP[%d] has stopped\n", vha->vp_idx); |
2155 | } | 2155 | } |
2156 | 2156 | ||
2157 | BUG_ON(atomic_read(&vha->vref_count)); | ||
2158 | |||
2159 | qla2x00_free_fcports(vha); | 2157 | qla2x00_free_fcports(vha); |
2160 | 2158 | ||
2161 | mutex_lock(&ha->vport_lock); | 2159 | mutex_lock(&ha->vport_lock); |
@@ -2166,7 +2164,7 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) | |||
2166 | dma_free_coherent(&ha->pdev->dev, vha->gnl.size, vha->gnl.l, | 2164 | dma_free_coherent(&ha->pdev->dev, vha->gnl.size, vha->gnl.l, |
2167 | vha->gnl.ldma); | 2165 | vha->gnl.ldma); |
2168 | 2166 | ||
2169 | if (vha->qpair->vp_idx == vha->vp_idx) { | 2167 | if (vha->qpair && vha->qpair->vp_idx == vha->vp_idx) { |
2170 | if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS) | 2168 | if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS) |
2171 | ql_log(ql_log_warn, vha, 0x7087, | 2169 | ql_log(ql_log_warn, vha, 0x7087, |
2172 | "Queue Pair delete failed.\n"); | 2170 | "Queue Pair delete failed.\n"); |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 21d9fb7fc887..51b4179469d1 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -2707,13 +2707,9 @@ ql_dump_buffer(uint32_t level, scsi_qla_host_t *vha, int32_t id, | |||
2707 | "%-+5d 0 1 2 3 4 5 6 7 8 9 A B C D E F\n", size); | 2707 | "%-+5d 0 1 2 3 4 5 6 7 8 9 A B C D E F\n", size); |
2708 | ql_dbg(level, vha, id, | 2708 | ql_dbg(level, vha, id, |
2709 | "----- -----------------------------------------------\n"); | 2709 | "----- -----------------------------------------------\n"); |
2710 | for (cnt = 0; cnt < size; cnt++, buf++) { | 2710 | for (cnt = 0; cnt < size; cnt += 16) { |
2711 | if (cnt % 16 == 0) | 2711 | ql_dbg(level, vha, id, "%04x: ", cnt); |
2712 | ql_dbg(level, vha, id, "%04x:", cnt & ~0xFU); | 2712 | print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, |
2713 | printk(" %02x", *buf); | 2713 | buf + cnt, min(16U, size - cnt), false); |
2714 | if (cnt % 16 == 15) | ||
2715 | printk("\n"); | ||
2716 | } | 2714 | } |
2717 | if (cnt % 16 != 0) | ||
2718 | printk("\n"); | ||
2719 | } | 2715 | } |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index e1fc4e66966a..c6bffe929fe7 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -348,6 +348,7 @@ ql_log_pci(uint32_t, struct pci_dev *pdev, int32_t, const char *fmt, ...); | |||
348 | #define ql_dbg_tgt 0x00004000 /* Target mode */ | 348 | #define ql_dbg_tgt 0x00004000 /* Target mode */ |
349 | #define ql_dbg_tgt_mgt 0x00002000 /* Target mode management */ | 349 | #define ql_dbg_tgt_mgt 0x00002000 /* Target mode management */ |
350 | #define ql_dbg_tgt_tmr 0x00001000 /* Target mode task management */ | 350 | #define ql_dbg_tgt_tmr 0x00001000 /* Target mode task management */ |
351 | #define ql_dbg_tgt_dif 0x00000800 /* Target mode dif */ | ||
351 | 352 | ||
352 | extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *, | 353 | extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *, |
353 | uint32_t, void **); | 354 | uint32_t, void **); |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 625d438e3cce..ae119018dfaa 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/firmware.h> | 25 | #include <linux/firmware.h> |
26 | #include <linux/aer.h> | 26 | #include <linux/aer.h> |
27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/btree.h> | ||
28 | 29 | ||
29 | #include <scsi/scsi.h> | 30 | #include <scsi/scsi.h> |
30 | #include <scsi/scsi_host.h> | 31 | #include <scsi/scsi_host.h> |
@@ -395,11 +396,15 @@ struct srb_iocb { | |||
395 | struct completion comp; | 396 | struct completion comp; |
396 | } abt; | 397 | } abt; |
397 | struct ct_arg ctarg; | 398 | struct ct_arg ctarg; |
399 | #define MAX_IOCB_MB_REG 28 | ||
400 | #define SIZEOF_IOCB_MB_REG (MAX_IOCB_MB_REG * sizeof(uint16_t)) | ||
398 | struct { | 401 | struct { |
399 | __le16 in_mb[28]; /* fr fw */ | 402 | __le16 in_mb[MAX_IOCB_MB_REG]; /* from FW */ |
400 | __le16 out_mb[28]; /* to fw */ | 403 | __le16 out_mb[MAX_IOCB_MB_REG]; /* to FW */ |
401 | void *out, *in; | 404 | void *out, *in; |
402 | dma_addr_t out_dma, in_dma; | 405 | dma_addr_t out_dma, in_dma; |
406 | struct completion comp; | ||
407 | int rc; | ||
403 | } mbx; | 408 | } mbx; |
404 | struct { | 409 | struct { |
405 | struct imm_ntfy_from_isp *ntfy; | 410 | struct imm_ntfy_from_isp *ntfy; |
@@ -437,7 +442,7 @@ typedef struct srb { | |||
437 | uint32_t handle; | 442 | uint32_t handle; |
438 | uint16_t flags; | 443 | uint16_t flags; |
439 | uint16_t type; | 444 | uint16_t type; |
440 | char *name; | 445 | const char *name; |
441 | int iocbs; | 446 | int iocbs; |
442 | struct qla_qpair *qpair; | 447 | struct qla_qpair *qpair; |
443 | u32 gen1; /* scratch */ | 448 | u32 gen1; /* scratch */ |
@@ -2300,6 +2305,8 @@ typedef struct fc_port { | |||
2300 | struct ct_sns_desc ct_desc; | 2305 | struct ct_sns_desc ct_desc; |
2301 | enum discovery_state disc_state; | 2306 | enum discovery_state disc_state; |
2302 | enum login_state fw_login_state; | 2307 | enum login_state fw_login_state; |
2308 | unsigned long plogi_nack_done_deadline; | ||
2309 | |||
2303 | u32 login_gen, last_login_gen; | 2310 | u32 login_gen, last_login_gen; |
2304 | u32 rscn_gen, last_rscn_gen; | 2311 | u32 rscn_gen, last_rscn_gen; |
2305 | u32 chip_reset; | 2312 | u32 chip_reset; |
@@ -3106,6 +3113,16 @@ struct qla_chip_state_84xx { | |||
3106 | uint32_t gold_fw_version; | 3113 | uint32_t gold_fw_version; |
3107 | }; | 3114 | }; |
3108 | 3115 | ||
3116 | struct qla_dif_statistics { | ||
3117 | uint64_t dif_input_bytes; | ||
3118 | uint64_t dif_output_bytes; | ||
3119 | uint64_t dif_input_requests; | ||
3120 | uint64_t dif_output_requests; | ||
3121 | uint32_t dif_guard_err; | ||
3122 | uint32_t dif_ref_tag_err; | ||
3123 | uint32_t dif_app_tag_err; | ||
3124 | }; | ||
3125 | |||
3109 | struct qla_statistics { | 3126 | struct qla_statistics { |
3110 | uint32_t total_isp_aborts; | 3127 | uint32_t total_isp_aborts; |
3111 | uint64_t input_bytes; | 3128 | uint64_t input_bytes; |
@@ -3118,6 +3135,8 @@ struct qla_statistics { | |||
3118 | uint32_t stat_max_pend_cmds; | 3135 | uint32_t stat_max_pend_cmds; |
3119 | uint32_t stat_max_qfull_cmds_alloc; | 3136 | uint32_t stat_max_qfull_cmds_alloc; |
3120 | uint32_t stat_max_qfull_cmds_dropped; | 3137 | uint32_t stat_max_qfull_cmds_dropped; |
3138 | |||
3139 | struct qla_dif_statistics qla_dif_stats; | ||
3121 | }; | 3140 | }; |
3122 | 3141 | ||
3123 | struct bidi_statistics { | 3142 | struct bidi_statistics { |
@@ -3125,6 +3144,16 @@ struct bidi_statistics { | |||
3125 | unsigned long long transfer_bytes; | 3144 | unsigned long long transfer_bytes; |
3126 | }; | 3145 | }; |
3127 | 3146 | ||
3147 | struct qla_tc_param { | ||
3148 | struct scsi_qla_host *vha; | ||
3149 | uint32_t blk_sz; | ||
3150 | uint32_t bufflen; | ||
3151 | struct scatterlist *sg; | ||
3152 | struct scatterlist *prot_sg; | ||
3153 | struct crc_context *ctx; | ||
3154 | uint8_t *ctx_dsd_alloced; | ||
3155 | }; | ||
3156 | |||
3128 | /* Multi queue support */ | 3157 | /* Multi queue support */ |
3129 | #define MBC_INITIALIZE_MULTIQ 0x1f | 3158 | #define MBC_INITIALIZE_MULTIQ 0x1f |
3130 | #define QLA_QUE_PAGE 0X1000 | 3159 | #define QLA_QUE_PAGE 0X1000 |
@@ -3272,6 +3301,8 @@ struct qlt_hw_data { | |||
3272 | uint8_t tgt_node_name[WWN_SIZE]; | 3301 | uint8_t tgt_node_name[WWN_SIZE]; |
3273 | 3302 | ||
3274 | struct dentry *dfs_tgt_sess; | 3303 | struct dentry *dfs_tgt_sess; |
3304 | struct dentry *dfs_tgt_port_database; | ||
3305 | |||
3275 | struct list_head q_full_list; | 3306 | struct list_head q_full_list; |
3276 | uint32_t num_pend_cmds; | 3307 | uint32_t num_pend_cmds; |
3277 | uint32_t num_qfull_cmds_alloc; | 3308 | uint32_t num_qfull_cmds_alloc; |
@@ -3281,6 +3312,7 @@ struct qlt_hw_data { | |||
3281 | spinlock_t sess_lock; | 3312 | spinlock_t sess_lock; |
3282 | int rspq_vector_cpuid; | 3313 | int rspq_vector_cpuid; |
3283 | spinlock_t atio_lock ____cacheline_aligned; | 3314 | spinlock_t atio_lock ____cacheline_aligned; |
3315 | struct btree_head32 host_map; | ||
3284 | }; | 3316 | }; |
3285 | 3317 | ||
3286 | #define MAX_QFULL_CMDS_ALLOC 8192 | 3318 | #define MAX_QFULL_CMDS_ALLOC 8192 |
@@ -3290,6 +3322,10 @@ struct qlt_hw_data { | |||
3290 | 3322 | ||
3291 | #define LEAK_EXCHG_THRESH_HOLD_PERCENT 75 /* 75 percent */ | 3323 | #define LEAK_EXCHG_THRESH_HOLD_PERCENT 75 /* 75 percent */ |
3292 | 3324 | ||
3325 | #define QLA_EARLY_LINKUP(_ha) \ | ||
3326 | ((_ha->flags.n2n_ae || _ha->flags.lip_ae) && \ | ||
3327 | _ha->flags.fw_started && !_ha->flags.fw_init_done) | ||
3328 | |||
3293 | /* | 3329 | /* |
3294 | * Qlogic host adapter specific data structure. | 3330 | * Qlogic host adapter specific data structure. |
3295 | */ | 3331 | */ |
@@ -3339,7 +3375,11 @@ struct qla_hw_data { | |||
3339 | uint32_t fawwpn_enabled:1; | 3375 | uint32_t fawwpn_enabled:1; |
3340 | uint32_t exlogins_enabled:1; | 3376 | uint32_t exlogins_enabled:1; |
3341 | uint32_t exchoffld_enabled:1; | 3377 | uint32_t exchoffld_enabled:1; |
3342 | /* 35 bits */ | 3378 | |
3379 | uint32_t lip_ae:1; | ||
3380 | uint32_t n2n_ae:1; | ||
3381 | uint32_t fw_started:1; | ||
3382 | uint32_t fw_init_done:1; | ||
3343 | } flags; | 3383 | } flags; |
3344 | 3384 | ||
3345 | /* This spinlock is used to protect "io transactions", you must | 3385 | /* This spinlock is used to protect "io transactions", you must |
@@ -3432,7 +3472,6 @@ struct qla_hw_data { | |||
3432 | #define P2P_LOOP 3 | 3472 | #define P2P_LOOP 3 |
3433 | uint8_t interrupts_on; | 3473 | uint8_t interrupts_on; |
3434 | uint32_t isp_abort_cnt; | 3474 | uint32_t isp_abort_cnt; |
3435 | |||
3436 | #define PCI_DEVICE_ID_QLOGIC_ISP2532 0x2532 | 3475 | #define PCI_DEVICE_ID_QLOGIC_ISP2532 0x2532 |
3437 | #define PCI_DEVICE_ID_QLOGIC_ISP8432 0x8432 | 3476 | #define PCI_DEVICE_ID_QLOGIC_ISP8432 0x8432 |
3438 | #define PCI_DEVICE_ID_QLOGIC_ISP8001 0x8001 | 3477 | #define PCI_DEVICE_ID_QLOGIC_ISP8001 0x8001 |
@@ -3913,6 +3952,7 @@ typedef struct scsi_qla_host { | |||
3913 | struct list_head vp_fcports; /* list of fcports */ | 3952 | struct list_head vp_fcports; /* list of fcports */ |
3914 | struct list_head work_list; | 3953 | struct list_head work_list; |
3915 | spinlock_t work_lock; | 3954 | spinlock_t work_lock; |
3955 | struct work_struct iocb_work; | ||
3916 | 3956 | ||
3917 | /* Commonly used flags and state information. */ | 3957 | /* Commonly used flags and state information. */ |
3918 | struct Scsi_Host *host; | 3958 | struct Scsi_Host *host; |
@@ -4076,6 +4116,7 @@ typedef struct scsi_qla_host { | |||
4076 | /* Count of active session/fcport */ | 4116 | /* Count of active session/fcport */ |
4077 | int fcport_count; | 4117 | int fcport_count; |
4078 | wait_queue_head_t fcport_waitQ; | 4118 | wait_queue_head_t fcport_waitQ; |
4119 | wait_queue_head_t vref_waitq; | ||
4079 | } scsi_qla_host_t; | 4120 | } scsi_qla_host_t; |
4080 | 4121 | ||
4081 | struct qla27xx_image_status { | 4122 | struct qla27xx_image_status { |
@@ -4131,14 +4172,17 @@ struct qla2_sgx { | |||
4131 | mb(); \ | 4172 | mb(); \ |
4132 | if (__vha->flags.delete_progress) { \ | 4173 | if (__vha->flags.delete_progress) { \ |
4133 | atomic_dec(&__vha->vref_count); \ | 4174 | atomic_dec(&__vha->vref_count); \ |
4175 | wake_up(&__vha->vref_waitq); \ | ||
4134 | __bail = 1; \ | 4176 | __bail = 1; \ |
4135 | } else { \ | 4177 | } else { \ |
4136 | __bail = 0; \ | 4178 | __bail = 0; \ |
4137 | } \ | 4179 | } \ |
4138 | } while (0) | 4180 | } while (0) |
4139 | 4181 | ||
4140 | #define QLA_VHA_MARK_NOT_BUSY(__vha) \ | 4182 | #define QLA_VHA_MARK_NOT_BUSY(__vha) do { \ |
4141 | atomic_dec(&__vha->vref_count); \ | 4183 | atomic_dec(&__vha->vref_count); \ |
4184 | wake_up(&__vha->vref_waitq); \ | ||
4185 | } while (0) \ | ||
4142 | 4186 | ||
4143 | #define QLA_QPAIR_MARK_BUSY(__qpair, __bail) do { \ | 4187 | #define QLA_QPAIR_MARK_BUSY(__qpair, __bail) do { \ |
4144 | atomic_inc(&__qpair->ref_count); \ | 4188 | atomic_inc(&__qpair->ref_count); \ |
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index b48cce696bac..989e17b0758c 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c | |||
@@ -19,11 +19,11 @@ qla2x00_dfs_tgt_sess_show(struct seq_file *s, void *unused) | |||
19 | struct qla_hw_data *ha = vha->hw; | 19 | struct qla_hw_data *ha = vha->hw; |
20 | unsigned long flags; | 20 | unsigned long flags; |
21 | struct fc_port *sess = NULL; | 21 | struct fc_port *sess = NULL; |
22 | struct qla_tgt *tgt= vha->vha_tgt.qla_tgt; | 22 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
23 | 23 | ||
24 | seq_printf(s, "%s\n",vha->host_str); | 24 | seq_printf(s, "%s\n", vha->host_str); |
25 | if (tgt) { | 25 | if (tgt) { |
26 | seq_printf(s, "Port ID Port Name Handle\n"); | 26 | seq_puts(s, "Port ID Port Name Handle\n"); |
27 | 27 | ||
28 | spin_lock_irqsave(&ha->tgt.sess_lock, flags); | 28 | spin_lock_irqsave(&ha->tgt.sess_lock, flags); |
29 | list_for_each_entry(sess, &vha->vp_fcports, list) | 29 | list_for_each_entry(sess, &vha->vp_fcports, list) |
@@ -44,7 +44,6 @@ qla2x00_dfs_tgt_sess_open(struct inode *inode, struct file *file) | |||
44 | return single_open(file, qla2x00_dfs_tgt_sess_show, vha); | 44 | return single_open(file, qla2x00_dfs_tgt_sess_show, vha); |
45 | } | 45 | } |
46 | 46 | ||
47 | |||
48 | static const struct file_operations dfs_tgt_sess_ops = { | 47 | static const struct file_operations dfs_tgt_sess_ops = { |
49 | .open = qla2x00_dfs_tgt_sess_open, | 48 | .open = qla2x00_dfs_tgt_sess_open, |
50 | .read = seq_read, | 49 | .read = seq_read, |
@@ -53,6 +52,78 @@ static const struct file_operations dfs_tgt_sess_ops = { | |||
53 | }; | 52 | }; |
54 | 53 | ||
55 | static int | 54 | static int |
55 | qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused) | ||
56 | { | ||
57 | scsi_qla_host_t *vha = s->private; | ||
58 | struct qla_hw_data *ha = vha->hw; | ||
59 | struct gid_list_info *gid_list; | ||
60 | dma_addr_t gid_list_dma; | ||
61 | fc_port_t fc_port; | ||
62 | char *id_iter; | ||
63 | int rc, i; | ||
64 | uint16_t entries, loop_id; | ||
65 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; | ||
66 | |||
67 | seq_printf(s, "%s\n", vha->host_str); | ||
68 | if (tgt) { | ||
69 | gid_list = dma_alloc_coherent(&ha->pdev->dev, | ||
70 | qla2x00_gid_list_size(ha), | ||
71 | &gid_list_dma, GFP_KERNEL); | ||
72 | if (!gid_list) { | ||
73 | ql_dbg(ql_dbg_user, vha, 0x705c, | ||
74 | "DMA allocation failed for %u\n", | ||
75 | qla2x00_gid_list_size(ha)); | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | rc = qla24xx_gidlist_wait(vha, gid_list, gid_list_dma, | ||
80 | &entries); | ||
81 | if (rc != QLA_SUCCESS) | ||
82 | goto out_free_id_list; | ||
83 | |||
84 | id_iter = (char *)gid_list; | ||
85 | |||
86 | seq_puts(s, "Port Name Port ID Loop ID\n"); | ||
87 | |||
88 | for (i = 0; i < entries; i++) { | ||
89 | struct gid_list_info *gid = | ||
90 | (struct gid_list_info *)id_iter; | ||
91 | loop_id = le16_to_cpu(gid->loop_id); | ||
92 | memset(&fc_port, 0, sizeof(fc_port_t)); | ||
93 | |||
94 | fc_port.loop_id = loop_id; | ||
95 | |||
96 | rc = qla24xx_gpdb_wait(vha, &fc_port, 0); | ||
97 | seq_printf(s, "%8phC %02x%02x%02x %d\n", | ||
98 | fc_port.port_name, fc_port.d_id.b.domain, | ||
99 | fc_port.d_id.b.area, fc_port.d_id.b.al_pa, | ||
100 | fc_port.loop_id); | ||
101 | id_iter += ha->gid_list_info_size; | ||
102 | } | ||
103 | out_free_id_list: | ||
104 | dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), | ||
105 | gid_list, gid_list_dma); | ||
106 | } | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static int | ||
112 | qla2x00_dfs_tgt_port_database_open(struct inode *inode, struct file *file) | ||
113 | { | ||
114 | scsi_qla_host_t *vha = inode->i_private; | ||
115 | |||
116 | return single_open(file, qla2x00_dfs_tgt_port_database_show, vha); | ||
117 | } | ||
118 | |||
119 | static const struct file_operations dfs_tgt_port_database_ops = { | ||
120 | .open = qla2x00_dfs_tgt_port_database_open, | ||
121 | .read = seq_read, | ||
122 | .llseek = seq_lseek, | ||
123 | .release = single_release, | ||
124 | }; | ||
125 | |||
126 | static int | ||
56 | qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused) | 127 | qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused) |
57 | { | 128 | { |
58 | struct scsi_qla_host *vha = s->private; | 129 | struct scsi_qla_host *vha = s->private; |
@@ -114,6 +185,21 @@ qla_dfs_tgt_counters_show(struct seq_file *s, void *unused) | |||
114 | seq_printf(s, "num Q full sent = %lld\n", | 185 | seq_printf(s, "num Q full sent = %lld\n", |
115 | vha->tgt_counters.num_q_full_sent); | 186 | vha->tgt_counters.num_q_full_sent); |
116 | 187 | ||
188 | /* DIF stats */ | ||
189 | seq_printf(s, "DIF Inp Bytes = %lld\n", | ||
190 | vha->qla_stats.qla_dif_stats.dif_input_bytes); | ||
191 | seq_printf(s, "DIF Outp Bytes = %lld\n", | ||
192 | vha->qla_stats.qla_dif_stats.dif_output_bytes); | ||
193 | seq_printf(s, "DIF Inp Req = %lld\n", | ||
194 | vha->qla_stats.qla_dif_stats.dif_input_requests); | ||
195 | seq_printf(s, "DIF Outp Req = %lld\n", | ||
196 | vha->qla_stats.qla_dif_stats.dif_output_requests); | ||
197 | seq_printf(s, "DIF Guard err = %d\n", | ||
198 | vha->qla_stats.qla_dif_stats.dif_guard_err); | ||
199 | seq_printf(s, "DIF Ref tag err = %d\n", | ||
200 | vha->qla_stats.qla_dif_stats.dif_ref_tag_err); | ||
201 | seq_printf(s, "DIF App tag err = %d\n", | ||
202 | vha->qla_stats.qla_dif_stats.dif_app_tag_err); | ||
117 | return 0; | 203 | return 0; |
118 | } | 204 | } |
119 | 205 | ||
@@ -281,6 +367,14 @@ create_nodes: | |||
281 | goto out; | 367 | goto out; |
282 | } | 368 | } |
283 | 369 | ||
370 | ha->tgt.dfs_tgt_port_database = debugfs_create_file("tgt_port_database", | ||
371 | S_IRUSR, ha->dfs_dir, vha, &dfs_tgt_port_database_ops); | ||
372 | if (!ha->tgt.dfs_tgt_port_database) { | ||
373 | ql_log(ql_log_warn, vha, 0xffff, | ||
374 | "Unable to create debugFS tgt_port_database node.\n"); | ||
375 | goto out; | ||
376 | } | ||
377 | |||
284 | ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha, | 378 | ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha, |
285 | &dfs_fce_ops); | 379 | &dfs_fce_ops); |
286 | if (!ha->dfs_fce) { | 380 | if (!ha->dfs_fce) { |
@@ -311,6 +405,11 @@ qla2x00_dfs_remove(scsi_qla_host_t *vha) | |||
311 | ha->tgt.dfs_tgt_sess = NULL; | 405 | ha->tgt.dfs_tgt_sess = NULL; |
312 | } | 406 | } |
313 | 407 | ||
408 | if (ha->tgt.dfs_tgt_port_database) { | ||
409 | debugfs_remove(ha->tgt.dfs_tgt_port_database); | ||
410 | ha->tgt.dfs_tgt_port_database = NULL; | ||
411 | } | ||
412 | |||
314 | if (ha->dfs_fw_resource_cnt) { | 413 | if (ha->dfs_fw_resource_cnt) { |
315 | debugfs_remove(ha->dfs_fw_resource_cnt); | 414 | debugfs_remove(ha->dfs_fw_resource_cnt); |
316 | ha->dfs_fw_resource_cnt = NULL; | 415 | ha->dfs_fw_resource_cnt = NULL; |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index b3d6441d1d90..5b2451745e9f 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -193,6 +193,7 @@ extern int qla24xx_post_upd_fcport_work(struct scsi_qla_host *, fc_port_t *); | |||
193 | void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *, | 193 | void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *, |
194 | uint16_t *); | 194 | uint16_t *); |
195 | int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *); | 195 | int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *); |
196 | int qla24xx_async_abort_cmd(srb_t *); | ||
196 | 197 | ||
197 | /* | 198 | /* |
198 | * Global Functions in qla_mid.c source file. | 199 | * Global Functions in qla_mid.c source file. |
@@ -256,11 +257,11 @@ extern unsigned long qla2x00_get_async_timeout(struct scsi_qla_host *); | |||
256 | extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *); | 257 | extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *); |
257 | extern int qla2x00_issue_marker(scsi_qla_host_t *, int); | 258 | extern int qla2x00_issue_marker(scsi_qla_host_t *, int); |
258 | extern int qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *, srb_t *, | 259 | extern int qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *, srb_t *, |
259 | uint32_t *, uint16_t, struct qla_tgt_cmd *); | 260 | uint32_t *, uint16_t, struct qla_tc_param *); |
260 | extern int qla24xx_walk_and_build_sglist(struct qla_hw_data *, srb_t *, | 261 | extern int qla24xx_walk_and_build_sglist(struct qla_hw_data *, srb_t *, |
261 | uint32_t *, uint16_t, struct qla_tgt_cmd *); | 262 | uint32_t *, uint16_t, struct qla_tc_param *); |
262 | extern int qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *, srb_t *, | 263 | extern int qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *, srb_t *, |
263 | uint32_t *, uint16_t, struct qla_tgt_cmd *); | 264 | uint32_t *, uint16_t, struct qla_tc_param *); |
264 | extern int qla24xx_get_one_block_sg(uint32_t, struct qla2_sgx *, uint32_t *); | 265 | extern int qla24xx_get_one_block_sg(uint32_t, struct qla2_sgx *, uint32_t *); |
265 | extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *); | 266 | extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *); |
266 | extern int qla24xx_build_scsi_crc_2_iocbs(srb_t *, | 267 | extern int qla24xx_build_scsi_crc_2_iocbs(srb_t *, |
@@ -368,7 +369,7 @@ qla2x00_get_link_status(scsi_qla_host_t *, uint16_t, struct link_statistics *, | |||
368 | 369 | ||
369 | extern int | 370 | extern int |
370 | qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *, | 371 | qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *, |
371 | dma_addr_t, uint); | 372 | dma_addr_t, uint16_t); |
372 | 373 | ||
373 | extern int qla24xx_abort_command(srb_t *); | 374 | extern int qla24xx_abort_command(srb_t *); |
374 | extern int qla24xx_async_abort_command(srb_t *); | 375 | extern int qla24xx_async_abort_command(srb_t *); |
@@ -472,6 +473,13 @@ qla2x00_dump_mctp_data(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t); | |||
472 | extern int | 473 | extern int |
473 | qla26xx_dport_diagnostics(scsi_qla_host_t *, void *, uint, uint); | 474 | qla26xx_dport_diagnostics(scsi_qla_host_t *, void *, uint, uint); |
474 | 475 | ||
476 | int qla24xx_send_mb_cmd(struct scsi_qla_host *, mbx_cmd_t *); | ||
477 | int qla24xx_gpdb_wait(struct scsi_qla_host *, fc_port_t *, u8); | ||
478 | int qla24xx_gidlist_wait(struct scsi_qla_host *, void *, dma_addr_t, | ||
479 | uint16_t *); | ||
480 | int __qla24xx_parse_gpdb(struct scsi_qla_host *, fc_port_t *, | ||
481 | struct port_database_24xx *); | ||
482 | |||
475 | /* | 483 | /* |
476 | * Global Function Prototypes in qla_isr.c source file. | 484 | * Global Function Prototypes in qla_isr.c source file. |
477 | */ | 485 | */ |
@@ -846,5 +854,7 @@ extern struct fc_port *qlt_find_sess_invalidate_other(scsi_qla_host_t *, | |||
846 | uint64_t wwn, port_id_t port_id, uint16_t loop_id, struct fc_port **); | 854 | uint64_t wwn, port_id_t port_id, uint16_t loop_id, struct fc_port **); |
847 | void qla24xx_delete_sess_fn(struct work_struct *); | 855 | void qla24xx_delete_sess_fn(struct work_struct *); |
848 | void qlt_unknown_atio_work_fn(struct work_struct *); | 856 | void qlt_unknown_atio_work_fn(struct work_struct *); |
857 | void qlt_update_host_map(struct scsi_qla_host *, port_id_t); | ||
858 | void qlt_remove_target_resources(struct qla_hw_data *); | ||
849 | 859 | ||
850 | #endif /* _QLA_GBL_H */ | 860 | #endif /* _QLA_GBL_H */ |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 32fb9007f137..f9d2fe7b1ade 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -629,7 +629,6 @@ void qla24xx_async_gpdb_sp_done(void *s, int res) | |||
629 | struct srb *sp = s; | 629 | struct srb *sp = s; |
630 | struct scsi_qla_host *vha = sp->vha; | 630 | struct scsi_qla_host *vha = sp->vha; |
631 | struct qla_hw_data *ha = vha->hw; | 631 | struct qla_hw_data *ha = vha->hw; |
632 | uint64_t zero = 0; | ||
633 | struct port_database_24xx *pd; | 632 | struct port_database_24xx *pd; |
634 | fc_port_t *fcport = sp->fcport; | 633 | fc_port_t *fcport = sp->fcport; |
635 | u16 *mb = sp->u.iocb_cmd.u.mbx.in_mb; | 634 | u16 *mb = sp->u.iocb_cmd.u.mbx.in_mb; |
@@ -649,48 +648,7 @@ void qla24xx_async_gpdb_sp_done(void *s, int res) | |||
649 | 648 | ||
650 | pd = (struct port_database_24xx *)sp->u.iocb_cmd.u.mbx.in; | 649 | pd = (struct port_database_24xx *)sp->u.iocb_cmd.u.mbx.in; |
651 | 650 | ||
652 | /* Check for logged in state. */ | 651 | rval = __qla24xx_parse_gpdb(vha, fcport, pd); |
653 | if (pd->current_login_state != PDS_PRLI_COMPLETE && | ||
654 | pd->last_login_state != PDS_PRLI_COMPLETE) { | ||
655 | ql_dbg(ql_dbg_mbx, vha, 0xffff, | ||
656 | "Unable to verify login-state (%x/%x) for " | ||
657 | "loop_id %x.\n", pd->current_login_state, | ||
658 | pd->last_login_state, fcport->loop_id); | ||
659 | rval = QLA_FUNCTION_FAILED; | ||
660 | goto gpd_error_out; | ||
661 | } | ||
662 | |||
663 | if (fcport->loop_id == FC_NO_LOOP_ID || | ||
664 | (memcmp(fcport->port_name, (uint8_t *)&zero, 8) && | ||
665 | memcmp(fcport->port_name, pd->port_name, 8))) { | ||
666 | /* We lost the device mid way. */ | ||
667 | rval = QLA_NOT_LOGGED_IN; | ||
668 | goto gpd_error_out; | ||
669 | } | ||
670 | |||
671 | /* Names are little-endian. */ | ||
672 | memcpy(fcport->node_name, pd->node_name, WWN_SIZE); | ||
673 | |||
674 | /* Get port_id of device. */ | ||
675 | fcport->d_id.b.domain = pd->port_id[0]; | ||
676 | fcport->d_id.b.area = pd->port_id[1]; | ||
677 | fcport->d_id.b.al_pa = pd->port_id[2]; | ||
678 | fcport->d_id.b.rsvd_1 = 0; | ||
679 | |||
680 | /* If not target must be initiator or unknown type. */ | ||
681 | if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) | ||
682 | fcport->port_type = FCT_INITIATOR; | ||
683 | else | ||
684 | fcport->port_type = FCT_TARGET; | ||
685 | |||
686 | /* Passback COS information. */ | ||
687 | fcport->supported_classes = (pd->flags & PDF_CLASS_2) ? | ||
688 | FC_COS_CLASS2 : FC_COS_CLASS3; | ||
689 | |||
690 | if (pd->prli_svc_param_word_3[0] & BIT_7) { | ||
691 | fcport->flags |= FCF_CONF_COMP_SUPPORTED; | ||
692 | fcport->conf_compl_supported = 1; | ||
693 | } | ||
694 | 652 | ||
695 | gpd_error_out: | 653 | gpd_error_out: |
696 | memset(&ea, 0, sizeof(ea)); | 654 | memset(&ea, 0, sizeof(ea)); |
@@ -876,10 +834,14 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
876 | fcport->login_retry--; | 834 | fcport->login_retry--; |
877 | 835 | ||
878 | if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || | 836 | if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || |
879 | (fcport->fw_login_state == DSC_LS_PLOGI_COMP) || | ||
880 | (fcport->fw_login_state == DSC_LS_PRLI_PEND)) | 837 | (fcport->fw_login_state == DSC_LS_PRLI_PEND)) |
881 | return 0; | 838 | return 0; |
882 | 839 | ||
840 | if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) { | ||
841 | if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline)) | ||
842 | return 0; | ||
843 | } | ||
844 | |||
883 | /* for pure Target Mode. Login will not be initiated */ | 845 | /* for pure Target Mode. Login will not be initiated */ |
884 | if (vha->host->active_mode == MODE_TARGET) | 846 | if (vha->host->active_mode == MODE_TARGET) |
885 | return 0; | 847 | return 0; |
@@ -1041,10 +1003,14 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha, | |||
1041 | fcport->flags); | 1003 | fcport->flags); |
1042 | 1004 | ||
1043 | if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || | 1005 | if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || |
1044 | (fcport->fw_login_state == DSC_LS_PLOGI_COMP) || | ||
1045 | (fcport->fw_login_state == DSC_LS_PRLI_PEND)) | 1006 | (fcport->fw_login_state == DSC_LS_PRLI_PEND)) |
1046 | return; | 1007 | return; |
1047 | 1008 | ||
1009 | if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) { | ||
1010 | if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline)) | ||
1011 | return; | ||
1012 | } | ||
1013 | |||
1048 | if (fcport->flags & FCF_ASYNC_SENT) { | 1014 | if (fcport->flags & FCF_ASYNC_SENT) { |
1049 | fcport->login_retry++; | 1015 | fcport->login_retry++; |
1050 | set_bit(RELOGIN_NEEDED, &vha->dpc_flags); | 1016 | set_bit(RELOGIN_NEEDED, &vha->dpc_flags); |
@@ -1258,7 +1224,7 @@ qla24xx_abort_sp_done(void *ptr, int res) | |||
1258 | complete(&abt->u.abt.comp); | 1224 | complete(&abt->u.abt.comp); |
1259 | } | 1225 | } |
1260 | 1226 | ||
1261 | static int | 1227 | int |
1262 | qla24xx_async_abort_cmd(srb_t *cmd_sp) | 1228 | qla24xx_async_abort_cmd(srb_t *cmd_sp) |
1263 | { | 1229 | { |
1264 | scsi_qla_host_t *vha = cmd_sp->vha; | 1230 | scsi_qla_host_t *vha = cmd_sp->vha; |
@@ -3212,6 +3178,7 @@ next_check: | |||
3212 | } else { | 3178 | } else { |
3213 | ql_dbg(ql_dbg_init, vha, 0x00d3, | 3179 | ql_dbg(ql_dbg_init, vha, 0x00d3, |
3214 | "Init Firmware -- success.\n"); | 3180 | "Init Firmware -- success.\n"); |
3181 | ha->flags.fw_started = 1; | ||
3215 | } | 3182 | } |
3216 | 3183 | ||
3217 | return (rval); | 3184 | return (rval); |
@@ -3374,8 +3341,8 @@ qla2x00_configure_hba(scsi_qla_host_t *vha) | |||
3374 | uint8_t domain; | 3341 | uint8_t domain; |
3375 | char connect_type[22]; | 3342 | char connect_type[22]; |
3376 | struct qla_hw_data *ha = vha->hw; | 3343 | struct qla_hw_data *ha = vha->hw; |
3377 | unsigned long flags; | ||
3378 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); | 3344 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); |
3345 | port_id_t id; | ||
3379 | 3346 | ||
3380 | /* Get host addresses. */ | 3347 | /* Get host addresses. */ |
3381 | rval = qla2x00_get_adapter_id(vha, | 3348 | rval = qla2x00_get_adapter_id(vha, |
@@ -3453,13 +3420,11 @@ qla2x00_configure_hba(scsi_qla_host_t *vha) | |||
3453 | 3420 | ||
3454 | /* Save Host port and loop ID. */ | 3421 | /* Save Host port and loop ID. */ |
3455 | /* byte order - Big Endian */ | 3422 | /* byte order - Big Endian */ |
3456 | vha->d_id.b.domain = domain; | 3423 | id.b.domain = domain; |
3457 | vha->d_id.b.area = area; | 3424 | id.b.area = area; |
3458 | vha->d_id.b.al_pa = al_pa; | 3425 | id.b.al_pa = al_pa; |
3459 | 3426 | id.b.rsvd_1 = 0; | |
3460 | spin_lock_irqsave(&ha->vport_slock, flags); | 3427 | qlt_update_host_map(vha, id); |
3461 | qlt_update_vp_map(vha, SET_AL_PA); | ||
3462 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
3463 | 3428 | ||
3464 | if (!vha->flags.init_done) | 3429 | if (!vha->flags.init_done) |
3465 | ql_log(ql_log_info, vha, 0x2010, | 3430 | ql_log(ql_log_info, vha, 0x2010, |
@@ -4036,6 +4001,7 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) | |||
4036 | atomic_set(&vha->loop_state, LOOP_READY); | 4001 | atomic_set(&vha->loop_state, LOOP_READY); |
4037 | ql_dbg(ql_dbg_disc, vha, 0x2069, | 4002 | ql_dbg(ql_dbg_disc, vha, 0x2069, |
4038 | "LOOP READY.\n"); | 4003 | "LOOP READY.\n"); |
4004 | ha->flags.fw_init_done = 1; | ||
4039 | 4005 | ||
4040 | /* | 4006 | /* |
4041 | * Process any ATIO queue entries that came in | 4007 | * Process any ATIO queue entries that came in |
@@ -5148,6 +5114,7 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha) | |||
5148 | } | 5114 | } |
5149 | } | 5115 | } |
5150 | atomic_dec(&vha->vref_count); | 5116 | atomic_dec(&vha->vref_count); |
5117 | wake_up(&vha->vref_waitq); | ||
5151 | } | 5118 | } |
5152 | spin_unlock_irqrestore(&ha->vport_slock, flags); | 5119 | spin_unlock_irqrestore(&ha->vport_slock, flags); |
5153 | } | 5120 | } |
@@ -5526,6 +5493,11 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) | |||
5526 | if (!(IS_P3P_TYPE(ha))) | 5493 | if (!(IS_P3P_TYPE(ha))) |
5527 | ha->isp_ops->reset_chip(vha); | 5494 | ha->isp_ops->reset_chip(vha); |
5528 | 5495 | ||
5496 | ha->flags.n2n_ae = 0; | ||
5497 | ha->flags.lip_ae = 0; | ||
5498 | ha->current_topology = 0; | ||
5499 | ha->flags.fw_started = 0; | ||
5500 | ha->flags.fw_init_done = 0; | ||
5529 | ha->chip_reset++; | 5501 | ha->chip_reset++; |
5530 | 5502 | ||
5531 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); | 5503 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); |
@@ -6802,6 +6774,8 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha) | |||
6802 | return; | 6774 | return; |
6803 | if (!ha->fw_major_version) | 6775 | if (!ha->fw_major_version) |
6804 | return; | 6776 | return; |
6777 | if (!ha->flags.fw_started) | ||
6778 | return; | ||
6805 | 6779 | ||
6806 | ret = qla2x00_stop_firmware(vha); | 6780 | ret = qla2x00_stop_firmware(vha); |
6807 | for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT && | 6781 | for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT && |
@@ -6815,6 +6789,9 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha) | |||
6815 | "Attempting retry of stop-firmware command.\n"); | 6789 | "Attempting retry of stop-firmware command.\n"); |
6816 | ret = qla2x00_stop_firmware(vha); | 6790 | ret = qla2x00_stop_firmware(vha); |
6817 | } | 6791 | } |
6792 | |||
6793 | ha->flags.fw_started = 0; | ||
6794 | ha->flags.fw_init_done = 0; | ||
6818 | } | 6795 | } |
6819 | 6796 | ||
6820 | int | 6797 | int |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 535079280288..ea027f6a7fd4 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -889,7 +889,7 @@ qla24xx_get_one_block_sg(uint32_t blk_sz, struct qla2_sgx *sgx, | |||
889 | 889 | ||
890 | int | 890 | int |
891 | qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, | 891 | qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, |
892 | uint32_t *dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc) | 892 | uint32_t *dsd, uint16_t tot_dsds, struct qla_tc_param *tc) |
893 | { | 893 | { |
894 | void *next_dsd; | 894 | void *next_dsd; |
895 | uint8_t avail_dsds = 0; | 895 | uint8_t avail_dsds = 0; |
@@ -898,7 +898,6 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, | |||
898 | struct scatterlist *sg_prot; | 898 | struct scatterlist *sg_prot; |
899 | uint32_t *cur_dsd = dsd; | 899 | uint32_t *cur_dsd = dsd; |
900 | uint16_t used_dsds = tot_dsds; | 900 | uint16_t used_dsds = tot_dsds; |
901 | |||
902 | uint32_t prot_int; /* protection interval */ | 901 | uint32_t prot_int; /* protection interval */ |
903 | uint32_t partial; | 902 | uint32_t partial; |
904 | struct qla2_sgx sgx; | 903 | struct qla2_sgx sgx; |
@@ -966,7 +965,7 @@ alloc_and_fill: | |||
966 | } else { | 965 | } else { |
967 | list_add_tail(&dsd_ptr->list, | 966 | list_add_tail(&dsd_ptr->list, |
968 | &(tc->ctx->dsd_list)); | 967 | &(tc->ctx->dsd_list)); |
969 | tc->ctx_dsd_alloced = 1; | 968 | *tc->ctx_dsd_alloced = 1; |
970 | } | 969 | } |
971 | 970 | ||
972 | 971 | ||
@@ -1005,7 +1004,7 @@ alloc_and_fill: | |||
1005 | 1004 | ||
1006 | int | 1005 | int |
1007 | qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, | 1006 | qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, |
1008 | uint16_t tot_dsds, struct qla_tgt_cmd *tc) | 1007 | uint16_t tot_dsds, struct qla_tc_param *tc) |
1009 | { | 1008 | { |
1010 | void *next_dsd; | 1009 | void *next_dsd; |
1011 | uint8_t avail_dsds = 0; | 1010 | uint8_t avail_dsds = 0; |
@@ -1066,7 +1065,7 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, | |||
1066 | } else { | 1065 | } else { |
1067 | list_add_tail(&dsd_ptr->list, | 1066 | list_add_tail(&dsd_ptr->list, |
1068 | &(tc->ctx->dsd_list)); | 1067 | &(tc->ctx->dsd_list)); |
1069 | tc->ctx_dsd_alloced = 1; | 1068 | *tc->ctx_dsd_alloced = 1; |
1070 | } | 1069 | } |
1071 | 1070 | ||
1072 | /* add new list to cmd iocb or last list */ | 1071 | /* add new list to cmd iocb or last list */ |
@@ -1092,7 +1091,7 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, | |||
1092 | 1091 | ||
1093 | int | 1092 | int |
1094 | qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, | 1093 | qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, |
1095 | uint32_t *dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc) | 1094 | uint32_t *dsd, uint16_t tot_dsds, struct qla_tc_param *tc) |
1096 | { | 1095 | { |
1097 | void *next_dsd; | 1096 | void *next_dsd; |
1098 | uint8_t avail_dsds = 0; | 1097 | uint8_t avail_dsds = 0; |
@@ -1158,7 +1157,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, | |||
1158 | } else { | 1157 | } else { |
1159 | list_add_tail(&dsd_ptr->list, | 1158 | list_add_tail(&dsd_ptr->list, |
1160 | &(tc->ctx->dsd_list)); | 1159 | &(tc->ctx->dsd_list)); |
1161 | tc->ctx_dsd_alloced = 1; | 1160 | *tc->ctx_dsd_alloced = 1; |
1162 | } | 1161 | } |
1163 | 1162 | ||
1164 | /* add new list to cmd iocb or last list */ | 1163 | /* add new list to cmd iocb or last list */ |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 3c66ea29de27..3203367a4f42 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -708,6 +708,8 @@ skip_rio: | |||
708 | "mbx7=%xh.\n", mb[1], mb[2], mb[3], mbx); | 708 | "mbx7=%xh.\n", mb[1], mb[2], mb[3], mbx); |
709 | 709 | ||
710 | ha->isp_ops->fw_dump(vha, 1); | 710 | ha->isp_ops->fw_dump(vha, 1); |
711 | ha->flags.fw_init_done = 0; | ||
712 | ha->flags.fw_started = 0; | ||
711 | 713 | ||
712 | if (IS_FWI2_CAPABLE(ha)) { | 714 | if (IS_FWI2_CAPABLE(ha)) { |
713 | if (mb[1] == 0 && mb[2] == 0) { | 715 | if (mb[1] == 0 && mb[2] == 0) { |
@@ -761,6 +763,9 @@ skip_rio: | |||
761 | break; | 763 | break; |
762 | 764 | ||
763 | case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */ | 765 | case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */ |
766 | ha->flags.lip_ae = 1; | ||
767 | ha->flags.n2n_ae = 0; | ||
768 | |||
764 | ql_dbg(ql_dbg_async, vha, 0x5009, | 769 | ql_dbg(ql_dbg_async, vha, 0x5009, |
765 | "LIP occurred (%x).\n", mb[1]); | 770 | "LIP occurred (%x).\n", mb[1]); |
766 | 771 | ||
@@ -797,6 +802,10 @@ skip_rio: | |||
797 | break; | 802 | break; |
798 | 803 | ||
799 | case MBA_LOOP_DOWN: /* Loop Down Event */ | 804 | case MBA_LOOP_DOWN: /* Loop Down Event */ |
805 | ha->flags.n2n_ae = 0; | ||
806 | ha->flags.lip_ae = 0; | ||
807 | ha->current_topology = 0; | ||
808 | |||
800 | mbx = (IS_QLA81XX(ha) || IS_QLA8031(ha)) | 809 | mbx = (IS_QLA81XX(ha) || IS_QLA8031(ha)) |
801 | ? RD_REG_WORD(®24->mailbox4) : 0; | 810 | ? RD_REG_WORD(®24->mailbox4) : 0; |
802 | mbx = (IS_P3P_TYPE(ha)) ? RD_REG_WORD(®82->mailbox_out[4]) | 811 | mbx = (IS_P3P_TYPE(ha)) ? RD_REG_WORD(®82->mailbox_out[4]) |
@@ -866,6 +875,9 @@ skip_rio: | |||
866 | 875 | ||
867 | /* case MBA_DCBX_COMPLETE: */ | 876 | /* case MBA_DCBX_COMPLETE: */ |
868 | case MBA_POINT_TO_POINT: /* Point-to-Point */ | 877 | case MBA_POINT_TO_POINT: /* Point-to-Point */ |
878 | ha->flags.lip_ae = 0; | ||
879 | ha->flags.n2n_ae = 1; | ||
880 | |||
869 | if (IS_QLA2100(ha)) | 881 | if (IS_QLA2100(ha)) |
870 | break; | 882 | break; |
871 | 883 | ||
@@ -1620,9 +1632,9 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1620 | QLA_LOGIO_LOGIN_RETRIED : 0; | 1632 | QLA_LOGIO_LOGIN_RETRIED : 0; |
1621 | if (logio->entry_status) { | 1633 | if (logio->entry_status) { |
1622 | ql_log(ql_log_warn, fcport->vha, 0x5034, | 1634 | ql_log(ql_log_warn, fcport->vha, 0x5034, |
1623 | "Async-%s error entry - hdl=%x" | 1635 | "Async-%s error entry - %8phC hdl=%x" |
1624 | "portid=%02x%02x%02x entry-status=%x.\n", | 1636 | "portid=%02x%02x%02x entry-status=%x.\n", |
1625 | type, sp->handle, fcport->d_id.b.domain, | 1637 | type, fcport->port_name, sp->handle, fcport->d_id.b.domain, |
1626 | fcport->d_id.b.area, fcport->d_id.b.al_pa, | 1638 | fcport->d_id.b.area, fcport->d_id.b.al_pa, |
1627 | logio->entry_status); | 1639 | logio->entry_status); |
1628 | ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x504d, | 1640 | ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x504d, |
@@ -1633,8 +1645,9 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1633 | 1645 | ||
1634 | if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) { | 1646 | if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) { |
1635 | ql_dbg(ql_dbg_async, fcport->vha, 0x5036, | 1647 | ql_dbg(ql_dbg_async, fcport->vha, 0x5036, |
1636 | "Async-%s complete - hdl=%x portid=%02x%02x%02x " | 1648 | "Async-%s complete - %8phC hdl=%x portid=%02x%02x%02x " |
1637 | "iop0=%x.\n", type, sp->handle, fcport->d_id.b.domain, | 1649 | "iop0=%x.\n", type, fcport->port_name, sp->handle, |
1650 | fcport->d_id.b.domain, | ||
1638 | fcport->d_id.b.area, fcport->d_id.b.al_pa, | 1651 | fcport->d_id.b.area, fcport->d_id.b.al_pa, |
1639 | le32_to_cpu(logio->io_parameter[0])); | 1652 | le32_to_cpu(logio->io_parameter[0])); |
1640 | 1653 | ||
@@ -1674,6 +1687,17 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1674 | case LSC_SCODE_NPORT_USED: | 1687 | case LSC_SCODE_NPORT_USED: |
1675 | data[0] = MBS_LOOP_ID_USED; | 1688 | data[0] = MBS_LOOP_ID_USED; |
1676 | break; | 1689 | break; |
1690 | case LSC_SCODE_CMD_FAILED: | ||
1691 | if (iop[1] == 0x0606) { | ||
1692 | /* | ||
1693 | * PLOGI/PRLI Completed. We must have Recv PLOGI/PRLI, | ||
1694 | * Target side acked. | ||
1695 | */ | ||
1696 | data[0] = MBS_COMMAND_COMPLETE; | ||
1697 | goto logio_done; | ||
1698 | } | ||
1699 | data[0] = MBS_COMMAND_ERROR; | ||
1700 | break; | ||
1677 | case LSC_SCODE_NOXCB: | 1701 | case LSC_SCODE_NOXCB: |
1678 | vha->hw->exch_starvation++; | 1702 | vha->hw->exch_starvation++; |
1679 | if (vha->hw->exch_starvation > 5) { | 1703 | if (vha->hw->exch_starvation > 5) { |
@@ -1695,8 +1719,9 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1695 | } | 1719 | } |
1696 | 1720 | ||
1697 | ql_dbg(ql_dbg_async, fcport->vha, 0x5037, | 1721 | ql_dbg(ql_dbg_async, fcport->vha, 0x5037, |
1698 | "Async-%s failed - hdl=%x portid=%02x%02x%02x comp=%x " | 1722 | "Async-%s failed - %8phC hdl=%x portid=%02x%02x%02x comp=%x " |
1699 | "iop0=%x iop1=%x.\n", type, sp->handle, fcport->d_id.b.domain, | 1723 | "iop0=%x iop1=%x.\n", type, fcport->port_name, |
1724 | sp->handle, fcport->d_id.b.domain, | ||
1700 | fcport->d_id.b.area, fcport->d_id.b.al_pa, | 1725 | fcport->d_id.b.area, fcport->d_id.b.al_pa, |
1701 | le16_to_cpu(logio->comp_status), | 1726 | le16_to_cpu(logio->comp_status), |
1702 | le32_to_cpu(logio->io_parameter[0]), | 1727 | le32_to_cpu(logio->io_parameter[0]), |
@@ -2679,7 +2704,7 @@ qla24xx_abort_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
2679 | return; | 2704 | return; |
2680 | 2705 | ||
2681 | abt = &sp->u.iocb_cmd; | 2706 | abt = &sp->u.iocb_cmd; |
2682 | abt->u.abt.comp_status = le32_to_cpu(pkt->nport_handle); | 2707 | abt->u.abt.comp_status = le16_to_cpu(pkt->nport_handle); |
2683 | sp->done(sp, 0); | 2708 | sp->done(sp, 0); |
2684 | } | 2709 | } |
2685 | 2710 | ||
@@ -2693,7 +2718,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, | |||
2693 | struct sts_entry_24xx *pkt; | 2718 | struct sts_entry_24xx *pkt; |
2694 | struct qla_hw_data *ha = vha->hw; | 2719 | struct qla_hw_data *ha = vha->hw; |
2695 | 2720 | ||
2696 | if (!vha->flags.online) | 2721 | if (!ha->flags.fw_started) |
2697 | return; | 2722 | return; |
2698 | 2723 | ||
2699 | while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) { | 2724 | while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) { |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 35079f417417..a113ab3592a7 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -10,6 +10,28 @@ | |||
10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
11 | #include <linux/gfp.h> | 11 | #include <linux/gfp.h> |
12 | 12 | ||
13 | static struct mb_cmd_name { | ||
14 | uint16_t cmd; | ||
15 | const char *str; | ||
16 | } mb_str[] = { | ||
17 | {MBC_GET_PORT_DATABASE, "GPDB"}, | ||
18 | {MBC_GET_ID_LIST, "GIDList"}, | ||
19 | {MBC_GET_LINK_PRIV_STATS, "Stats"}, | ||
20 | }; | ||
21 | |||
22 | static const char *mb_to_str(uint16_t cmd) | ||
23 | { | ||
24 | int i; | ||
25 | struct mb_cmd_name *e; | ||
26 | |||
27 | for (i = 0; i < ARRAY_SIZE(mb_str); i++) { | ||
28 | e = mb_str + i; | ||
29 | if (cmd == e->cmd) | ||
30 | return e->str; | ||
31 | } | ||
32 | return "unknown"; | ||
33 | } | ||
34 | |||
13 | static struct rom_cmd { | 35 | static struct rom_cmd { |
14 | uint16_t cmd; | 36 | uint16_t cmd; |
15 | } rom_cmds[] = { | 37 | } rom_cmds[] = { |
@@ -2818,7 +2840,7 @@ qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id, | |||
2818 | 2840 | ||
2819 | int | 2841 | int |
2820 | qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats, | 2842 | qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats, |
2821 | dma_addr_t stats_dma, uint options) | 2843 | dma_addr_t stats_dma, uint16_t options) |
2822 | { | 2844 | { |
2823 | int rval; | 2845 | int rval; |
2824 | mbx_cmd_t mc; | 2846 | mbx_cmd_t mc; |
@@ -2828,19 +2850,17 @@ qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats, | |||
2828 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088, | 2850 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088, |
2829 | "Entered %s.\n", __func__); | 2851 | "Entered %s.\n", __func__); |
2830 | 2852 | ||
2831 | mcp->mb[0] = MBC_GET_LINK_PRIV_STATS; | 2853 | memset(&mc, 0, sizeof(mc)); |
2832 | mcp->mb[2] = MSW(stats_dma); | 2854 | mc.mb[0] = MBC_GET_LINK_PRIV_STATS; |
2833 | mcp->mb[3] = LSW(stats_dma); | 2855 | mc.mb[2] = MSW(stats_dma); |
2834 | mcp->mb[6] = MSW(MSD(stats_dma)); | 2856 | mc.mb[3] = LSW(stats_dma); |
2835 | mcp->mb[7] = LSW(MSD(stats_dma)); | 2857 | mc.mb[6] = MSW(MSD(stats_dma)); |
2836 | mcp->mb[8] = sizeof(struct link_statistics) / 4; | 2858 | mc.mb[7] = LSW(MSD(stats_dma)); |
2837 | mcp->mb[9] = vha->vp_idx; | 2859 | mc.mb[8] = sizeof(struct link_statistics) / 4; |
2838 | mcp->mb[10] = options; | 2860 | mc.mb[9] = cpu_to_le16(vha->vp_idx); |
2839 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; | 2861 | mc.mb[10] = cpu_to_le16(options); |
2840 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | 2862 | |
2841 | mcp->tov = MBX_TOV_SECONDS; | 2863 | rval = qla24xx_send_mb_cmd(vha, &mc); |
2842 | mcp->flags = IOCTL_CMD; | ||
2843 | rval = qla2x00_mailbox_command(vha, mcp); | ||
2844 | 2864 | ||
2845 | if (rval == QLA_SUCCESS) { | 2865 | if (rval == QLA_SUCCESS) { |
2846 | if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { | 2866 | if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { |
@@ -3603,6 +3623,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, | |||
3603 | scsi_qla_host_t *vp = NULL; | 3623 | scsi_qla_host_t *vp = NULL; |
3604 | unsigned long flags; | 3624 | unsigned long flags; |
3605 | int found; | 3625 | int found; |
3626 | port_id_t id; | ||
3606 | 3627 | ||
3607 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6, | 3628 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6, |
3608 | "Entered %s.\n", __func__); | 3629 | "Entered %s.\n", __func__); |
@@ -3610,28 +3631,27 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, | |||
3610 | if (rptid_entry->entry_status != 0) | 3631 | if (rptid_entry->entry_status != 0) |
3611 | return; | 3632 | return; |
3612 | 3633 | ||
3634 | id.b.domain = rptid_entry->port_id[2]; | ||
3635 | id.b.area = rptid_entry->port_id[1]; | ||
3636 | id.b.al_pa = rptid_entry->port_id[0]; | ||
3637 | id.b.rsvd_1 = 0; | ||
3638 | |||
3613 | if (rptid_entry->format == 0) { | 3639 | if (rptid_entry->format == 0) { |
3614 | /* loop */ | 3640 | /* loop */ |
3615 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b7, | 3641 | ql_dbg(ql_dbg_async, vha, 0x10b7, |
3616 | "Format 0 : Number of VPs setup %d, number of " | 3642 | "Format 0 : Number of VPs setup %d, number of " |
3617 | "VPs acquired %d.\n", rptid_entry->vp_setup, | 3643 | "VPs acquired %d.\n", rptid_entry->vp_setup, |
3618 | rptid_entry->vp_acquired); | 3644 | rptid_entry->vp_acquired); |
3619 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b8, | 3645 | ql_dbg(ql_dbg_async, vha, 0x10b8, |
3620 | "Primary port id %02x%02x%02x.\n", | 3646 | "Primary port id %02x%02x%02x.\n", |
3621 | rptid_entry->port_id[2], rptid_entry->port_id[1], | 3647 | rptid_entry->port_id[2], rptid_entry->port_id[1], |
3622 | rptid_entry->port_id[0]); | 3648 | rptid_entry->port_id[0]); |
3623 | 3649 | ||
3624 | vha->d_id.b.domain = rptid_entry->port_id[2]; | 3650 | qlt_update_host_map(vha, id); |
3625 | vha->d_id.b.area = rptid_entry->port_id[1]; | ||
3626 | vha->d_id.b.al_pa = rptid_entry->port_id[0]; | ||
3627 | |||
3628 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
3629 | qlt_update_vp_map(vha, SET_AL_PA); | ||
3630 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
3631 | 3651 | ||
3632 | } else if (rptid_entry->format == 1) { | 3652 | } else if (rptid_entry->format == 1) { |
3633 | /* fabric */ | 3653 | /* fabric */ |
3634 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b9, | 3654 | ql_dbg(ql_dbg_async, vha, 0x10b9, |
3635 | "Format 1: VP[%d] enabled - status %d - with " | 3655 | "Format 1: VP[%d] enabled - status %d - with " |
3636 | "port id %02x%02x%02x.\n", rptid_entry->vp_idx, | 3656 | "port id %02x%02x%02x.\n", rptid_entry->vp_idx, |
3637 | rptid_entry->vp_status, | 3657 | rptid_entry->vp_status, |
@@ -3653,12 +3673,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, | |||
3653 | WWN_SIZE); | 3673 | WWN_SIZE); |
3654 | } | 3674 | } |
3655 | 3675 | ||
3656 | vha->d_id.b.domain = rptid_entry->port_id[2]; | 3676 | qlt_update_host_map(vha, id); |
3657 | vha->d_id.b.area = rptid_entry->port_id[1]; | ||
3658 | vha->d_id.b.al_pa = rptid_entry->port_id[0]; | ||
3659 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
3660 | qlt_update_vp_map(vha, SET_AL_PA); | ||
3661 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
3662 | } | 3677 | } |
3663 | 3678 | ||
3664 | fc_host_port_name(vha->host) = | 3679 | fc_host_port_name(vha->host) = |
@@ -3694,12 +3709,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, | |||
3694 | if (!found) | 3709 | if (!found) |
3695 | return; | 3710 | return; |
3696 | 3711 | ||
3697 | vp->d_id.b.domain = rptid_entry->port_id[2]; | 3712 | qlt_update_host_map(vp, id); |
3698 | vp->d_id.b.area = rptid_entry->port_id[1]; | ||
3699 | vp->d_id.b.al_pa = rptid_entry->port_id[0]; | ||
3700 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
3701 | qlt_update_vp_map(vp, SET_AL_PA); | ||
3702 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
3703 | 3713 | ||
3704 | /* | 3714 | /* |
3705 | * Cannot configure here as we are still sitting on the | 3715 | * Cannot configure here as we are still sitting on the |
@@ -5827,3 +5837,225 @@ qla26xx_dport_diagnostics(scsi_qla_host_t *vha, | |||
5827 | 5837 | ||
5828 | return rval; | 5838 | return rval; |
5829 | } | 5839 | } |
5840 | |||
5841 | static void qla2x00_async_mb_sp_done(void *s, int res) | ||
5842 | { | ||
5843 | struct srb *sp = s; | ||
5844 | |||
5845 | sp->u.iocb_cmd.u.mbx.rc = res; | ||
5846 | |||
5847 | complete(&sp->u.iocb_cmd.u.mbx.comp); | ||
5848 | /* don't free sp here. Let the caller do the free */ | ||
5849 | } | ||
5850 | |||
5851 | /* | ||
5852 | * This mailbox uses the iocb interface to send MB command. | ||
5853 | * This allows non-critial (non chip setup) command to go | ||
5854 | * out in parrallel. | ||
5855 | */ | ||
5856 | int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp) | ||
5857 | { | ||
5858 | int rval = QLA_FUNCTION_FAILED; | ||
5859 | srb_t *sp; | ||
5860 | struct srb_iocb *c; | ||
5861 | |||
5862 | if (!vha->hw->flags.fw_started) | ||
5863 | goto done; | ||
5864 | |||
5865 | sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); | ||
5866 | if (!sp) | ||
5867 | goto done; | ||
5868 | |||
5869 | sp->type = SRB_MB_IOCB; | ||
5870 | sp->name = mb_to_str(mcp->mb[0]); | ||
5871 | |||
5872 | qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); | ||
5873 | |||
5874 | memcpy(sp->u.iocb_cmd.u.mbx.out_mb, mcp->mb, SIZEOF_IOCB_MB_REG); | ||
5875 | |||
5876 | c = &sp->u.iocb_cmd; | ||
5877 | c->timeout = qla2x00_async_iocb_timeout; | ||
5878 | init_completion(&c->u.mbx.comp); | ||
5879 | |||
5880 | sp->done = qla2x00_async_mb_sp_done; | ||
5881 | |||
5882 | rval = qla2x00_start_sp(sp); | ||
5883 | if (rval != QLA_SUCCESS) { | ||
5884 | ql_dbg(ql_dbg_mbx, vha, 0xffff, | ||
5885 | "%s: %s Failed submission. %x.\n", | ||
5886 | __func__, sp->name, rval); | ||
5887 | goto done_free_sp; | ||
5888 | } | ||
5889 | |||
5890 | ql_dbg(ql_dbg_mbx, vha, 0xffff, "MB:%s hndl %x submitted\n", | ||
5891 | sp->name, sp->handle); | ||
5892 | |||
5893 | wait_for_completion(&c->u.mbx.comp); | ||
5894 | memcpy(mcp->mb, sp->u.iocb_cmd.u.mbx.in_mb, SIZEOF_IOCB_MB_REG); | ||
5895 | |||
5896 | rval = c->u.mbx.rc; | ||
5897 | switch (rval) { | ||
5898 | case QLA_FUNCTION_TIMEOUT: | ||
5899 | ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %s Timeout. %x.\n", | ||
5900 | __func__, sp->name, rval); | ||
5901 | break; | ||
5902 | case QLA_SUCCESS: | ||
5903 | ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %s done.\n", | ||
5904 | __func__, sp->name); | ||
5905 | sp->free(sp); | ||
5906 | break; | ||
5907 | default: | ||
5908 | ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %s Failed. %x.\n", | ||
5909 | __func__, sp->name, rval); | ||
5910 | sp->free(sp); | ||
5911 | break; | ||
5912 | } | ||
5913 | |||
5914 | return rval; | ||
5915 | |||
5916 | done_free_sp: | ||
5917 | sp->free(sp); | ||
5918 | done: | ||
5919 | return rval; | ||
5920 | } | ||
5921 | |||
5922 | /* | ||
5923 | * qla24xx_gpdb_wait | ||
5924 | * NOTE: Do not call this routine from DPC thread | ||
5925 | */ | ||
5926 | int qla24xx_gpdb_wait(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt) | ||
5927 | { | ||
5928 | int rval = QLA_FUNCTION_FAILED; | ||
5929 | dma_addr_t pd_dma; | ||
5930 | struct port_database_24xx *pd; | ||
5931 | struct qla_hw_data *ha = vha->hw; | ||
5932 | mbx_cmd_t mc; | ||
5933 | |||
5934 | if (!vha->hw->flags.fw_started) | ||
5935 | goto done; | ||
5936 | |||
5937 | pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); | ||
5938 | if (pd == NULL) { | ||
5939 | ql_log(ql_log_warn, vha, 0xffff, | ||
5940 | "Failed to allocate port database structure.\n"); | ||
5941 | goto done_free_sp; | ||
5942 | } | ||
5943 | memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE)); | ||
5944 | |||
5945 | memset(&mc, 0, sizeof(mc)); | ||
5946 | mc.mb[0] = MBC_GET_PORT_DATABASE; | ||
5947 | mc.mb[1] = cpu_to_le16(fcport->loop_id); | ||
5948 | mc.mb[2] = MSW(pd_dma); | ||
5949 | mc.mb[3] = LSW(pd_dma); | ||
5950 | mc.mb[6] = MSW(MSD(pd_dma)); | ||
5951 | mc.mb[7] = LSW(MSD(pd_dma)); | ||
5952 | mc.mb[9] = cpu_to_le16(vha->vp_idx); | ||
5953 | mc.mb[10] = cpu_to_le16((uint16_t)opt); | ||
5954 | |||
5955 | rval = qla24xx_send_mb_cmd(vha, &mc); | ||
5956 | if (rval != QLA_SUCCESS) { | ||
5957 | ql_dbg(ql_dbg_mbx, vha, 0xffff, | ||
5958 | "%s: %8phC fail\n", __func__, fcport->port_name); | ||
5959 | goto done_free_sp; | ||
5960 | } | ||
5961 | |||
5962 | rval = __qla24xx_parse_gpdb(vha, fcport, pd); | ||
5963 | |||
5964 | ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %8phC done\n", | ||
5965 | __func__, fcport->port_name); | ||
5966 | |||
5967 | done_free_sp: | ||
5968 | if (pd) | ||
5969 | dma_pool_free(ha->s_dma_pool, pd, pd_dma); | ||
5970 | done: | ||
5971 | return rval; | ||
5972 | } | ||
5973 | |||
5974 | int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, | ||
5975 | struct port_database_24xx *pd) | ||
5976 | { | ||
5977 | int rval = QLA_SUCCESS; | ||
5978 | uint64_t zero = 0; | ||
5979 | |||
5980 | /* Check for logged in state. */ | ||
5981 | if (pd->current_login_state != PDS_PRLI_COMPLETE && | ||
5982 | pd->last_login_state != PDS_PRLI_COMPLETE) { | ||
5983 | ql_dbg(ql_dbg_mbx, vha, 0xffff, | ||
5984 | "Unable to verify login-state (%x/%x) for " | ||
5985 | "loop_id %x.\n", pd->current_login_state, | ||
5986 | pd->last_login_state, fcport->loop_id); | ||
5987 | rval = QLA_FUNCTION_FAILED; | ||
5988 | goto gpd_error_out; | ||
5989 | } | ||
5990 | |||
5991 | if (fcport->loop_id == FC_NO_LOOP_ID || | ||
5992 | (memcmp(fcport->port_name, (uint8_t *)&zero, 8) && | ||
5993 | memcmp(fcport->port_name, pd->port_name, 8))) { | ||
5994 | /* We lost the device mid way. */ | ||
5995 | rval = QLA_NOT_LOGGED_IN; | ||
5996 | goto gpd_error_out; | ||
5997 | } | ||
5998 | |||
5999 | /* Names are little-endian. */ | ||
6000 | memcpy(fcport->node_name, pd->node_name, WWN_SIZE); | ||
6001 | memcpy(fcport->port_name, pd->port_name, WWN_SIZE); | ||
6002 | |||
6003 | /* Get port_id of device. */ | ||
6004 | fcport->d_id.b.domain = pd->port_id[0]; | ||
6005 | fcport->d_id.b.area = pd->port_id[1]; | ||
6006 | fcport->d_id.b.al_pa = pd->port_id[2]; | ||
6007 | fcport->d_id.b.rsvd_1 = 0; | ||
6008 | |||
6009 | /* If not target must be initiator or unknown type. */ | ||
6010 | if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) | ||
6011 | fcport->port_type = FCT_INITIATOR; | ||
6012 | else | ||
6013 | fcport->port_type = FCT_TARGET; | ||
6014 | |||
6015 | /* Passback COS information. */ | ||
6016 | fcport->supported_classes = (pd->flags & PDF_CLASS_2) ? | ||
6017 | FC_COS_CLASS2 : FC_COS_CLASS3; | ||
6018 | |||
6019 | if (pd->prli_svc_param_word_3[0] & BIT_7) { | ||
6020 | fcport->flags |= FCF_CONF_COMP_SUPPORTED; | ||
6021 | fcport->conf_compl_supported = 1; | ||
6022 | } | ||
6023 | |||
6024 | gpd_error_out: | ||
6025 | return rval; | ||
6026 | } | ||
6027 | |||
6028 | /* | ||
6029 | * qla24xx_gidlist__wait | ||
6030 | * NOTE: don't call this routine from DPC thread. | ||
6031 | */ | ||
6032 | int qla24xx_gidlist_wait(struct scsi_qla_host *vha, | ||
6033 | void *id_list, dma_addr_t id_list_dma, uint16_t *entries) | ||
6034 | { | ||
6035 | int rval = QLA_FUNCTION_FAILED; | ||
6036 | mbx_cmd_t mc; | ||
6037 | |||
6038 | if (!vha->hw->flags.fw_started) | ||
6039 | goto done; | ||
6040 | |||
6041 | memset(&mc, 0, sizeof(mc)); | ||
6042 | mc.mb[0] = MBC_GET_ID_LIST; | ||
6043 | mc.mb[2] = MSW(id_list_dma); | ||
6044 | mc.mb[3] = LSW(id_list_dma); | ||
6045 | mc.mb[6] = MSW(MSD(id_list_dma)); | ||
6046 | mc.mb[7] = LSW(MSD(id_list_dma)); | ||
6047 | mc.mb[8] = 0; | ||
6048 | mc.mb[9] = cpu_to_le16(vha->vp_idx); | ||
6049 | |||
6050 | rval = qla24xx_send_mb_cmd(vha, &mc); | ||
6051 | if (rval != QLA_SUCCESS) { | ||
6052 | ql_dbg(ql_dbg_mbx, vha, 0xffff, | ||
6053 | "%s: fail\n", __func__); | ||
6054 | } else { | ||
6055 | *entries = mc.mb[1]; | ||
6056 | ql_dbg(ql_dbg_mbx, vha, 0xffff, | ||
6057 | "%s: done\n", __func__); | ||
6058 | } | ||
6059 | done: | ||
6060 | return rval; | ||
6061 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index c6d6f0d912ff..09a490c98763 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -74,13 +74,14 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha) | |||
74 | * ensures no active vp_list traversal while the vport is removed | 74 | * ensures no active vp_list traversal while the vport is removed |
75 | * from the queue) | 75 | * from the queue) |
76 | */ | 76 | */ |
77 | spin_lock_irqsave(&ha->vport_slock, flags); | 77 | wait_event_timeout(vha->vref_waitq, atomic_read(&vha->vref_count), |
78 | while (atomic_read(&vha->vref_count)) { | 78 | 10*HZ); |
79 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
80 | |||
81 | msleep(500); | ||
82 | 79 | ||
83 | spin_lock_irqsave(&ha->vport_slock, flags); | 80 | spin_lock_irqsave(&ha->vport_slock, flags); |
81 | if (atomic_read(&vha->vref_count)) { | ||
82 | ql_dbg(ql_dbg_vport, vha, 0xfffa, | ||
83 | "vha->vref_count=%u timeout\n", vha->vref_count.counter); | ||
84 | vha->vref_count = (atomic_t)ATOMIC_INIT(0); | ||
84 | } | 85 | } |
85 | list_del(&vha->list); | 86 | list_del(&vha->list); |
86 | qlt_update_vp_map(vha, RESET_VP_IDX); | 87 | qlt_update_vp_map(vha, RESET_VP_IDX); |
@@ -269,6 +270,7 @@ qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb) | |||
269 | 270 | ||
270 | spin_lock_irqsave(&ha->vport_slock, flags); | 271 | spin_lock_irqsave(&ha->vport_slock, flags); |
271 | atomic_dec(&vha->vref_count); | 272 | atomic_dec(&vha->vref_count); |
273 | wake_up(&vha->vref_waitq); | ||
272 | } | 274 | } |
273 | i++; | 275 | i++; |
274 | } | 276 | } |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 1fed235a1b4a..41d5b09f7326 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -2560,6 +2560,20 @@ qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time) | |||
2560 | return atomic_read(&vha->loop_state) == LOOP_READY; | 2560 | return atomic_read(&vha->loop_state) == LOOP_READY; |
2561 | } | 2561 | } |
2562 | 2562 | ||
2563 | static void qla2x00_iocb_work_fn(struct work_struct *work) | ||
2564 | { | ||
2565 | struct scsi_qla_host *vha = container_of(work, | ||
2566 | struct scsi_qla_host, iocb_work); | ||
2567 | int cnt = 0; | ||
2568 | |||
2569 | while (!list_empty(&vha->work_list)) { | ||
2570 | qla2x00_do_work(vha); | ||
2571 | cnt++; | ||
2572 | if (cnt > 10) | ||
2573 | break; | ||
2574 | } | ||
2575 | } | ||
2576 | |||
2563 | /* | 2577 | /* |
2564 | * PCI driver interface | 2578 | * PCI driver interface |
2565 | */ | 2579 | */ |
@@ -3078,6 +3092,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
3078 | */ | 3092 | */ |
3079 | qla2xxx_wake_dpc(base_vha); | 3093 | qla2xxx_wake_dpc(base_vha); |
3080 | 3094 | ||
3095 | INIT_WORK(&base_vha->iocb_work, qla2x00_iocb_work_fn); | ||
3081 | INIT_WORK(&ha->board_disable, qla2x00_disable_board_on_pci_error); | 3096 | INIT_WORK(&ha->board_disable, qla2x00_disable_board_on_pci_error); |
3082 | 3097 | ||
3083 | if (IS_QLA8031(ha) || IS_MCTP_CAPABLE(ha)) { | 3098 | if (IS_QLA8031(ha) || IS_MCTP_CAPABLE(ha)) { |
@@ -3469,6 +3484,7 @@ qla2x00_remove_one(struct pci_dev *pdev) | |||
3469 | qla2x00_free_sysfs_attr(base_vha, true); | 3484 | qla2x00_free_sysfs_attr(base_vha, true); |
3470 | 3485 | ||
3471 | fc_remove_host(base_vha->host); | 3486 | fc_remove_host(base_vha->host); |
3487 | qlt_remove_target_resources(ha); | ||
3472 | 3488 | ||
3473 | scsi_remove_host(base_vha->host); | 3489 | scsi_remove_host(base_vha->host); |
3474 | 3490 | ||
@@ -4268,6 +4284,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, | |||
4268 | spin_lock_init(&vha->work_lock); | 4284 | spin_lock_init(&vha->work_lock); |
4269 | spin_lock_init(&vha->cmd_list_lock); | 4285 | spin_lock_init(&vha->cmd_list_lock); |
4270 | init_waitqueue_head(&vha->fcport_waitQ); | 4286 | init_waitqueue_head(&vha->fcport_waitQ); |
4287 | init_waitqueue_head(&vha->vref_waitq); | ||
4271 | 4288 | ||
4272 | vha->gnl.size = sizeof(struct get_name_list_extended) * | 4289 | vha->gnl.size = sizeof(struct get_name_list_extended) * |
4273 | (ha->max_loop_id + 1); | 4290 | (ha->max_loop_id + 1); |
@@ -4319,7 +4336,11 @@ qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e) | |||
4319 | spin_lock_irqsave(&vha->work_lock, flags); | 4336 | spin_lock_irqsave(&vha->work_lock, flags); |
4320 | list_add_tail(&e->list, &vha->work_list); | 4337 | list_add_tail(&e->list, &vha->work_list); |
4321 | spin_unlock_irqrestore(&vha->work_lock, flags); | 4338 | spin_unlock_irqrestore(&vha->work_lock, flags); |
4322 | qla2xxx_wake_dpc(vha); | 4339 | |
4340 | if (QLA_EARLY_LINKUP(vha->hw)) | ||
4341 | schedule_work(&vha->iocb_work); | ||
4342 | else | ||
4343 | qla2xxx_wake_dpc(vha); | ||
4323 | 4344 | ||
4324 | return QLA_SUCCESS; | 4345 | return QLA_SUCCESS; |
4325 | } | 4346 | } |
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 45f5077684f0..0e03ca2ab3e5 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
@@ -130,6 +130,9 @@ static void qlt_send_term_imm_notif(struct scsi_qla_host *vha, | |||
130 | static struct fc_port *qlt_create_sess(struct scsi_qla_host *vha, | 130 | static struct fc_port *qlt_create_sess(struct scsi_qla_host *vha, |
131 | fc_port_t *fcport, bool local); | 131 | fc_port_t *fcport, bool local); |
132 | void qlt_unreg_sess(struct fc_port *sess); | 132 | void qlt_unreg_sess(struct fc_port *sess); |
133 | static void qlt_24xx_handle_abts(struct scsi_qla_host *, | ||
134 | struct abts_recv_from_24xx *); | ||
135 | |||
133 | /* | 136 | /* |
134 | * Global Variables | 137 | * Global Variables |
135 | */ | 138 | */ |
@@ -140,6 +143,20 @@ static struct workqueue_struct *qla_tgt_wq; | |||
140 | static DEFINE_MUTEX(qla_tgt_mutex); | 143 | static DEFINE_MUTEX(qla_tgt_mutex); |
141 | static LIST_HEAD(qla_tgt_glist); | 144 | static LIST_HEAD(qla_tgt_glist); |
142 | 145 | ||
146 | static const char *prot_op_str(u32 prot_op) | ||
147 | { | ||
148 | switch (prot_op) { | ||
149 | case TARGET_PROT_NORMAL: return "NORMAL"; | ||
150 | case TARGET_PROT_DIN_INSERT: return "DIN_INSERT"; | ||
151 | case TARGET_PROT_DOUT_INSERT: return "DOUT_INSERT"; | ||
152 | case TARGET_PROT_DIN_STRIP: return "DIN_STRIP"; | ||
153 | case TARGET_PROT_DOUT_STRIP: return "DOUT_STRIP"; | ||
154 | case TARGET_PROT_DIN_PASS: return "DIN_PASS"; | ||
155 | case TARGET_PROT_DOUT_PASS: return "DOUT_PASS"; | ||
156 | default: return "UNKNOWN"; | ||
157 | } | ||
158 | } | ||
159 | |||
143 | /* This API intentionally takes dest as a parameter, rather than returning | 160 | /* This API intentionally takes dest as a parameter, rather than returning |
144 | * int value to avoid caller forgetting to issue wmb() after the store */ | 161 | * int value to avoid caller forgetting to issue wmb() after the store */ |
145 | void qlt_do_generation_tick(struct scsi_qla_host *vha, int *dest) | 162 | void qlt_do_generation_tick(struct scsi_qla_host *vha, int *dest) |
@@ -170,21 +187,23 @@ static inline | |||
170 | struct scsi_qla_host *qlt_find_host_by_d_id(struct scsi_qla_host *vha, | 187 | struct scsi_qla_host *qlt_find_host_by_d_id(struct scsi_qla_host *vha, |
171 | uint8_t *d_id) | 188 | uint8_t *d_id) |
172 | { | 189 | { |
173 | struct qla_hw_data *ha = vha->hw; | 190 | struct scsi_qla_host *host; |
174 | uint8_t vp_idx; | 191 | uint32_t key = 0; |
175 | |||
176 | if ((vha->d_id.b.area != d_id[1]) || (vha->d_id.b.domain != d_id[0])) | ||
177 | return NULL; | ||
178 | 192 | ||
179 | if (vha->d_id.b.al_pa == d_id[2]) | 193 | if ((vha->d_id.b.area == d_id[1]) && (vha->d_id.b.domain == d_id[0]) && |
194 | (vha->d_id.b.al_pa == d_id[2])) | ||
180 | return vha; | 195 | return vha; |
181 | 196 | ||
182 | BUG_ON(ha->tgt.tgt_vp_map == NULL); | 197 | key = (uint32_t)d_id[0] << 16; |
183 | vp_idx = ha->tgt.tgt_vp_map[d_id[2]].idx; | 198 | key |= (uint32_t)d_id[1] << 8; |
184 | if (likely(test_bit(vp_idx, ha->vp_idx_map))) | 199 | key |= (uint32_t)d_id[2]; |
185 | return ha->tgt.tgt_vp_map[vp_idx].vha; | ||
186 | 200 | ||
187 | return NULL; | 201 | host = btree_lookup32(&vha->hw->tgt.host_map, key); |
202 | if (!host) | ||
203 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff, | ||
204 | "Unable to find host %06x\n", key); | ||
205 | |||
206 | return host; | ||
188 | } | 207 | } |
189 | 208 | ||
190 | static inline | 209 | static inline |
@@ -389,6 +408,8 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, | |||
389 | (struct abts_recv_from_24xx *)atio; | 408 | (struct abts_recv_from_24xx *)atio; |
390 | struct scsi_qla_host *host = qlt_find_host_by_vp_idx(vha, | 409 | struct scsi_qla_host *host = qlt_find_host_by_vp_idx(vha, |
391 | entry->vp_index); | 410 | entry->vp_index); |
411 | unsigned long flags; | ||
412 | |||
392 | if (unlikely(!host)) { | 413 | if (unlikely(!host)) { |
393 | ql_dbg(ql_dbg_tgt, vha, 0xffff, | 414 | ql_dbg(ql_dbg_tgt, vha, 0xffff, |
394 | "qla_target(%d): Response pkt (ABTS_RECV_24XX) " | 415 | "qla_target(%d): Response pkt (ABTS_RECV_24XX) " |
@@ -396,9 +417,12 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, | |||
396 | vha->vp_idx, entry->vp_index); | 417 | vha->vp_idx, entry->vp_index); |
397 | break; | 418 | break; |
398 | } | 419 | } |
399 | qlt_response_pkt(host, (response_t *)atio); | 420 | if (!ha_locked) |
421 | spin_lock_irqsave(&host->hw->hardware_lock, flags); | ||
422 | qlt_24xx_handle_abts(host, (struct abts_recv_from_24xx *)atio); | ||
423 | if (!ha_locked) | ||
424 | spin_unlock_irqrestore(&host->hw->hardware_lock, flags); | ||
400 | break; | 425 | break; |
401 | |||
402 | } | 426 | } |
403 | 427 | ||
404 | /* case PUREX_IOCB_TYPE: ql2xmvasynctoatio */ | 428 | /* case PUREX_IOCB_TYPE: ql2xmvasynctoatio */ |
@@ -554,6 +578,7 @@ void qla2x00_async_nack_sp_done(void *s, int res) | |||
554 | sp->fcport->login_gen++; | 578 | sp->fcport->login_gen++; |
555 | sp->fcport->fw_login_state = DSC_LS_PLOGI_COMP; | 579 | sp->fcport->fw_login_state = DSC_LS_PLOGI_COMP; |
556 | sp->fcport->logout_on_delete = 1; | 580 | sp->fcport->logout_on_delete = 1; |
581 | sp->fcport->plogi_nack_done_deadline = jiffies + HZ; | ||
557 | break; | 582 | break; |
558 | 583 | ||
559 | case SRB_NACK_PRLI: | 584 | case SRB_NACK_PRLI: |
@@ -613,6 +638,7 @@ int qla24xx_async_notify_ack(scsi_qla_host_t *vha, fc_port_t *fcport, | |||
613 | break; | 638 | break; |
614 | case SRB_NACK_PRLI: | 639 | case SRB_NACK_PRLI: |
615 | fcport->fw_login_state = DSC_LS_PRLI_PEND; | 640 | fcport->fw_login_state = DSC_LS_PRLI_PEND; |
641 | fcport->deleted = 0; | ||
616 | c = "PRLI"; | 642 | c = "PRLI"; |
617 | break; | 643 | break; |
618 | case SRB_NACK_LOGO: | 644 | case SRB_NACK_LOGO: |
@@ -1215,7 +1241,7 @@ static int qla24xx_get_loop_id(struct scsi_qla_host *vha, const uint8_t *s_id, | |||
1215 | } | 1241 | } |
1216 | 1242 | ||
1217 | /* Get list of logged in devices */ | 1243 | /* Get list of logged in devices */ |
1218 | rc = qla2x00_get_id_list(vha, gid_list, gid_list_dma, &entries); | 1244 | rc = qla24xx_gidlist_wait(vha, gid_list, gid_list_dma, &entries); |
1219 | if (rc != QLA_SUCCESS) { | 1245 | if (rc != QLA_SUCCESS) { |
1220 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf045, | 1246 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf045, |
1221 | "qla_target(%d): get_id_list() failed: %x\n", | 1247 | "qla_target(%d): get_id_list() failed: %x\n", |
@@ -1551,6 +1577,9 @@ static void qlt_send_notify_ack(struct scsi_qla_host *vha, | |||
1551 | request_t *pkt; | 1577 | request_t *pkt; |
1552 | struct nack_to_isp *nack; | 1578 | struct nack_to_isp *nack; |
1553 | 1579 | ||
1580 | if (!ha->flags.fw_started) | ||
1581 | return; | ||
1582 | |||
1554 | ql_dbg(ql_dbg_tgt, vha, 0xe004, "Sending NOTIFY_ACK (ha=%p)\n", ha); | 1583 | ql_dbg(ql_dbg_tgt, vha, 0xe004, "Sending NOTIFY_ACK (ha=%p)\n", ha); |
1555 | 1584 | ||
1556 | /* Send marker if required */ | 1585 | /* Send marker if required */ |
@@ -2013,6 +2042,70 @@ void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd) | |||
2013 | } | 2042 | } |
2014 | EXPORT_SYMBOL(qlt_free_mcmd); | 2043 | EXPORT_SYMBOL(qlt_free_mcmd); |
2015 | 2044 | ||
2045 | /* | ||
2046 | * ha->hardware_lock supposed to be held on entry. Might drop it, then | ||
2047 | * reacquire | ||
2048 | */ | ||
2049 | void qlt_send_resp_ctio(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd, | ||
2050 | uint8_t scsi_status, uint8_t sense_key, uint8_t asc, uint8_t ascq) | ||
2051 | { | ||
2052 | struct atio_from_isp *atio = &cmd->atio; | ||
2053 | struct ctio7_to_24xx *ctio; | ||
2054 | uint16_t temp; | ||
2055 | |||
2056 | ql_dbg(ql_dbg_tgt_dif, vha, 0x3066, | ||
2057 | "Sending response CTIO7 (vha=%p, atio=%p, scsi_status=%02x, " | ||
2058 | "sense_key=%02x, asc=%02x, ascq=%02x", | ||
2059 | vha, atio, scsi_status, sense_key, asc, ascq); | ||
2060 | |||
2061 | ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs(vha, NULL); | ||
2062 | if (!ctio) { | ||
2063 | ql_dbg(ql_dbg_async, vha, 0x3067, | ||
2064 | "qla2x00t(%ld): %s failed: unable to allocate request packet", | ||
2065 | vha->host_no, __func__); | ||
2066 | goto out; | ||
2067 | } | ||
2068 | |||
2069 | ctio->entry_type = CTIO_TYPE7; | ||
2070 | ctio->entry_count = 1; | ||
2071 | ctio->handle = QLA_TGT_SKIP_HANDLE; | ||
2072 | ctio->nport_handle = cmd->sess->loop_id; | ||
2073 | ctio->timeout = cpu_to_le16(QLA_TGT_TIMEOUT); | ||
2074 | ctio->vp_index = vha->vp_idx; | ||
2075 | ctio->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; | ||
2076 | ctio->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; | ||
2077 | ctio->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; | ||
2078 | ctio->exchange_addr = atio->u.isp24.exchange_addr; | ||
2079 | ctio->u.status1.flags = (atio->u.isp24.attr << 9) | | ||
2080 | cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS); | ||
2081 | temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id); | ||
2082 | ctio->u.status1.ox_id = cpu_to_le16(temp); | ||
2083 | ctio->u.status1.scsi_status = | ||
2084 | cpu_to_le16(SS_RESPONSE_INFO_LEN_VALID | scsi_status); | ||
2085 | ctio->u.status1.response_len = cpu_to_le16(18); | ||
2086 | ctio->u.status1.residual = cpu_to_le32(get_datalen_for_atio(atio)); | ||
2087 | |||
2088 | if (ctio->u.status1.residual != 0) | ||
2089 | ctio->u.status1.scsi_status |= | ||
2090 | cpu_to_le16(SS_RESIDUAL_UNDER); | ||
2091 | |||
2092 | /* Response code and sense key */ | ||
2093 | put_unaligned_le32(((0x70 << 24) | (sense_key << 8)), | ||
2094 | (&ctio->u.status1.sense_data)[0]); | ||
2095 | /* Additional sense length */ | ||
2096 | put_unaligned_le32(0x0a, (&ctio->u.status1.sense_data)[1]); | ||
2097 | /* ASC and ASCQ */ | ||
2098 | put_unaligned_le32(((asc << 24) | (ascq << 16)), | ||
2099 | (&ctio->u.status1.sense_data)[3]); | ||
2100 | |||
2101 | /* Memory Barrier */ | ||
2102 | wmb(); | ||
2103 | |||
2104 | qla2x00_start_iocbs(vha, vha->req); | ||
2105 | out: | ||
2106 | return; | ||
2107 | } | ||
2108 | |||
2016 | /* callback from target fabric module code */ | 2109 | /* callback from target fabric module code */ |
2017 | void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd) | 2110 | void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd) |
2018 | { | 2111 | { |
@@ -2261,7 +2354,7 @@ static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm, | |||
2261 | */ | 2354 | */ |
2262 | return -EAGAIN; | 2355 | return -EAGAIN; |
2263 | } else | 2356 | } else |
2264 | ha->tgt.cmds[h-1] = prm->cmd; | 2357 | ha->tgt.cmds[h - 1] = prm->cmd; |
2265 | 2358 | ||
2266 | pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK; | 2359 | pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK; |
2267 | pkt->nport_handle = prm->cmd->loop_id; | 2360 | pkt->nport_handle = prm->cmd->loop_id; |
@@ -2391,6 +2484,50 @@ static inline int qlt_has_data(struct qla_tgt_cmd *cmd) | |||
2391 | return cmd->bufflen > 0; | 2484 | return cmd->bufflen > 0; |
2392 | } | 2485 | } |
2393 | 2486 | ||
2487 | static void qlt_print_dif_err(struct qla_tgt_prm *prm) | ||
2488 | { | ||
2489 | struct qla_tgt_cmd *cmd; | ||
2490 | struct scsi_qla_host *vha; | ||
2491 | |||
2492 | /* asc 0x10=dif error */ | ||
2493 | if (prm->sense_buffer && (prm->sense_buffer[12] == 0x10)) { | ||
2494 | cmd = prm->cmd; | ||
2495 | vha = cmd->vha; | ||
2496 | /* ASCQ */ | ||
2497 | switch (prm->sense_buffer[13]) { | ||
2498 | case 1: | ||
2499 | ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, | ||
2500 | "BE detected Guard TAG ERR: lba[0x%llx|%lld] len[0x%x] " | ||
2501 | "se_cmd=%p tag[%x]", | ||
2502 | cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, | ||
2503 | cmd->atio.u.isp24.exchange_addr); | ||
2504 | break; | ||
2505 | case 2: | ||
2506 | ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, | ||
2507 | "BE detected APP TAG ERR: lba[0x%llx|%lld] len[0x%x] " | ||
2508 | "se_cmd=%p tag[%x]", | ||
2509 | cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, | ||
2510 | cmd->atio.u.isp24.exchange_addr); | ||
2511 | break; | ||
2512 | case 3: | ||
2513 | ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, | ||
2514 | "BE detected REF TAG ERR: lba[0x%llx|%lld] len[0x%x] " | ||
2515 | "se_cmd=%p tag[%x]", | ||
2516 | cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, | ||
2517 | cmd->atio.u.isp24.exchange_addr); | ||
2518 | break; | ||
2519 | default: | ||
2520 | ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, | ||
2521 | "BE detected Dif ERR: lba[%llx|%lld] len[%x] " | ||
2522 | "se_cmd=%p tag[%x]", | ||
2523 | cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, | ||
2524 | cmd->atio.u.isp24.exchange_addr); | ||
2525 | break; | ||
2526 | } | ||
2527 | ql_dump_buffer(ql_dbg_tgt_dif, vha, 0xffff, cmd->cdb, 16); | ||
2528 | } | ||
2529 | } | ||
2530 | |||
2394 | /* | 2531 | /* |
2395 | * Called without ha->hardware_lock held | 2532 | * Called without ha->hardware_lock held |
2396 | */ | 2533 | */ |
@@ -2512,18 +2649,9 @@ skip_explict_conf: | |||
2512 | for (i = 0; i < prm->sense_buffer_len/4; i++) | 2649 | for (i = 0; i < prm->sense_buffer_len/4; i++) |
2513 | ((uint32_t *)ctio->u.status1.sense_data)[i] = | 2650 | ((uint32_t *)ctio->u.status1.sense_data)[i] = |
2514 | cpu_to_be32(((uint32_t *)prm->sense_buffer)[i]); | 2651 | cpu_to_be32(((uint32_t *)prm->sense_buffer)[i]); |
2515 | #if 0 | 2652 | |
2516 | if (unlikely((prm->sense_buffer_len % 4) != 0)) { | 2653 | qlt_print_dif_err(prm); |
2517 | static int q; | 2654 | |
2518 | if (q < 10) { | ||
2519 | ql_dbg(ql_dbg_tgt, vha, 0xe04f, | ||
2520 | "qla_target(%d): %d bytes of sense " | ||
2521 | "lost", prm->tgt->ha->vp_idx, | ||
2522 | prm->sense_buffer_len % 4); | ||
2523 | q++; | ||
2524 | } | ||
2525 | } | ||
2526 | #endif | ||
2527 | } else { | 2655 | } else { |
2528 | ctio->u.status1.flags &= | 2656 | ctio->u.status1.flags &= |
2529 | ~cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_0); | 2657 | ~cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_0); |
@@ -2537,19 +2665,9 @@ skip_explict_conf: | |||
2537 | /* Sense with len > 24, is it possible ??? */ | 2665 | /* Sense with len > 24, is it possible ??? */ |
2538 | } | 2666 | } |
2539 | 2667 | ||
2540 | |||
2541 | |||
2542 | /* diff */ | ||
2543 | static inline int | 2668 | static inline int |
2544 | qlt_hba_err_chk_enabled(struct se_cmd *se_cmd) | 2669 | qlt_hba_err_chk_enabled(struct se_cmd *se_cmd) |
2545 | { | 2670 | { |
2546 | /* | ||
2547 | * Uncomment when corresponding SCSI changes are done. | ||
2548 | * | ||
2549 | if (!sp->cmd->prot_chk) | ||
2550 | return 0; | ||
2551 | * | ||
2552 | */ | ||
2553 | switch (se_cmd->prot_op) { | 2671 | switch (se_cmd->prot_op) { |
2554 | case TARGET_PROT_DOUT_INSERT: | 2672 | case TARGET_PROT_DOUT_INSERT: |
2555 | case TARGET_PROT_DIN_STRIP: | 2673 | case TARGET_PROT_DIN_STRIP: |
@@ -2570,16 +2688,38 @@ qlt_hba_err_chk_enabled(struct se_cmd *se_cmd) | |||
2570 | return 0; | 2688 | return 0; |
2571 | } | 2689 | } |
2572 | 2690 | ||
2691 | static inline int | ||
2692 | qla_tgt_ref_mask_check(struct se_cmd *se_cmd) | ||
2693 | { | ||
2694 | switch (se_cmd->prot_op) { | ||
2695 | case TARGET_PROT_DIN_INSERT: | ||
2696 | case TARGET_PROT_DOUT_INSERT: | ||
2697 | case TARGET_PROT_DIN_STRIP: | ||
2698 | case TARGET_PROT_DOUT_STRIP: | ||
2699 | case TARGET_PROT_DIN_PASS: | ||
2700 | case TARGET_PROT_DOUT_PASS: | ||
2701 | return 1; | ||
2702 | default: | ||
2703 | return 0; | ||
2704 | } | ||
2705 | return 0; | ||
2706 | } | ||
2707 | |||
2573 | /* | 2708 | /* |
2574 | * qla24xx_set_t10dif_tags_from_cmd - Extract Ref and App tags from SCSI command | 2709 | * qla_tgt_set_dif_tags - Extract Ref and App tags from SCSI command |
2575 | * | ||
2576 | */ | 2710 | */ |
2577 | static inline void | 2711 | static void |
2578 | qlt_set_t10dif_tags(struct se_cmd *se_cmd, struct crc_context *ctx) | 2712 | qla_tgt_set_dif_tags(struct qla_tgt_cmd *cmd, struct crc_context *ctx, |
2713 | uint16_t *pfw_prot_opts) | ||
2579 | { | 2714 | { |
2715 | struct se_cmd *se_cmd = &cmd->se_cmd; | ||
2580 | uint32_t lba = 0xffffffff & se_cmd->t_task_lba; | 2716 | uint32_t lba = 0xffffffff & se_cmd->t_task_lba; |
2717 | scsi_qla_host_t *vha = cmd->tgt->vha; | ||
2718 | struct qla_hw_data *ha = vha->hw; | ||
2719 | uint32_t t32 = 0; | ||
2581 | 2720 | ||
2582 | /* wait til Mode Sense/Select cmd, modepage Ah, subpage 2 | 2721 | /* |
2722 | * wait till Mode Sense/Select cmd, modepage Ah, subpage 2 | ||
2583 | * have been immplemented by TCM, before AppTag is avail. | 2723 | * have been immplemented by TCM, before AppTag is avail. |
2584 | * Look for modesense_handlers[] | 2724 | * Look for modesense_handlers[] |
2585 | */ | 2725 | */ |
@@ -2587,65 +2727,73 @@ qlt_set_t10dif_tags(struct se_cmd *se_cmd, struct crc_context *ctx) | |||
2587 | ctx->app_tag_mask[0] = 0x0; | 2727 | ctx->app_tag_mask[0] = 0x0; |
2588 | ctx->app_tag_mask[1] = 0x0; | 2728 | ctx->app_tag_mask[1] = 0x0; |
2589 | 2729 | ||
2730 | if (IS_PI_UNINIT_CAPABLE(ha)) { | ||
2731 | if ((se_cmd->prot_type == TARGET_DIF_TYPE1_PROT) || | ||
2732 | (se_cmd->prot_type == TARGET_DIF_TYPE2_PROT)) | ||
2733 | *pfw_prot_opts |= PO_DIS_VALD_APP_ESC; | ||
2734 | else if (se_cmd->prot_type == TARGET_DIF_TYPE3_PROT) | ||
2735 | *pfw_prot_opts |= PO_DIS_VALD_APP_REF_ESC; | ||
2736 | } | ||
2737 | |||
2738 | t32 = ha->tgt.tgt_ops->get_dif_tags(cmd, pfw_prot_opts); | ||
2739 | |||
2590 | switch (se_cmd->prot_type) { | 2740 | switch (se_cmd->prot_type) { |
2591 | case TARGET_DIF_TYPE0_PROT: | 2741 | case TARGET_DIF_TYPE0_PROT: |
2592 | /* | 2742 | /* |
2593 | * No check for ql2xenablehba_err_chk, as it would be an | 2743 | * No check for ql2xenablehba_err_chk, as it |
2594 | * I/O error if hba tag generation is not done. | 2744 | * would be an I/O error if hba tag generation |
2745 | * is not done. | ||
2595 | */ | 2746 | */ |
2596 | ctx->ref_tag = cpu_to_le32(lba); | 2747 | ctx->ref_tag = cpu_to_le32(lba); |
2597 | |||
2598 | if (!qlt_hba_err_chk_enabled(se_cmd)) | ||
2599 | break; | ||
2600 | |||
2601 | /* enable ALL bytes of the ref tag */ | 2748 | /* enable ALL bytes of the ref tag */ |
2602 | ctx->ref_tag_mask[0] = 0xff; | 2749 | ctx->ref_tag_mask[0] = 0xff; |
2603 | ctx->ref_tag_mask[1] = 0xff; | 2750 | ctx->ref_tag_mask[1] = 0xff; |
2604 | ctx->ref_tag_mask[2] = 0xff; | 2751 | ctx->ref_tag_mask[2] = 0xff; |
2605 | ctx->ref_tag_mask[3] = 0xff; | 2752 | ctx->ref_tag_mask[3] = 0xff; |
2606 | break; | 2753 | break; |
2607 | /* | ||
2608 | * For TYpe 1 protection: 16 bit GUARD tag, 32 bit REF tag, and | ||
2609 | * 16 bit app tag. | ||
2610 | */ | ||
2611 | case TARGET_DIF_TYPE1_PROT: | 2754 | case TARGET_DIF_TYPE1_PROT: |
2612 | ctx->ref_tag = cpu_to_le32(lba); | 2755 | /* |
2613 | 2756 | * For TYPE 1 protection: 16 bit GUARD tag, 32 bit | |
2614 | if (!qlt_hba_err_chk_enabled(se_cmd)) | 2757 | * REF tag, and 16 bit app tag. |
2615 | break; | 2758 | */ |
2616 | 2759 | ctx->ref_tag = cpu_to_le32(lba); | |
2617 | /* enable ALL bytes of the ref tag */ | 2760 | if (!qla_tgt_ref_mask_check(se_cmd) || |
2618 | ctx->ref_tag_mask[0] = 0xff; | 2761 | !(ha->tgt.tgt_ops->chk_dif_tags(t32))) { |
2619 | ctx->ref_tag_mask[1] = 0xff; | 2762 | *pfw_prot_opts |= PO_DIS_REF_TAG_VALD; |
2620 | ctx->ref_tag_mask[2] = 0xff; | 2763 | break; |
2621 | ctx->ref_tag_mask[3] = 0xff; | 2764 | } |
2622 | break; | 2765 | /* enable ALL bytes of the ref tag */ |
2623 | /* | 2766 | ctx->ref_tag_mask[0] = 0xff; |
2624 | * For TYPE 2 protection: 16 bit GUARD + 32 bit REF tag has to | 2767 | ctx->ref_tag_mask[1] = 0xff; |
2625 | * match LBA in CDB + N | 2768 | ctx->ref_tag_mask[2] = 0xff; |
2626 | */ | 2769 | ctx->ref_tag_mask[3] = 0xff; |
2770 | break; | ||
2627 | case TARGET_DIF_TYPE2_PROT: | 2771 | case TARGET_DIF_TYPE2_PROT: |
2628 | ctx->ref_tag = cpu_to_le32(lba); | 2772 | /* |
2629 | 2773 | * For TYPE 2 protection: 16 bit GUARD + 32 bit REF | |
2630 | if (!qlt_hba_err_chk_enabled(se_cmd)) | 2774 | * tag has to match LBA in CDB + N |
2631 | break; | 2775 | */ |
2632 | 2776 | ctx->ref_tag = cpu_to_le32(lba); | |
2633 | /* enable ALL bytes of the ref tag */ | 2777 | if (!qla_tgt_ref_mask_check(se_cmd) || |
2634 | ctx->ref_tag_mask[0] = 0xff; | 2778 | !(ha->tgt.tgt_ops->chk_dif_tags(t32))) { |
2635 | ctx->ref_tag_mask[1] = 0xff; | 2779 | *pfw_prot_opts |= PO_DIS_REF_TAG_VALD; |
2636 | ctx->ref_tag_mask[2] = 0xff; | 2780 | break; |
2637 | ctx->ref_tag_mask[3] = 0xff; | 2781 | } |
2638 | break; | 2782 | /* enable ALL bytes of the ref tag */ |
2639 | 2783 | ctx->ref_tag_mask[0] = 0xff; | |
2640 | /* For Type 3 protection: 16 bit GUARD only */ | 2784 | ctx->ref_tag_mask[1] = 0xff; |
2785 | ctx->ref_tag_mask[2] = 0xff; | ||
2786 | ctx->ref_tag_mask[3] = 0xff; | ||
2787 | break; | ||
2641 | case TARGET_DIF_TYPE3_PROT: | 2788 | case TARGET_DIF_TYPE3_PROT: |
2642 | ctx->ref_tag_mask[0] = ctx->ref_tag_mask[1] = | 2789 | /* For TYPE 3 protection: 16 bit GUARD only */ |
2643 | ctx->ref_tag_mask[2] = ctx->ref_tag_mask[3] = 0x00; | 2790 | *pfw_prot_opts |= PO_DIS_REF_TAG_VALD; |
2644 | break; | 2791 | ctx->ref_tag_mask[0] = ctx->ref_tag_mask[1] = |
2792 | ctx->ref_tag_mask[2] = ctx->ref_tag_mask[3] = 0x00; | ||
2793 | break; | ||
2645 | } | 2794 | } |
2646 | } | 2795 | } |
2647 | 2796 | ||
2648 | |||
2649 | static inline int | 2797 | static inline int |
2650 | qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) | 2798 | qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) |
2651 | { | 2799 | { |
@@ -2664,6 +2812,7 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) | |||
2664 | struct se_cmd *se_cmd = &cmd->se_cmd; | 2812 | struct se_cmd *se_cmd = &cmd->se_cmd; |
2665 | uint32_t h; | 2813 | uint32_t h; |
2666 | struct atio_from_isp *atio = &prm->cmd->atio; | 2814 | struct atio_from_isp *atio = &prm->cmd->atio; |
2815 | struct qla_tc_param tc; | ||
2667 | uint16_t t16; | 2816 | uint16_t t16; |
2668 | 2817 | ||
2669 | ha = vha->hw; | 2818 | ha = vha->hw; |
@@ -2689,16 +2838,15 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) | |||
2689 | case TARGET_PROT_DIN_INSERT: | 2838 | case TARGET_PROT_DIN_INSERT: |
2690 | case TARGET_PROT_DOUT_STRIP: | 2839 | case TARGET_PROT_DOUT_STRIP: |
2691 | transfer_length = data_bytes; | 2840 | transfer_length = data_bytes; |
2692 | data_bytes += dif_bytes; | 2841 | if (cmd->prot_sg_cnt) |
2842 | data_bytes += dif_bytes; | ||
2693 | break; | 2843 | break; |
2694 | |||
2695 | case TARGET_PROT_DIN_STRIP: | 2844 | case TARGET_PROT_DIN_STRIP: |
2696 | case TARGET_PROT_DOUT_INSERT: | 2845 | case TARGET_PROT_DOUT_INSERT: |
2697 | case TARGET_PROT_DIN_PASS: | 2846 | case TARGET_PROT_DIN_PASS: |
2698 | case TARGET_PROT_DOUT_PASS: | 2847 | case TARGET_PROT_DOUT_PASS: |
2699 | transfer_length = data_bytes + dif_bytes; | 2848 | transfer_length = data_bytes + dif_bytes; |
2700 | break; | 2849 | break; |
2701 | |||
2702 | default: | 2850 | default: |
2703 | BUG(); | 2851 | BUG(); |
2704 | break; | 2852 | break; |
@@ -2734,7 +2882,6 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) | |||
2734 | break; | 2882 | break; |
2735 | } | 2883 | } |
2736 | 2884 | ||
2737 | |||
2738 | /* ---- PKT ---- */ | 2885 | /* ---- PKT ---- */ |
2739 | /* Update entry type to indicate Command Type CRC_2 IOCB */ | 2886 | /* Update entry type to indicate Command Type CRC_2 IOCB */ |
2740 | pkt->entry_type = CTIO_CRC2; | 2887 | pkt->entry_type = CTIO_CRC2; |
@@ -2752,9 +2899,8 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) | |||
2752 | } else | 2899 | } else |
2753 | ha->tgt.cmds[h-1] = prm->cmd; | 2900 | ha->tgt.cmds[h-1] = prm->cmd; |
2754 | 2901 | ||
2755 | |||
2756 | pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK; | 2902 | pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK; |
2757 | pkt->nport_handle = prm->cmd->loop_id; | 2903 | pkt->nport_handle = cpu_to_le16(prm->cmd->loop_id); |
2758 | pkt->timeout = cpu_to_le16(QLA_TGT_TIMEOUT); | 2904 | pkt->timeout = cpu_to_le16(QLA_TGT_TIMEOUT); |
2759 | pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; | 2905 | pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; |
2760 | pkt->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; | 2906 | pkt->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; |
@@ -2775,12 +2921,10 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) | |||
2775 | else if (cmd->dma_data_direction == DMA_FROM_DEVICE) | 2921 | else if (cmd->dma_data_direction == DMA_FROM_DEVICE) |
2776 | pkt->flags = cpu_to_le16(CTIO7_FLAGS_DATA_OUT); | 2922 | pkt->flags = cpu_to_le16(CTIO7_FLAGS_DATA_OUT); |
2777 | 2923 | ||
2778 | |||
2779 | pkt->dseg_count = prm->tot_dsds; | 2924 | pkt->dseg_count = prm->tot_dsds; |
2780 | /* Fibre channel byte count */ | 2925 | /* Fibre channel byte count */ |
2781 | pkt->transfer_length = cpu_to_le32(transfer_length); | 2926 | pkt->transfer_length = cpu_to_le32(transfer_length); |
2782 | 2927 | ||
2783 | |||
2784 | /* ----- CRC context -------- */ | 2928 | /* ----- CRC context -------- */ |
2785 | 2929 | ||
2786 | /* Allocate CRC context from global pool */ | 2930 | /* Allocate CRC context from global pool */ |
@@ -2800,13 +2944,12 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) | |||
2800 | /* Set handle */ | 2944 | /* Set handle */ |
2801 | crc_ctx_pkt->handle = pkt->handle; | 2945 | crc_ctx_pkt->handle = pkt->handle; |
2802 | 2946 | ||
2803 | qlt_set_t10dif_tags(se_cmd, crc_ctx_pkt); | 2947 | qla_tgt_set_dif_tags(cmd, crc_ctx_pkt, &fw_prot_opts); |
2804 | 2948 | ||
2805 | pkt->crc_context_address[0] = cpu_to_le32(LSD(crc_ctx_dma)); | 2949 | pkt->crc_context_address[0] = cpu_to_le32(LSD(crc_ctx_dma)); |
2806 | pkt->crc_context_address[1] = cpu_to_le32(MSD(crc_ctx_dma)); | 2950 | pkt->crc_context_address[1] = cpu_to_le32(MSD(crc_ctx_dma)); |
2807 | pkt->crc_context_len = CRC_CONTEXT_LEN_FW; | 2951 | pkt->crc_context_len = CRC_CONTEXT_LEN_FW; |
2808 | 2952 | ||
2809 | |||
2810 | if (!bundling) { | 2953 | if (!bundling) { |
2811 | cur_dsd = (uint32_t *) &crc_ctx_pkt->u.nobundling.data_address; | 2954 | cur_dsd = (uint32_t *) &crc_ctx_pkt->u.nobundling.data_address; |
2812 | } else { | 2955 | } else { |
@@ -2827,16 +2970,24 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) | |||
2827 | crc_ctx_pkt->byte_count = cpu_to_le32(data_bytes); | 2970 | crc_ctx_pkt->byte_count = cpu_to_le32(data_bytes); |
2828 | crc_ctx_pkt->guard_seed = cpu_to_le16(0); | 2971 | crc_ctx_pkt->guard_seed = cpu_to_le16(0); |
2829 | 2972 | ||
2973 | memset((uint8_t *)&tc, 0 , sizeof(tc)); | ||
2974 | tc.vha = vha; | ||
2975 | tc.blk_sz = cmd->blk_sz; | ||
2976 | tc.bufflen = cmd->bufflen; | ||
2977 | tc.sg = cmd->sg; | ||
2978 | tc.prot_sg = cmd->prot_sg; | ||
2979 | tc.ctx = crc_ctx_pkt; | ||
2980 | tc.ctx_dsd_alloced = &cmd->ctx_dsd_alloced; | ||
2830 | 2981 | ||
2831 | /* Walks data segments */ | 2982 | /* Walks data segments */ |
2832 | pkt->flags |= cpu_to_le16(CTIO7_FLAGS_DSD_PTR); | 2983 | pkt->flags |= cpu_to_le16(CTIO7_FLAGS_DSD_PTR); |
2833 | 2984 | ||
2834 | if (!bundling && prm->prot_seg_cnt) { | 2985 | if (!bundling && prm->prot_seg_cnt) { |
2835 | if (qla24xx_walk_and_build_sglist_no_difb(ha, NULL, cur_dsd, | 2986 | if (qla24xx_walk_and_build_sglist_no_difb(ha, NULL, cur_dsd, |
2836 | prm->tot_dsds, cmd)) | 2987 | prm->tot_dsds, &tc)) |
2837 | goto crc_queuing_error; | 2988 | goto crc_queuing_error; |
2838 | } else if (qla24xx_walk_and_build_sglist(ha, NULL, cur_dsd, | 2989 | } else if (qla24xx_walk_and_build_sglist(ha, NULL, cur_dsd, |
2839 | (prm->tot_dsds - prm->prot_seg_cnt), cmd)) | 2990 | (prm->tot_dsds - prm->prot_seg_cnt), &tc)) |
2840 | goto crc_queuing_error; | 2991 | goto crc_queuing_error; |
2841 | 2992 | ||
2842 | if (bundling && prm->prot_seg_cnt) { | 2993 | if (bundling && prm->prot_seg_cnt) { |
@@ -2845,18 +2996,18 @@ qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) | |||
2845 | 2996 | ||
2846 | cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address; | 2997 | cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address; |
2847 | if (qla24xx_walk_and_build_prot_sglist(ha, NULL, cur_dsd, | 2998 | if (qla24xx_walk_and_build_prot_sglist(ha, NULL, cur_dsd, |
2848 | prm->prot_seg_cnt, cmd)) | 2999 | prm->prot_seg_cnt, &tc)) |
2849 | goto crc_queuing_error; | 3000 | goto crc_queuing_error; |
2850 | } | 3001 | } |
2851 | return QLA_SUCCESS; | 3002 | return QLA_SUCCESS; |
2852 | 3003 | ||
2853 | crc_queuing_error: | 3004 | crc_queuing_error: |
2854 | /* Cleanup will be performed by the caller */ | 3005 | /* Cleanup will be performed by the caller */ |
3006 | vha->hw->tgt.cmds[h - 1] = NULL; | ||
2855 | 3007 | ||
2856 | return QLA_FUNCTION_FAILED; | 3008 | return QLA_FUNCTION_FAILED; |
2857 | } | 3009 | } |
2858 | 3010 | ||
2859 | |||
2860 | /* | 3011 | /* |
2861 | * Callback to setup response of xmit_type of QLA_TGT_XMIT_DATA and * | 3012 | * Callback to setup response of xmit_type of QLA_TGT_XMIT_DATA and * |
2862 | * QLA_TGT_XMIT_STATUS for >= 24xx silicon | 3013 | * QLA_TGT_XMIT_STATUS for >= 24xx silicon |
@@ -2906,7 +3057,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, | |||
2906 | else | 3057 | else |
2907 | vha->tgt_counters.core_qla_que_buf++; | 3058 | vha->tgt_counters.core_qla_que_buf++; |
2908 | 3059 | ||
2909 | if (!vha->flags.online || cmd->reset_count != ha->chip_reset) { | 3060 | if (!ha->flags.fw_started || cmd->reset_count != ha->chip_reset) { |
2910 | /* | 3061 | /* |
2911 | * Either the port is not online or this request was from | 3062 | * Either the port is not online or this request was from |
2912 | * previous life, just abort the processing. | 3063 | * previous life, just abort the processing. |
@@ -3047,7 +3198,7 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd) | |||
3047 | 3198 | ||
3048 | spin_lock_irqsave(&ha->hardware_lock, flags); | 3199 | spin_lock_irqsave(&ha->hardware_lock, flags); |
3049 | 3200 | ||
3050 | if (!vha->flags.online || (cmd->reset_count != ha->chip_reset) || | 3201 | if (!ha->flags.fw_started || (cmd->reset_count != ha->chip_reset) || |
3051 | (cmd->sess && cmd->sess->deleted)) { | 3202 | (cmd->sess && cmd->sess->deleted)) { |
3052 | /* | 3203 | /* |
3053 | * Either the port is not online or this request was from | 3204 | * Either the port is not online or this request was from |
@@ -3104,139 +3255,113 @@ EXPORT_SYMBOL(qlt_rdy_to_xfer); | |||
3104 | 3255 | ||
3105 | 3256 | ||
3106 | /* | 3257 | /* |
3107 | * Checks the guard or meta-data for the type of error | 3258 | * it is assumed either hardware_lock or qpair lock is held. |
3108 | * detected by the HBA. | ||
3109 | */ | 3259 | */ |
3110 | static inline int | 3260 | static void |
3111 | qlt_handle_dif_error(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd, | 3261 | qlt_handle_dif_error(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd, |
3112 | struct ctio_crc_from_fw *sts) | 3262 | struct ctio_crc_from_fw *sts) |
3113 | { | 3263 | { |
3114 | uint8_t *ap = &sts->actual_dif[0]; | 3264 | uint8_t *ap = &sts->actual_dif[0]; |
3115 | uint8_t *ep = &sts->expected_dif[0]; | 3265 | uint8_t *ep = &sts->expected_dif[0]; |
3116 | uint32_t e_ref_tag, a_ref_tag; | ||
3117 | uint16_t e_app_tag, a_app_tag; | ||
3118 | uint16_t e_guard, a_guard; | ||
3119 | uint64_t lba = cmd->se_cmd.t_task_lba; | 3266 | uint64_t lba = cmd->se_cmd.t_task_lba; |
3267 | uint8_t scsi_status, sense_key, asc, ascq; | ||
3268 | unsigned long flags; | ||
3120 | 3269 | ||
3121 | a_guard = be16_to_cpu(*(uint16_t *)(ap + 0)); | 3270 | cmd->trc_flags |= TRC_DIF_ERR; |
3122 | a_app_tag = be16_to_cpu(*(uint16_t *)(ap + 2)); | ||
3123 | a_ref_tag = be32_to_cpu(*(uint32_t *)(ap + 4)); | ||
3124 | |||
3125 | e_guard = be16_to_cpu(*(uint16_t *)(ep + 0)); | ||
3126 | e_app_tag = be16_to_cpu(*(uint16_t *)(ep + 2)); | ||
3127 | e_ref_tag = be32_to_cpu(*(uint32_t *)(ep + 4)); | ||
3128 | |||
3129 | ql_dbg(ql_dbg_tgt, vha, 0xe075, | ||
3130 | "iocb(s) %p Returned STATUS.\n", sts); | ||
3131 | |||
3132 | ql_dbg(ql_dbg_tgt, vha, 0xf075, | ||
3133 | "dif check TGT cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x]\n", | ||
3134 | cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba, | ||
3135 | a_ref_tag, e_ref_tag, a_app_tag, e_app_tag, a_guard, e_guard); | ||
3136 | |||
3137 | /* | ||
3138 | * Ignore sector if: | ||
3139 | * For type 3: ref & app tag is all 'f's | ||
3140 | * For type 0,1,2: app tag is all 'f's | ||
3141 | */ | ||
3142 | if ((a_app_tag == 0xffff) && | ||
3143 | ((cmd->se_cmd.prot_type != TARGET_DIF_TYPE3_PROT) || | ||
3144 | (a_ref_tag == 0xffffffff))) { | ||
3145 | uint32_t blocks_done; | ||
3146 | |||
3147 | /* 2TB boundary case covered automatically with this */ | ||
3148 | blocks_done = e_ref_tag - (uint32_t)lba + 1; | ||
3149 | cmd->se_cmd.bad_sector = e_ref_tag; | ||
3150 | cmd->se_cmd.pi_err = 0; | ||
3151 | ql_dbg(ql_dbg_tgt, vha, 0xf074, | ||
3152 | "need to return scsi good\n"); | ||
3153 | |||
3154 | /* Update protection tag */ | ||
3155 | if (cmd->prot_sg_cnt) { | ||
3156 | uint32_t i, k = 0, num_ent; | ||
3157 | struct scatterlist *sg, *sgl; | ||
3158 | |||
3159 | |||
3160 | sgl = cmd->prot_sg; | ||
3161 | |||
3162 | /* Patch the corresponding protection tags */ | ||
3163 | for_each_sg(sgl, sg, cmd->prot_sg_cnt, i) { | ||
3164 | num_ent = sg_dma_len(sg) / 8; | ||
3165 | if (k + num_ent < blocks_done) { | ||
3166 | k += num_ent; | ||
3167 | continue; | ||
3168 | } | ||
3169 | k = blocks_done; | ||
3170 | break; | ||
3171 | } | ||
3172 | 3271 | ||
3173 | if (k != blocks_done) { | 3272 | cmd->a_guard = be16_to_cpu(*(uint16_t *)(ap + 0)); |
3174 | ql_log(ql_log_warn, vha, 0xf076, | 3273 | cmd->a_app_tag = be16_to_cpu(*(uint16_t *)(ap + 2)); |
3175 | "unexpected tag values tag:lba=%u:%llu)\n", | 3274 | cmd->a_ref_tag = be32_to_cpu(*(uint32_t *)(ap + 4)); |
3176 | e_ref_tag, (unsigned long long)lba); | ||
3177 | goto out; | ||
3178 | } | ||
3179 | 3275 | ||
3180 | #if 0 | 3276 | cmd->e_guard = be16_to_cpu(*(uint16_t *)(ep + 0)); |
3181 | struct sd_dif_tuple *spt; | 3277 | cmd->e_app_tag = be16_to_cpu(*(uint16_t *)(ep + 2)); |
3182 | /* TODO: | 3278 | cmd->e_ref_tag = be32_to_cpu(*(uint32_t *)(ep + 4)); |
3183 | * This section came from initiator. Is it valid here? | ||
3184 | * should ulp be override with actual val??? | ||
3185 | */ | ||
3186 | spt = page_address(sg_page(sg)) + sg->offset; | ||
3187 | spt += j; | ||
3188 | 3279 | ||
3189 | spt->app_tag = 0xffff; | 3280 | ql_dbg(ql_dbg_tgt_dif, vha, 0xf075, |
3190 | if (cmd->se_cmd.prot_type == SCSI_PROT_DIF_TYPE3) | 3281 | "%s: aborted %d state %d\n", __func__, cmd->aborted, cmd->state); |
3191 | spt->ref_tag = 0xffffffff; | ||
3192 | #endif | ||
3193 | } | ||
3194 | 3282 | ||
3195 | return 0; | 3283 | scsi_status = sense_key = asc = ascq = 0; |
3196 | } | ||
3197 | 3284 | ||
3198 | /* check guard */ | 3285 | /* check appl tag */ |
3199 | if (e_guard != a_guard) { | 3286 | if (cmd->e_app_tag != cmd->a_app_tag) { |
3200 | cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED; | 3287 | ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, |
3201 | cmd->se_cmd.bad_sector = cmd->se_cmd.t_task_lba; | 3288 | "App Tag ERR: cdb[%x] lba[%llx %llx] blks[%x] [Actual|Expected] " |
3202 | 3289 | "Ref[%x|%x], App[%x|%x], " | |
3203 | ql_log(ql_log_warn, vha, 0xe076, | 3290 | "Guard [%x|%x] cmd=%p ox_id[%04x]", |
3204 | "Guard ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n", | 3291 | cmd->cdb[0], lba, (lba+cmd->num_blks), cmd->num_blks, |
3205 | cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba, | 3292 | cmd->a_ref_tag, cmd->e_ref_tag, |
3206 | a_ref_tag, e_ref_tag, a_app_tag, e_app_tag, | 3293 | cmd->a_app_tag, cmd->e_app_tag, |
3207 | a_guard, e_guard, cmd); | 3294 | cmd->a_guard, cmd->e_guard, |
3208 | goto out; | 3295 | cmd, cmd->atio.u.isp24.fcp_hdr.ox_id); |
3296 | |||
3297 | cmd->dif_err_code = DIF_ERR_APP; | ||
3298 | scsi_status = SAM_STAT_CHECK_CONDITION; | ||
3299 | sense_key = ABORTED_COMMAND; | ||
3300 | asc = 0x10; | ||
3301 | ascq = 0x2; | ||
3209 | } | 3302 | } |
3210 | 3303 | ||
3211 | /* check ref tag */ | 3304 | /* check ref tag */ |
3212 | if (e_ref_tag != a_ref_tag) { | 3305 | if (cmd->e_ref_tag != cmd->a_ref_tag) { |
3213 | cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED; | 3306 | ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, |
3214 | cmd->se_cmd.bad_sector = e_ref_tag; | 3307 | "Ref Tag ERR: cdb[%x] lba[%llx %llx] blks[%x] [Actual|Expected] " |
3215 | 3308 | "Ref[%x|%x], App[%x|%x], " | |
3216 | ql_log(ql_log_warn, vha, 0xe077, | 3309 | "Guard[%x|%x] cmd=%p ox_id[%04x] ", |
3217 | "Ref Tag ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n", | 3310 | cmd->cdb[0], lba, (lba+cmd->num_blks), cmd->num_blks, |
3218 | cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba, | 3311 | cmd->a_ref_tag, cmd->e_ref_tag, |
3219 | a_ref_tag, e_ref_tag, a_app_tag, e_app_tag, | 3312 | cmd->a_app_tag, cmd->e_app_tag, |
3220 | a_guard, e_guard, cmd); | 3313 | cmd->a_guard, cmd->e_guard, |
3314 | cmd, cmd->atio.u.isp24.fcp_hdr.ox_id); | ||
3315 | |||
3316 | cmd->dif_err_code = DIF_ERR_REF; | ||
3317 | scsi_status = SAM_STAT_CHECK_CONDITION; | ||
3318 | sense_key = ABORTED_COMMAND; | ||
3319 | asc = 0x10; | ||
3320 | ascq = 0x3; | ||
3221 | goto out; | 3321 | goto out; |
3222 | } | 3322 | } |
3223 | 3323 | ||
3224 | /* check appl tag */ | 3324 | /* check guard */ |
3225 | if (e_app_tag != a_app_tag) { | 3325 | if (cmd->e_guard != cmd->a_guard) { |
3226 | cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED; | 3326 | ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, |
3227 | cmd->se_cmd.bad_sector = cmd->se_cmd.t_task_lba; | 3327 | "Guard ERR: cdb[%x] lba[%llx %llx] blks[%x] [Actual|Expected] " |
3228 | 3328 | "Ref[%x|%x], App[%x|%x], " | |
3229 | ql_log(ql_log_warn, vha, 0xe078, | 3329 | "Guard [%x|%x] cmd=%p ox_id[%04x]", |
3230 | "App Tag ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n", | 3330 | cmd->cdb[0], lba, (lba+cmd->num_blks), cmd->num_blks, |
3231 | cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba, | 3331 | cmd->a_ref_tag, cmd->e_ref_tag, |
3232 | a_ref_tag, e_ref_tag, a_app_tag, e_app_tag, | 3332 | cmd->a_app_tag, cmd->e_app_tag, |
3233 | a_guard, e_guard, cmd); | 3333 | cmd->a_guard, cmd->e_guard, |
3234 | goto out; | 3334 | cmd, cmd->atio.u.isp24.fcp_hdr.ox_id); |
3335 | cmd->dif_err_code = DIF_ERR_GRD; | ||
3336 | scsi_status = SAM_STAT_CHECK_CONDITION; | ||
3337 | sense_key = ABORTED_COMMAND; | ||
3338 | asc = 0x10; | ||
3339 | ascq = 0x1; | ||
3235 | } | 3340 | } |
3236 | out: | 3341 | out: |
3237 | return 1; | 3342 | switch (cmd->state) { |
3238 | } | 3343 | case QLA_TGT_STATE_NEED_DATA: |
3344 | /* handle_data will load DIF error code */ | ||
3345 | cmd->state = QLA_TGT_STATE_DATA_IN; | ||
3346 | vha->hw->tgt.tgt_ops->handle_data(cmd); | ||
3347 | break; | ||
3348 | default: | ||
3349 | spin_lock_irqsave(&cmd->cmd_lock, flags); | ||
3350 | if (cmd->aborted) { | ||
3351 | spin_unlock_irqrestore(&cmd->cmd_lock, flags); | ||
3352 | vha->hw->tgt.tgt_ops->free_cmd(cmd); | ||
3353 | break; | ||
3354 | } | ||
3355 | spin_unlock_irqrestore(&cmd->cmd_lock, flags); | ||
3239 | 3356 | ||
3357 | qlt_send_resp_ctio(vha, cmd, scsi_status, sense_key, asc, ascq); | ||
3358 | /* assume scsi status gets out on the wire. | ||
3359 | * Will not wait for completion. | ||
3360 | */ | ||
3361 | vha->hw->tgt.tgt_ops->free_cmd(cmd); | ||
3362 | break; | ||
3363 | } | ||
3364 | } | ||
3240 | 3365 | ||
3241 | /* If hardware_lock held on entry, might drop it, then reaquire */ | 3366 | /* If hardware_lock held on entry, might drop it, then reaquire */ |
3242 | /* This function sends the appropriate CTIO to ISP 2xxx or 24xx */ | 3367 | /* This function sends the appropriate CTIO to ISP 2xxx or 24xx */ |
@@ -3251,7 +3376,7 @@ static int __qlt_send_term_imm_notif(struct scsi_qla_host *vha, | |||
3251 | ql_dbg(ql_dbg_tgt_tmr, vha, 0xe01c, | 3376 | ql_dbg(ql_dbg_tgt_tmr, vha, 0xe01c, |
3252 | "Sending TERM ELS CTIO (ha=%p)\n", ha); | 3377 | "Sending TERM ELS CTIO (ha=%p)\n", ha); |
3253 | 3378 | ||
3254 | pkt = (request_t *)qla2x00_alloc_iocbs_ready(vha, NULL); | 3379 | pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL); |
3255 | if (pkt == NULL) { | 3380 | if (pkt == NULL) { |
3256 | ql_dbg(ql_dbg_tgt, vha, 0xe080, | 3381 | ql_dbg(ql_dbg_tgt, vha, 0xe080, |
3257 | "qla_target(%d): %s failed: unable to allocate " | 3382 | "qla_target(%d): %s failed: unable to allocate " |
@@ -3543,6 +3668,16 @@ static int qlt_term_ctio_exchange(struct scsi_qla_host *vha, void *ctio, | |||
3543 | { | 3668 | { |
3544 | int term = 0; | 3669 | int term = 0; |
3545 | 3670 | ||
3671 | if (cmd->se_cmd.prot_op) | ||
3672 | ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, | ||
3673 | "Term DIF cmd: lba[0x%llx|%lld] len[0x%x] " | ||
3674 | "se_cmd=%p tag[%x] op %#x/%s", | ||
3675 | cmd->lba, cmd->lba, | ||
3676 | cmd->num_blks, &cmd->se_cmd, | ||
3677 | cmd->atio.u.isp24.exchange_addr, | ||
3678 | cmd->se_cmd.prot_op, | ||
3679 | prot_op_str(cmd->se_cmd.prot_op)); | ||
3680 | |||
3546 | if (ctio != NULL) { | 3681 | if (ctio != NULL) { |
3547 | struct ctio7_from_24xx *c = (struct ctio7_from_24xx *)ctio; | 3682 | struct ctio7_from_24xx *c = (struct ctio7_from_24xx *)ctio; |
3548 | term = !(c->flags & | 3683 | term = !(c->flags & |
@@ -3760,32 +3895,15 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, | |||
3760 | struct ctio_crc_from_fw *crc = | 3895 | struct ctio_crc_from_fw *crc = |
3761 | (struct ctio_crc_from_fw *)ctio; | 3896 | (struct ctio_crc_from_fw *)ctio; |
3762 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf073, | 3897 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf073, |
3763 | "qla_target(%d): CTIO with DIF_ERROR status %x received (state %x, se_cmd %p) actual_dif[0x%llx] expect_dif[0x%llx]\n", | 3898 | "qla_target(%d): CTIO with DIF_ERROR status %x " |
3899 | "received (state %x, ulp_cmd %p) actual_dif[0x%llx] " | ||
3900 | "expect_dif[0x%llx]\n", | ||
3764 | vha->vp_idx, status, cmd->state, se_cmd, | 3901 | vha->vp_idx, status, cmd->state, se_cmd, |
3765 | *((u64 *)&crc->actual_dif[0]), | 3902 | *((u64 *)&crc->actual_dif[0]), |
3766 | *((u64 *)&crc->expected_dif[0])); | 3903 | *((u64 *)&crc->expected_dif[0])); |
3767 | 3904 | ||
3768 | if (qlt_handle_dif_error(vha, cmd, ctio)) { | 3905 | qlt_handle_dif_error(vha, cmd, ctio); |
3769 | if (cmd->state == QLA_TGT_STATE_NEED_DATA) { | 3906 | return; |
3770 | /* scsi Write/xfer rdy complete */ | ||
3771 | goto skip_term; | ||
3772 | } else { | ||
3773 | /* scsi read/xmit respond complete | ||
3774 | * call handle dif to send scsi status | ||
3775 | * rather than terminate exchange. | ||
3776 | */ | ||
3777 | cmd->state = QLA_TGT_STATE_PROCESSED; | ||
3778 | ha->tgt.tgt_ops->handle_dif_err(cmd); | ||
3779 | return; | ||
3780 | } | ||
3781 | } else { | ||
3782 | /* Need to generate a SCSI good completion. | ||
3783 | * because FW did not send scsi status. | ||
3784 | */ | ||
3785 | status = 0; | ||
3786 | goto skip_term; | ||
3787 | } | ||
3788 | break; | ||
3789 | } | 3907 | } |
3790 | default: | 3908 | default: |
3791 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b, | 3909 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b, |
@@ -3808,7 +3926,6 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, | |||
3808 | return; | 3926 | return; |
3809 | } | 3927 | } |
3810 | } | 3928 | } |
3811 | skip_term: | ||
3812 | 3929 | ||
3813 | if (cmd->state == QLA_TGT_STATE_PROCESSED) { | 3930 | if (cmd->state == QLA_TGT_STATE_PROCESSED) { |
3814 | cmd->trc_flags |= TRC_CTIO_DONE; | 3931 | cmd->trc_flags |= TRC_CTIO_DONE; |
@@ -4584,7 +4701,8 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, | |||
4584 | } | 4701 | } |
4585 | 4702 | ||
4586 | if (sess != NULL) { | 4703 | if (sess != NULL) { |
4587 | if (sess->fw_login_state == DSC_LS_PLOGI_PEND) { | 4704 | if (sess->fw_login_state != DSC_LS_PLOGI_PEND && |
4705 | sess->fw_login_state != DSC_LS_PLOGI_COMP) { | ||
4588 | /* | 4706 | /* |
4589 | * Impatient initiator sent PRLI before last | 4707 | * Impatient initiator sent PRLI before last |
4590 | * PLOGI could finish. Will force him to re-try, | 4708 | * PLOGI could finish. Will force him to re-try, |
@@ -4623,15 +4741,23 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, | |||
4623 | 4741 | ||
4624 | /* Make session global (not used in fabric mode) */ | 4742 | /* Make session global (not used in fabric mode) */ |
4625 | if (ha->current_topology != ISP_CFG_F) { | 4743 | if (ha->current_topology != ISP_CFG_F) { |
4626 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); | 4744 | if (sess) { |
4627 | set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); | 4745 | ql_dbg(ql_dbg_disc, vha, 0xffff, |
4628 | qla2xxx_wake_dpc(vha); | 4746 | "%s %d %8phC post nack\n", |
4747 | __func__, __LINE__, sess->port_name); | ||
4748 | qla24xx_post_nack_work(vha, sess, iocb, | ||
4749 | SRB_NACK_PRLI); | ||
4750 | res = 0; | ||
4751 | } else { | ||
4752 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); | ||
4753 | set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); | ||
4754 | qla2xxx_wake_dpc(vha); | ||
4755 | } | ||
4629 | } else { | 4756 | } else { |
4630 | if (sess) { | 4757 | if (sess) { |
4631 | ql_dbg(ql_dbg_disc, vha, 0xffff, | 4758 | ql_dbg(ql_dbg_disc, vha, 0xffff, |
4632 | "%s %d %8phC post nack\n", | 4759 | "%s %d %8phC post nack\n", |
4633 | __func__, __LINE__, sess->port_name); | 4760 | __func__, __LINE__, sess->port_name); |
4634 | |||
4635 | qla24xx_post_nack_work(vha, sess, iocb, | 4761 | qla24xx_post_nack_work(vha, sess, iocb, |
4636 | SRB_NACK_PRLI); | 4762 | SRB_NACK_PRLI); |
4637 | res = 0; | 4763 | res = 0; |
@@ -4639,7 +4765,6 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, | |||
4639 | } | 4765 | } |
4640 | break; | 4766 | break; |
4641 | 4767 | ||
4642 | |||
4643 | case ELS_TPRLO: | 4768 | case ELS_TPRLO: |
4644 | if (le16_to_cpu(iocb->u.isp24.flags) & | 4769 | if (le16_to_cpu(iocb->u.isp24.flags) & |
4645 | NOTIFY24XX_FLAGS_GLOBAL_TPRLO) { | 4770 | NOTIFY24XX_FLAGS_GLOBAL_TPRLO) { |
@@ -5079,16 +5204,22 @@ qlt_send_busy(struct scsi_qla_host *vha, | |||
5079 | 5204 | ||
5080 | static int | 5205 | static int |
5081 | qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, | 5206 | qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, |
5082 | struct atio_from_isp *atio) | 5207 | struct atio_from_isp *atio, bool ha_locked) |
5083 | { | 5208 | { |
5084 | struct qla_hw_data *ha = vha->hw; | 5209 | struct qla_hw_data *ha = vha->hw; |
5085 | uint16_t status; | 5210 | uint16_t status; |
5211 | unsigned long flags; | ||
5086 | 5212 | ||
5087 | if (ha->tgt.num_pend_cmds < Q_FULL_THRESH_HOLD(ha)) | 5213 | if (ha->tgt.num_pend_cmds < Q_FULL_THRESH_HOLD(ha)) |
5088 | return 0; | 5214 | return 0; |
5089 | 5215 | ||
5216 | if (!ha_locked) | ||
5217 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
5090 | status = temp_sam_status; | 5218 | status = temp_sam_status; |
5091 | qlt_send_busy(vha, atio, status); | 5219 | qlt_send_busy(vha, atio, status); |
5220 | if (!ha_locked) | ||
5221 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
5222 | |||
5092 | return 1; | 5223 | return 1; |
5093 | } | 5224 | } |
5094 | 5225 | ||
@@ -5103,7 +5234,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, | |||
5103 | unsigned long flags; | 5234 | unsigned long flags; |
5104 | 5235 | ||
5105 | if (unlikely(tgt == NULL)) { | 5236 | if (unlikely(tgt == NULL)) { |
5106 | ql_dbg(ql_dbg_io, vha, 0x3064, | 5237 | ql_dbg(ql_dbg_tgt, vha, 0x3064, |
5107 | "ATIO pkt, but no tgt (ha %p)", ha); | 5238 | "ATIO pkt, but no tgt (ha %p)", ha); |
5108 | return; | 5239 | return; |
5109 | } | 5240 | } |
@@ -5133,7 +5264,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, | |||
5133 | 5264 | ||
5134 | 5265 | ||
5135 | if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) { | 5266 | if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) { |
5136 | rc = qlt_chk_qfull_thresh_hold(vha, atio); | 5267 | rc = qlt_chk_qfull_thresh_hold(vha, atio, ha_locked); |
5137 | if (rc != 0) { | 5268 | if (rc != 0) { |
5138 | tgt->atio_irq_cmd_count--; | 5269 | tgt->atio_irq_cmd_count--; |
5139 | return; | 5270 | return; |
@@ -5256,7 +5387,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt) | |||
5256 | break; | 5387 | break; |
5257 | } | 5388 | } |
5258 | 5389 | ||
5259 | rc = qlt_chk_qfull_thresh_hold(vha, atio); | 5390 | rc = qlt_chk_qfull_thresh_hold(vha, atio, true); |
5260 | if (rc != 0) { | 5391 | if (rc != 0) { |
5261 | tgt->irq_cmd_count--; | 5392 | tgt->irq_cmd_count--; |
5262 | return; | 5393 | return; |
@@ -5531,7 +5662,7 @@ static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha, | |||
5531 | 5662 | ||
5532 | fcport->loop_id = loop_id; | 5663 | fcport->loop_id = loop_id; |
5533 | 5664 | ||
5534 | rc = qla2x00_get_port_database(vha, fcport, 0); | 5665 | rc = qla24xx_gpdb_wait(vha, fcport, 0); |
5535 | if (rc != QLA_SUCCESS) { | 5666 | if (rc != QLA_SUCCESS) { |
5536 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf070, | 5667 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf070, |
5537 | "qla_target(%d): Failed to retrieve fcport " | 5668 | "qla_target(%d): Failed to retrieve fcport " |
@@ -5713,30 +5844,23 @@ static void qlt_abort_work(struct qla_tgt *tgt, | |||
5713 | } | 5844 | } |
5714 | } | 5845 | } |
5715 | 5846 | ||
5716 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
5717 | |||
5718 | if (tgt->tgt_stop) | ||
5719 | goto out_term; | ||
5720 | |||
5721 | rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess); | 5847 | rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess); |
5848 | ha->tgt.tgt_ops->put_sess(sess); | ||
5849 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2); | ||
5850 | |||
5722 | if (rc != 0) | 5851 | if (rc != 0) |
5723 | goto out_term; | 5852 | goto out_term; |
5724 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
5725 | if (sess) | ||
5726 | ha->tgt.tgt_ops->put_sess(sess); | ||
5727 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2); | ||
5728 | return; | 5853 | return; |
5729 | 5854 | ||
5730 | out_term2: | 5855 | out_term2: |
5731 | spin_lock_irqsave(&ha->hardware_lock, flags); | 5856 | if (sess) |
5857 | ha->tgt.tgt_ops->put_sess(sess); | ||
5858 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2); | ||
5732 | 5859 | ||
5733 | out_term: | 5860 | out_term: |
5861 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
5734 | qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false); | 5862 | qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false); |
5735 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 5863 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
5736 | |||
5737 | if (sess) | ||
5738 | ha->tgt.tgt_ops->put_sess(sess); | ||
5739 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2); | ||
5740 | } | 5864 | } |
5741 | 5865 | ||
5742 | static void qlt_tmr_work(struct qla_tgt *tgt, | 5866 | static void qlt_tmr_work(struct qla_tgt *tgt, |
@@ -5756,7 +5880,7 @@ static void qlt_tmr_work(struct qla_tgt *tgt, | |||
5756 | spin_lock_irqsave(&ha->tgt.sess_lock, flags); | 5880 | spin_lock_irqsave(&ha->tgt.sess_lock, flags); |
5757 | 5881 | ||
5758 | if (tgt->tgt_stop) | 5882 | if (tgt->tgt_stop) |
5759 | goto out_term; | 5883 | goto out_term2; |
5760 | 5884 | ||
5761 | s_id = prm->tm_iocb2.u.isp24.fcp_hdr.s_id; | 5885 | s_id = prm->tm_iocb2.u.isp24.fcp_hdr.s_id; |
5762 | sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); | 5886 | sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); |
@@ -5768,11 +5892,11 @@ static void qlt_tmr_work(struct qla_tgt *tgt, | |||
5768 | 5892 | ||
5769 | spin_lock_irqsave(&ha->tgt.sess_lock, flags); | 5893 | spin_lock_irqsave(&ha->tgt.sess_lock, flags); |
5770 | if (!sess) | 5894 | if (!sess) |
5771 | goto out_term; | 5895 | goto out_term2; |
5772 | } else { | 5896 | } else { |
5773 | if (sess->deleted) { | 5897 | if (sess->deleted) { |
5774 | sess = NULL; | 5898 | sess = NULL; |
5775 | goto out_term; | 5899 | goto out_term2; |
5776 | } | 5900 | } |
5777 | 5901 | ||
5778 | if (!kref_get_unless_zero(&sess->sess_kref)) { | 5902 | if (!kref_get_unless_zero(&sess->sess_kref)) { |
@@ -5780,7 +5904,7 @@ static void qlt_tmr_work(struct qla_tgt *tgt, | |||
5780 | "%s: kref_get fail %8phC\n", | 5904 | "%s: kref_get fail %8phC\n", |
5781 | __func__, sess->port_name); | 5905 | __func__, sess->port_name); |
5782 | sess = NULL; | 5906 | sess = NULL; |
5783 | goto out_term; | 5907 | goto out_term2; |
5784 | } | 5908 | } |
5785 | } | 5909 | } |
5786 | 5910 | ||
@@ -5790,17 +5914,19 @@ static void qlt_tmr_work(struct qla_tgt *tgt, | |||
5790 | unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun); | 5914 | unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun); |
5791 | 5915 | ||
5792 | rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); | 5916 | rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); |
5793 | if (rc != 0) | ||
5794 | goto out_term; | ||
5795 | |||
5796 | ha->tgt.tgt_ops->put_sess(sess); | 5917 | ha->tgt.tgt_ops->put_sess(sess); |
5797 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); | 5918 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); |
5919 | |||
5920 | if (rc != 0) | ||
5921 | goto out_term; | ||
5798 | return; | 5922 | return; |
5799 | 5923 | ||
5924 | out_term2: | ||
5925 | if (sess) | ||
5926 | ha->tgt.tgt_ops->put_sess(sess); | ||
5927 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); | ||
5800 | out_term: | 5928 | out_term: |
5801 | qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1, 0); | 5929 | qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1, 0); |
5802 | ha->tgt.tgt_ops->put_sess(sess); | ||
5803 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); | ||
5804 | } | 5930 | } |
5805 | 5931 | ||
5806 | static void qlt_sess_work_fn(struct work_struct *work) | 5932 | static void qlt_sess_work_fn(struct work_struct *work) |
@@ -5893,13 +6019,13 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha) | |||
5893 | tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX; | 6019 | tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX; |
5894 | tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX; | 6020 | tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX; |
5895 | 6021 | ||
5896 | if (base_vha->fc_vport) | ||
5897 | return 0; | ||
5898 | |||
5899 | mutex_lock(&qla_tgt_mutex); | 6022 | mutex_lock(&qla_tgt_mutex); |
5900 | list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist); | 6023 | list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist); |
5901 | mutex_unlock(&qla_tgt_mutex); | 6024 | mutex_unlock(&qla_tgt_mutex); |
5902 | 6025 | ||
6026 | if (ha->tgt.tgt_ops && ha->tgt.tgt_ops->add_target) | ||
6027 | ha->tgt.tgt_ops->add_target(base_vha); | ||
6028 | |||
5903 | return 0; | 6029 | return 0; |
5904 | } | 6030 | } |
5905 | 6031 | ||
@@ -5928,6 +6054,17 @@ int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha) | |||
5928 | return 0; | 6054 | return 0; |
5929 | } | 6055 | } |
5930 | 6056 | ||
6057 | void qlt_remove_target_resources(struct qla_hw_data *ha) | ||
6058 | { | ||
6059 | struct scsi_qla_host *node; | ||
6060 | u32 key = 0; | ||
6061 | |||
6062 | btree_for_each_safe32(&ha->tgt.host_map, key, node) | ||
6063 | btree_remove32(&ha->tgt.host_map, key); | ||
6064 | |||
6065 | btree_destroy32(&ha->tgt.host_map); | ||
6066 | } | ||
6067 | |||
5931 | static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn, | 6068 | static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn, |
5932 | unsigned char *b) | 6069 | unsigned char *b) |
5933 | { | 6070 | { |
@@ -6234,7 +6371,7 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha, uint8_t ha_locked) | |||
6234 | struct atio_from_isp *pkt; | 6371 | struct atio_from_isp *pkt; |
6235 | int cnt, i; | 6372 | int cnt, i; |
6236 | 6373 | ||
6237 | if (!vha->flags.online) | 6374 | if (!ha->flags.fw_started) |
6238 | return; | 6375 | return; |
6239 | 6376 | ||
6240 | while ((ha->tgt.atio_ring_ptr->signature != ATIO_PROCESSED) || | 6377 | while ((ha->tgt.atio_ring_ptr->signature != ATIO_PROCESSED) || |
@@ -6581,6 +6718,8 @@ qlt_modify_vp_config(struct scsi_qla_host *vha, | |||
6581 | void | 6718 | void |
6582 | qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha) | 6719 | qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha) |
6583 | { | 6720 | { |
6721 | int rc; | ||
6722 | |||
6584 | if (!QLA_TGT_MODE_ENABLED()) | 6723 | if (!QLA_TGT_MODE_ENABLED()) |
6585 | return; | 6724 | return; |
6586 | 6725 | ||
@@ -6600,6 +6739,13 @@ qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha) | |||
6600 | qlt_unknown_atio_work_fn); | 6739 | qlt_unknown_atio_work_fn); |
6601 | 6740 | ||
6602 | qlt_clear_mode(base_vha); | 6741 | qlt_clear_mode(base_vha); |
6742 | |||
6743 | rc = btree_init32(&ha->tgt.host_map); | ||
6744 | if (rc) | ||
6745 | ql_log(ql_log_info, base_vha, 0xffff, | ||
6746 | "Unable to initialize ha->host_map btree\n"); | ||
6747 | |||
6748 | qlt_update_vp_map(base_vha, SET_VP_IDX); | ||
6603 | } | 6749 | } |
6604 | 6750 | ||
6605 | irqreturn_t | 6751 | irqreturn_t |
@@ -6642,6 +6788,8 @@ qlt_handle_abts_recv_work(struct work_struct *work) | |||
6642 | spin_lock_irqsave(&ha->hardware_lock, flags); | 6788 | spin_lock_irqsave(&ha->hardware_lock, flags); |
6643 | qlt_response_pkt_all_vps(vha, (response_t *)&op->atio); | 6789 | qlt_response_pkt_all_vps(vha, (response_t *)&op->atio); |
6644 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 6790 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
6791 | |||
6792 | kfree(op); | ||
6645 | } | 6793 | } |
6646 | 6794 | ||
6647 | void | 6795 | void |
@@ -6706,25 +6854,69 @@ qlt_mem_free(struct qla_hw_data *ha) | |||
6706 | void | 6854 | void |
6707 | qlt_update_vp_map(struct scsi_qla_host *vha, int cmd) | 6855 | qlt_update_vp_map(struct scsi_qla_host *vha, int cmd) |
6708 | { | 6856 | { |
6857 | void *slot; | ||
6858 | u32 key; | ||
6859 | int rc; | ||
6860 | |||
6709 | if (!QLA_TGT_MODE_ENABLED()) | 6861 | if (!QLA_TGT_MODE_ENABLED()) |
6710 | return; | 6862 | return; |
6711 | 6863 | ||
6864 | key = vha->d_id.b24; | ||
6865 | |||
6712 | switch (cmd) { | 6866 | switch (cmd) { |
6713 | case SET_VP_IDX: | 6867 | case SET_VP_IDX: |
6714 | vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = vha; | 6868 | vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = vha; |
6715 | break; | 6869 | break; |
6716 | case SET_AL_PA: | 6870 | case SET_AL_PA: |
6717 | vha->hw->tgt.tgt_vp_map[vha->d_id.b.al_pa].idx = vha->vp_idx; | 6871 | slot = btree_lookup32(&vha->hw->tgt.host_map, key); |
6872 | if (!slot) { | ||
6873 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff, | ||
6874 | "Save vha in host_map %p %06x\n", vha, key); | ||
6875 | rc = btree_insert32(&vha->hw->tgt.host_map, | ||
6876 | key, vha, GFP_ATOMIC); | ||
6877 | if (rc) | ||
6878 | ql_log(ql_log_info, vha, 0xffff, | ||
6879 | "Unable to insert s_id into host_map: %06x\n", | ||
6880 | key); | ||
6881 | return; | ||
6882 | } | ||
6883 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff, | ||
6884 | "replace existing vha in host_map %p %06x\n", vha, key); | ||
6885 | btree_update32(&vha->hw->tgt.host_map, key, vha); | ||
6718 | break; | 6886 | break; |
6719 | case RESET_VP_IDX: | 6887 | case RESET_VP_IDX: |
6720 | vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = NULL; | 6888 | vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = NULL; |
6721 | break; | 6889 | break; |
6722 | case RESET_AL_PA: | 6890 | case RESET_AL_PA: |
6723 | vha->hw->tgt.tgt_vp_map[vha->d_id.b.al_pa].idx = 0; | 6891 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff, |
6892 | "clear vha in host_map %p %06x\n", vha, key); | ||
6893 | slot = btree_lookup32(&vha->hw->tgt.host_map, key); | ||
6894 | if (slot) | ||
6895 | btree_remove32(&vha->hw->tgt.host_map, key); | ||
6896 | vha->d_id.b24 = 0; | ||
6724 | break; | 6897 | break; |
6725 | } | 6898 | } |
6726 | } | 6899 | } |
6727 | 6900 | ||
6901 | void qlt_update_host_map(struct scsi_qla_host *vha, port_id_t id) | ||
6902 | { | ||
6903 | unsigned long flags; | ||
6904 | struct qla_hw_data *ha = vha->hw; | ||
6905 | |||
6906 | if (!vha->d_id.b24) { | ||
6907 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
6908 | vha->d_id = id; | ||
6909 | qlt_update_vp_map(vha, SET_AL_PA); | ||
6910 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
6911 | } else if (vha->d_id.b24 != id.b24) { | ||
6912 | spin_lock_irqsave(&ha->vport_slock, flags); | ||
6913 | qlt_update_vp_map(vha, RESET_AL_PA); | ||
6914 | vha->d_id = id; | ||
6915 | qlt_update_vp_map(vha, SET_AL_PA); | ||
6916 | spin_unlock_irqrestore(&ha->vport_slock, flags); | ||
6917 | } | ||
6918 | } | ||
6919 | |||
6728 | static int __init qlt_parse_ini_mode(void) | 6920 | static int __init qlt_parse_ini_mode(void) |
6729 | { | 6921 | { |
6730 | if (strcasecmp(qlini_mode, QLA2XXX_INI_MODE_STR_EXCLUSIVE) == 0) | 6922 | if (strcasecmp(qlini_mode, QLA2XXX_INI_MODE_STR_EXCLUSIVE) == 0) |
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index a7f90dcaae37..d64420251194 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h | |||
@@ -378,6 +378,14 @@ static inline void adjust_corrupted_atio(struct atio_from_isp *atio) | |||
378 | atio->u.isp24.fcp_cmnd.add_cdb_len = 0; | 378 | atio->u.isp24.fcp_cmnd.add_cdb_len = 0; |
379 | } | 379 | } |
380 | 380 | ||
381 | static inline int get_datalen_for_atio(struct atio_from_isp *atio) | ||
382 | { | ||
383 | int len = atio->u.isp24.fcp_cmnd.add_cdb_len; | ||
384 | |||
385 | return (be32_to_cpu(get_unaligned((uint32_t *) | ||
386 | &atio->u.isp24.fcp_cmnd.add_cdb[len * 4]))); | ||
387 | } | ||
388 | |||
381 | #define CTIO_TYPE7 0x12 /* Continue target I/O entry (for 24xx) */ | 389 | #define CTIO_TYPE7 0x12 /* Continue target I/O entry (for 24xx) */ |
382 | 390 | ||
383 | /* | 391 | /* |
@@ -667,7 +675,6 @@ struct qla_tgt_func_tmpl { | |||
667 | int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *, | 675 | int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *, |
668 | unsigned char *, uint32_t, int, int, int); | 676 | unsigned char *, uint32_t, int, int, int); |
669 | void (*handle_data)(struct qla_tgt_cmd *); | 677 | void (*handle_data)(struct qla_tgt_cmd *); |
670 | void (*handle_dif_err)(struct qla_tgt_cmd *); | ||
671 | int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint16_t, | 678 | int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint16_t, |
672 | uint32_t); | 679 | uint32_t); |
673 | void (*free_cmd)(struct qla_tgt_cmd *); | 680 | void (*free_cmd)(struct qla_tgt_cmd *); |
@@ -684,6 +691,9 @@ struct qla_tgt_func_tmpl { | |||
684 | void (*clear_nacl_from_fcport_map)(struct fc_port *); | 691 | void (*clear_nacl_from_fcport_map)(struct fc_port *); |
685 | void (*put_sess)(struct fc_port *); | 692 | void (*put_sess)(struct fc_port *); |
686 | void (*shutdown_sess)(struct fc_port *); | 693 | void (*shutdown_sess)(struct fc_port *); |
694 | int (*get_dif_tags)(struct qla_tgt_cmd *cmd, uint16_t *pfw_prot_opts); | ||
695 | int (*chk_dif_tags)(uint32_t tag); | ||
696 | void (*add_target)(struct scsi_qla_host *); | ||
687 | }; | 697 | }; |
688 | 698 | ||
689 | int qla2x00_wait_for_hba_online(struct scsi_qla_host *); | 699 | int qla2x00_wait_for_hba_online(struct scsi_qla_host *); |
@@ -720,8 +730,8 @@ int qla2x00_wait_for_hba_online(struct scsi_qla_host *); | |||
720 | #define QLA_TGT_ABORT_ALL 0xFFFE | 730 | #define QLA_TGT_ABORT_ALL 0xFFFE |
721 | #define QLA_TGT_NEXUS_LOSS_SESS 0xFFFD | 731 | #define QLA_TGT_NEXUS_LOSS_SESS 0xFFFD |
722 | #define QLA_TGT_NEXUS_LOSS 0xFFFC | 732 | #define QLA_TGT_NEXUS_LOSS 0xFFFC |
723 | #define QLA_TGT_ABTS 0xFFFB | 733 | #define QLA_TGT_ABTS 0xFFFB |
724 | #define QLA_TGT_2G_ABORT_TASK 0xFFFA | 734 | #define QLA_TGT_2G_ABORT_TASK 0xFFFA |
725 | 735 | ||
726 | /* Notify Acknowledge flags */ | 736 | /* Notify Acknowledge flags */ |
727 | #define NOTIFY_ACK_RES_COUNT BIT_8 | 737 | #define NOTIFY_ACK_RES_COUNT BIT_8 |
@@ -845,6 +855,7 @@ enum trace_flags { | |||
845 | TRC_CMD_FREE = BIT_17, | 855 | TRC_CMD_FREE = BIT_17, |
846 | TRC_DATA_IN = BIT_18, | 856 | TRC_DATA_IN = BIT_18, |
847 | TRC_ABORT = BIT_19, | 857 | TRC_ABORT = BIT_19, |
858 | TRC_DIF_ERR = BIT_20, | ||
848 | }; | 859 | }; |
849 | 860 | ||
850 | struct qla_tgt_cmd { | 861 | struct qla_tgt_cmd { |
@@ -862,7 +873,6 @@ struct qla_tgt_cmd { | |||
862 | unsigned int sg_mapped:1; | 873 | unsigned int sg_mapped:1; |
863 | unsigned int free_sg:1; | 874 | unsigned int free_sg:1; |
864 | unsigned int write_data_transferred:1; | 875 | unsigned int write_data_transferred:1; |
865 | unsigned int ctx_dsd_alloced:1; | ||
866 | unsigned int q_full:1; | 876 | unsigned int q_full:1; |
867 | unsigned int term_exchg:1; | 877 | unsigned int term_exchg:1; |
868 | unsigned int cmd_sent_to_fw:1; | 878 | unsigned int cmd_sent_to_fw:1; |
@@ -885,11 +895,25 @@ struct qla_tgt_cmd { | |||
885 | struct list_head cmd_list; | 895 | struct list_head cmd_list; |
886 | 896 | ||
887 | struct atio_from_isp atio; | 897 | struct atio_from_isp atio; |
888 | /* t10dif */ | 898 | |
899 | uint8_t ctx_dsd_alloced; | ||
900 | |||
901 | /* T10-DIF */ | ||
902 | #define DIF_ERR_NONE 0 | ||
903 | #define DIF_ERR_GRD 1 | ||
904 | #define DIF_ERR_REF 2 | ||
905 | #define DIF_ERR_APP 3 | ||
906 | int8_t dif_err_code; | ||
889 | struct scatterlist *prot_sg; | 907 | struct scatterlist *prot_sg; |
890 | uint32_t prot_sg_cnt; | 908 | uint32_t prot_sg_cnt; |
891 | uint32_t blk_sz; | 909 | uint32_t blk_sz, num_blks; |
910 | uint8_t scsi_status, sense_key, asc, ascq; | ||
911 | |||
892 | struct crc_context *ctx; | 912 | struct crc_context *ctx; |
913 | uint8_t *cdb; | ||
914 | uint64_t lba; | ||
915 | uint16_t a_guard, e_guard, a_app_tag, e_app_tag; | ||
916 | uint32_t a_ref_tag, e_ref_tag; | ||
893 | 917 | ||
894 | uint64_t jiffies_at_alloc; | 918 | uint64_t jiffies_at_alloc; |
895 | uint64_t jiffies_at_free; | 919 | uint64_t jiffies_at_free; |
@@ -1053,4 +1077,7 @@ extern int qlt_free_qfull_cmds(struct scsi_qla_host *); | |||
1053 | extern void qlt_logo_completion_handler(fc_port_t *, int); | 1077 | extern void qlt_logo_completion_handler(fc_port_t *, int); |
1054 | extern void qlt_do_generation_tick(struct scsi_qla_host *, int *); | 1078 | extern void qlt_do_generation_tick(struct scsi_qla_host *, int *); |
1055 | 1079 | ||
1080 | void qlt_send_resp_ctio(scsi_qla_host_t *, struct qla_tgt_cmd *, uint8_t, | ||
1081 | uint8_t, uint8_t, uint8_t); | ||
1082 | |||
1056 | #endif /* __QLA_TARGET_H */ | 1083 | #endif /* __QLA_TARGET_H */ |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 3cb1964b7786..45bc84e8e3bf 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,9 +7,9 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.07.00.38-k" | 10 | #define QLA2XXX_VERSION "9.00.00.00-k" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 9 |
13 | #define QLA_DRIVER_MINOR_VER 7 | 13 | #define QLA_DRIVER_MINOR_VER 0 |
14 | #define QLA_DRIVER_PATCH_VER 0 | 14 | #define QLA_DRIVER_PATCH_VER 0 |
15 | #define QLA_DRIVER_BETA_VER 0 | 15 | #define QLA_DRIVER_BETA_VER 0 |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 8e8ab0fa9672..7443e4efa3ae 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
@@ -531,6 +531,24 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work) | |||
531 | return; | 531 | return; |
532 | } | 532 | } |
533 | 533 | ||
534 | switch (cmd->dif_err_code) { | ||
535 | case DIF_ERR_GRD: | ||
536 | cmd->se_cmd.pi_err = | ||
537 | TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED; | ||
538 | break; | ||
539 | case DIF_ERR_REF: | ||
540 | cmd->se_cmd.pi_err = | ||
541 | TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED; | ||
542 | break; | ||
543 | case DIF_ERR_APP: | ||
544 | cmd->se_cmd.pi_err = | ||
545 | TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED; | ||
546 | break; | ||
547 | case DIF_ERR_NONE: | ||
548 | default: | ||
549 | break; | ||
550 | } | ||
551 | |||
534 | if (cmd->se_cmd.pi_err) | 552 | if (cmd->se_cmd.pi_err) |
535 | transport_generic_request_failure(&cmd->se_cmd, | 553 | transport_generic_request_failure(&cmd->se_cmd, |
536 | cmd->se_cmd.pi_err); | 554 | cmd->se_cmd.pi_err); |
@@ -555,25 +573,23 @@ static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd) | |||
555 | queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work); | 573 | queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work); |
556 | } | 574 | } |
557 | 575 | ||
558 | static void tcm_qla2xxx_handle_dif_work(struct work_struct *work) | 576 | static int tcm_qla2xxx_chk_dif_tags(uint32_t tag) |
559 | { | 577 | { |
560 | struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); | 578 | return 0; |
561 | |||
562 | /* take an extra kref to prevent cmd free too early. | ||
563 | * need to wait for SCSI status/check condition to | ||
564 | * finish responding generate by transport_generic_request_failure. | ||
565 | */ | ||
566 | kref_get(&cmd->se_cmd.cmd_kref); | ||
567 | transport_generic_request_failure(&cmd->se_cmd, cmd->se_cmd.pi_err); | ||
568 | } | 579 | } |
569 | 580 | ||
570 | /* | 581 | static int tcm_qla2xxx_dif_tags(struct qla_tgt_cmd *cmd, |
571 | * Called from qla_target.c:qlt_do_ctio_completion() | 582 | uint16_t *pfw_prot_opts) |
572 | */ | ||
573 | static void tcm_qla2xxx_handle_dif_err(struct qla_tgt_cmd *cmd) | ||
574 | { | 583 | { |
575 | INIT_WORK(&cmd->work, tcm_qla2xxx_handle_dif_work); | 584 | struct se_cmd *se_cmd = &cmd->se_cmd; |
576 | queue_work(tcm_qla2xxx_free_wq, &cmd->work); | 585 | |
586 | if (!(se_cmd->prot_checks & TARGET_DIF_CHECK_GUARD)) | ||
587 | *pfw_prot_opts |= PO_DISABLE_GUARD_CHECK; | ||
588 | |||
589 | if (!(se_cmd->prot_checks & TARGET_DIF_CHECK_APPTAG)) | ||
590 | *pfw_prot_opts |= PO_DIS_APP_TAG_VALD; | ||
591 | |||
592 | return 0; | ||
577 | } | 593 | } |
578 | 594 | ||
579 | /* | 595 | /* |
@@ -1610,7 +1626,6 @@ static void tcm_qla2xxx_update_sess(struct fc_port *sess, port_id_t s_id, | |||
1610 | static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { | 1626 | static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { |
1611 | .handle_cmd = tcm_qla2xxx_handle_cmd, | 1627 | .handle_cmd = tcm_qla2xxx_handle_cmd, |
1612 | .handle_data = tcm_qla2xxx_handle_data, | 1628 | .handle_data = tcm_qla2xxx_handle_data, |
1613 | .handle_dif_err = tcm_qla2xxx_handle_dif_err, | ||
1614 | .handle_tmr = tcm_qla2xxx_handle_tmr, | 1629 | .handle_tmr = tcm_qla2xxx_handle_tmr, |
1615 | .free_cmd = tcm_qla2xxx_free_cmd, | 1630 | .free_cmd = tcm_qla2xxx_free_cmd, |
1616 | .free_mcmd = tcm_qla2xxx_free_mcmd, | 1631 | .free_mcmd = tcm_qla2xxx_free_mcmd, |
@@ -1622,6 +1637,8 @@ static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { | |||
1622 | .clear_nacl_from_fcport_map = tcm_qla2xxx_clear_nacl_from_fcport_map, | 1637 | .clear_nacl_from_fcport_map = tcm_qla2xxx_clear_nacl_from_fcport_map, |
1623 | .put_sess = tcm_qla2xxx_put_sess, | 1638 | .put_sess = tcm_qla2xxx_put_sess, |
1624 | .shutdown_sess = tcm_qla2xxx_shutdown_sess, | 1639 | .shutdown_sess = tcm_qla2xxx_shutdown_sess, |
1640 | .get_dif_tags = tcm_qla2xxx_dif_tags, | ||
1641 | .chk_dif_tags = tcm_qla2xxx_chk_dif_tags, | ||
1625 | }; | 1642 | }; |
1626 | 1643 | ||
1627 | static int tcm_qla2xxx_init_lport(struct tcm_qla2xxx_lport *lport) | 1644 | static int tcm_qla2xxx_init_lport(struct tcm_qla2xxx_lport *lport) |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ba2286652ff6..19125d72f322 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -2932,6 +2932,8 @@ EXPORT_SYMBOL(scsi_target_resume); | |||
2932 | /** | 2932 | /** |
2933 | * scsi_internal_device_block - internal function to put a device temporarily into the SDEV_BLOCK state | 2933 | * scsi_internal_device_block - internal function to put a device temporarily into the SDEV_BLOCK state |
2934 | * @sdev: device to block | 2934 | * @sdev: device to block |
2935 | * @wait: Whether or not to wait until ongoing .queuecommand() / | ||
2936 | * .queue_rq() calls have finished. | ||
2935 | * | 2937 | * |
2936 | * Block request made by scsi lld's to temporarily stop all | 2938 | * Block request made by scsi lld's to temporarily stop all |
2937 | * scsi commands on the specified device. May sleep. | 2939 | * scsi commands on the specified device. May sleep. |
@@ -2949,7 +2951,7 @@ EXPORT_SYMBOL(scsi_target_resume); | |||
2949 | * remove the rport mutex lock and unlock calls from srp_queuecommand(). | 2951 | * remove the rport mutex lock and unlock calls from srp_queuecommand(). |
2950 | */ | 2952 | */ |
2951 | int | 2953 | int |
2952 | scsi_internal_device_block(struct scsi_device *sdev) | 2954 | scsi_internal_device_block(struct scsi_device *sdev, bool wait) |
2953 | { | 2955 | { |
2954 | struct request_queue *q = sdev->request_queue; | 2956 | struct request_queue *q = sdev->request_queue; |
2955 | unsigned long flags; | 2957 | unsigned long flags; |
@@ -2969,12 +2971,16 @@ scsi_internal_device_block(struct scsi_device *sdev) | |||
2969 | * request queue. | 2971 | * request queue. |
2970 | */ | 2972 | */ |
2971 | if (q->mq_ops) { | 2973 | if (q->mq_ops) { |
2972 | blk_mq_quiesce_queue(q); | 2974 | if (wait) |
2975 | blk_mq_quiesce_queue(q); | ||
2976 | else | ||
2977 | blk_mq_stop_hw_queues(q); | ||
2973 | } else { | 2978 | } else { |
2974 | spin_lock_irqsave(q->queue_lock, flags); | 2979 | spin_lock_irqsave(q->queue_lock, flags); |
2975 | blk_stop_queue(q); | 2980 | blk_stop_queue(q); |
2976 | spin_unlock_irqrestore(q->queue_lock, flags); | 2981 | spin_unlock_irqrestore(q->queue_lock, flags); |
2977 | scsi_wait_for_queuecommand(sdev); | 2982 | if (wait) |
2983 | scsi_wait_for_queuecommand(sdev); | ||
2978 | } | 2984 | } |
2979 | 2985 | ||
2980 | return 0; | 2986 | return 0; |
@@ -3036,7 +3042,7 @@ EXPORT_SYMBOL_GPL(scsi_internal_device_unblock); | |||
3036 | static void | 3042 | static void |
3037 | device_block(struct scsi_device *sdev, void *data) | 3043 | device_block(struct scsi_device *sdev, void *data) |
3038 | { | 3044 | { |
3039 | scsi_internal_device_block(sdev); | 3045 | scsi_internal_device_block(sdev, true); |
3040 | } | 3046 | } |
3041 | 3047 | ||
3042 | static int | 3048 | static int |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 99bfc985e190..f11bd102d6d5 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -188,8 +188,5 @@ static inline void scsi_dh_remove_device(struct scsi_device *sdev) { } | |||
188 | */ | 188 | */ |
189 | 189 | ||
190 | #define SCSI_DEVICE_BLOCK_MAX_TIMEOUT 600 /* units in seconds */ | 190 | #define SCSI_DEVICE_BLOCK_MAX_TIMEOUT 600 /* units in seconds */ |
191 | extern int scsi_internal_device_block(struct scsi_device *sdev); | ||
192 | extern int scsi_internal_device_unblock(struct scsi_device *sdev, | ||
193 | enum scsi_device_state new_state); | ||
194 | 191 | ||
195 | #endif /* _SCSI_PRIV_H */ | 192 | #endif /* _SCSI_PRIV_H */ |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index d277e8620e3e..fcfeddc79331 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -1783,6 +1783,8 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1783 | { | 1783 | { |
1784 | int result = SCpnt->result; | 1784 | int result = SCpnt->result; |
1785 | unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); | 1785 | unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); |
1786 | unsigned int sector_size = SCpnt->device->sector_size; | ||
1787 | unsigned int resid; | ||
1786 | struct scsi_sense_hdr sshdr; | 1788 | struct scsi_sense_hdr sshdr; |
1787 | struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); | 1789 | struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); |
1788 | struct request *req = SCpnt->request; | 1790 | struct request *req = SCpnt->request; |
@@ -1813,6 +1815,21 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1813 | scsi_set_resid(SCpnt, blk_rq_bytes(req)); | 1815 | scsi_set_resid(SCpnt, blk_rq_bytes(req)); |
1814 | } | 1816 | } |
1815 | break; | 1817 | break; |
1818 | default: | ||
1819 | /* | ||
1820 | * In case of bogus fw or device, we could end up having | ||
1821 | * an unaligned partial completion. Check this here and force | ||
1822 | * alignment. | ||
1823 | */ | ||
1824 | resid = scsi_get_resid(SCpnt); | ||
1825 | if (resid & (sector_size - 1)) { | ||
1826 | sd_printk(KERN_INFO, sdkp, | ||
1827 | "Unaligned partial completion (resid=%u, sector_sz=%u)\n", | ||
1828 | resid, sector_size); | ||
1829 | resid = min(scsi_bufflen(SCpnt), | ||
1830 | round_up(resid, sector_size)); | ||
1831 | scsi_set_resid(SCpnt, resid); | ||
1832 | } | ||
1816 | } | 1833 | } |
1817 | 1834 | ||
1818 | if (result) { | 1835 | if (result) { |
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 638e5f427c90..016639d7fef1 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c | |||
@@ -400,8 +400,6 @@ MODULE_PARM_DESC(storvsc_vcpus_per_sub_channel, "Ratio of VCPUs to subchannels") | |||
400 | */ | 400 | */ |
401 | static int storvsc_timeout = 180; | 401 | static int storvsc_timeout = 180; |
402 | 402 | ||
403 | static int msft_blist_flags = BLIST_TRY_VPD_PAGES; | ||
404 | |||
405 | #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) | 403 | #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) |
406 | static struct scsi_transport_template *fc_transport_template; | 404 | static struct scsi_transport_template *fc_transport_template; |
407 | #endif | 405 | #endif |
@@ -1383,6 +1381,22 @@ static int storvsc_do_io(struct hv_device *device, | |||
1383 | return ret; | 1381 | return ret; |
1384 | } | 1382 | } |
1385 | 1383 | ||
1384 | static int storvsc_device_alloc(struct scsi_device *sdevice) | ||
1385 | { | ||
1386 | /* | ||
1387 | * Set blist flag to permit the reading of the VPD pages even when | ||
1388 | * the target may claim SPC-2 compliance. MSFT targets currently | ||
1389 | * claim SPC-2 compliance while they implement post SPC-2 features. | ||
1390 | * With this flag we can correctly handle WRITE_SAME_16 issues. | ||
1391 | * | ||
1392 | * Hypervisor reports SCSI_UNKNOWN type for DVD ROM device but | ||
1393 | * still supports REPORT LUN. | ||
1394 | */ | ||
1395 | sdevice->sdev_bflags = BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES; | ||
1396 | |||
1397 | return 0; | ||
1398 | } | ||
1399 | |||
1386 | static int storvsc_device_configure(struct scsi_device *sdevice) | 1400 | static int storvsc_device_configure(struct scsi_device *sdevice) |
1387 | { | 1401 | { |
1388 | 1402 | ||
@@ -1396,14 +1410,6 @@ static int storvsc_device_configure(struct scsi_device *sdevice) | |||
1396 | sdevice->no_write_same = 1; | 1410 | sdevice->no_write_same = 1; |
1397 | 1411 | ||
1398 | /* | 1412 | /* |
1399 | * Add blist flags to permit the reading of the VPD pages even when | ||
1400 | * the target may claim SPC-2 compliance. MSFT targets currently | ||
1401 | * claim SPC-2 compliance while they implement post SPC-2 features. | ||
1402 | * With this patch we can correctly handle WRITE_SAME_16 issues. | ||
1403 | */ | ||
1404 | sdevice->sdev_bflags |= msft_blist_flags; | ||
1405 | |||
1406 | /* | ||
1407 | * If the host is WIN8 or WIN8 R2, claim conformance to SPC-3 | 1413 | * If the host is WIN8 or WIN8 R2, claim conformance to SPC-3 |
1408 | * if the device is a MSFT virtual device. If the host is | 1414 | * if the device is a MSFT virtual device. If the host is |
1409 | * WIN10 or newer, allow write_same. | 1415 | * WIN10 or newer, allow write_same. |
@@ -1661,6 +1667,7 @@ static struct scsi_host_template scsi_driver = { | |||
1661 | .eh_host_reset_handler = storvsc_host_reset_handler, | 1667 | .eh_host_reset_handler = storvsc_host_reset_handler, |
1662 | .proc_name = "storvsc_host", | 1668 | .proc_name = "storvsc_host", |
1663 | .eh_timed_out = storvsc_eh_timed_out, | 1669 | .eh_timed_out = storvsc_eh_timed_out, |
1670 | .slave_alloc = storvsc_device_alloc, | ||
1664 | .slave_configure = storvsc_device_configure, | 1671 | .slave_configure = storvsc_device_configure, |
1665 | .cmd_per_lun = 255, | 1672 | .cmd_per_lun = 255, |
1666 | .this_id = -1, | 1673 | .this_id = -1, |
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 318e4a1f76c9..54deeb754db5 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h | |||
@@ -146,7 +146,7 @@ enum attr_idn { | |||
146 | /* Descriptor idn for Query requests */ | 146 | /* Descriptor idn for Query requests */ |
147 | enum desc_idn { | 147 | enum desc_idn { |
148 | QUERY_DESC_IDN_DEVICE = 0x0, | 148 | QUERY_DESC_IDN_DEVICE = 0x0, |
149 | QUERY_DESC_IDN_CONFIGURAION = 0x1, | 149 | QUERY_DESC_IDN_CONFIGURATION = 0x1, |
150 | QUERY_DESC_IDN_UNIT = 0x2, | 150 | QUERY_DESC_IDN_UNIT = 0x2, |
151 | QUERY_DESC_IDN_RFU_0 = 0x3, | 151 | QUERY_DESC_IDN_RFU_0 = 0x3, |
152 | QUERY_DESC_IDN_INTERCONNECT = 0x4, | 152 | QUERY_DESC_IDN_INTERCONNECT = 0x4, |
@@ -162,19 +162,13 @@ enum desc_header_offset { | |||
162 | QUERY_DESC_DESC_TYPE_OFFSET = 0x01, | 162 | QUERY_DESC_DESC_TYPE_OFFSET = 0x01, |
163 | }; | 163 | }; |
164 | 164 | ||
165 | enum ufs_desc_max_size { | 165 | enum ufs_desc_def_size { |
166 | QUERY_DESC_DEVICE_MAX_SIZE = 0x40, | 166 | QUERY_DESC_DEVICE_DEF_SIZE = 0x40, |
167 | QUERY_DESC_CONFIGURAION_MAX_SIZE = 0x90, | 167 | QUERY_DESC_CONFIGURATION_DEF_SIZE = 0x90, |
168 | QUERY_DESC_UNIT_MAX_SIZE = 0x23, | 168 | QUERY_DESC_UNIT_DEF_SIZE = 0x23, |
169 | QUERY_DESC_INTERCONNECT_MAX_SIZE = 0x06, | 169 | QUERY_DESC_INTERCONNECT_DEF_SIZE = 0x06, |
170 | /* | 170 | QUERY_DESC_GEOMETRY_DEF_SIZE = 0x44, |
171 | * Max. 126 UNICODE characters (2 bytes per character) plus 2 bytes | 171 | QUERY_DESC_POWER_DEF_SIZE = 0x62, |
172 | * of descriptor header. | ||
173 | */ | ||
174 | QUERY_DESC_STRING_MAX_SIZE = 0xFE, | ||
175 | QUERY_DESC_GEOMETRY_MAX_SIZE = 0x44, | ||
176 | QUERY_DESC_POWER_MAX_SIZE = 0x62, | ||
177 | QUERY_DESC_RFU_MAX_SIZE = 0x00, | ||
178 | }; | 172 | }; |
179 | 173 | ||
180 | /* Unit descriptor parameters offsets in bytes*/ | 174 | /* Unit descriptor parameters offsets in bytes*/ |
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index dc6efbd1be8e..1359913bf840 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c | |||
@@ -100,19 +100,6 @@ | |||
100 | #define ufshcd_hex_dump(prefix_str, buf, len) \ | 100 | #define ufshcd_hex_dump(prefix_str, buf, len) \ |
101 | print_hex_dump(KERN_ERR, prefix_str, DUMP_PREFIX_OFFSET, 16, 4, buf, len, false) | 101 | print_hex_dump(KERN_ERR, prefix_str, DUMP_PREFIX_OFFSET, 16, 4, buf, len, false) |
102 | 102 | ||
103 | static u32 ufs_query_desc_max_size[] = { | ||
104 | QUERY_DESC_DEVICE_MAX_SIZE, | ||
105 | QUERY_DESC_CONFIGURAION_MAX_SIZE, | ||
106 | QUERY_DESC_UNIT_MAX_SIZE, | ||
107 | QUERY_DESC_RFU_MAX_SIZE, | ||
108 | QUERY_DESC_INTERCONNECT_MAX_SIZE, | ||
109 | QUERY_DESC_STRING_MAX_SIZE, | ||
110 | QUERY_DESC_RFU_MAX_SIZE, | ||
111 | QUERY_DESC_GEOMETRY_MAX_SIZE, | ||
112 | QUERY_DESC_POWER_MAX_SIZE, | ||
113 | QUERY_DESC_RFU_MAX_SIZE, | ||
114 | }; | ||
115 | |||
116 | enum { | 103 | enum { |
117 | UFSHCD_MAX_CHANNEL = 0, | 104 | UFSHCD_MAX_CHANNEL = 0, |
118 | UFSHCD_MAX_ID = 1, | 105 | UFSHCD_MAX_ID = 1, |
@@ -2857,7 +2844,7 @@ static int __ufshcd_query_descriptor(struct ufs_hba *hba, | |||
2857 | goto out; | 2844 | goto out; |
2858 | } | 2845 | } |
2859 | 2846 | ||
2860 | if (*buf_len <= QUERY_DESC_MIN_SIZE || *buf_len > QUERY_DESC_MAX_SIZE) { | 2847 | if (*buf_len < QUERY_DESC_MIN_SIZE || *buf_len > QUERY_DESC_MAX_SIZE) { |
2861 | dev_err(hba->dev, "%s: descriptor buffer size (%d) is out of range\n", | 2848 | dev_err(hba->dev, "%s: descriptor buffer size (%d) is out of range\n", |
2862 | __func__, *buf_len); | 2849 | __func__, *buf_len); |
2863 | err = -EINVAL; | 2850 | err = -EINVAL; |
@@ -2938,6 +2925,92 @@ static int ufshcd_query_descriptor_retry(struct ufs_hba *hba, | |||
2938 | } | 2925 | } |
2939 | 2926 | ||
2940 | /** | 2927 | /** |
2928 | * ufshcd_read_desc_length - read the specified descriptor length from header | ||
2929 | * @hba: Pointer to adapter instance | ||
2930 | * @desc_id: descriptor idn value | ||
2931 | * @desc_index: descriptor index | ||
2932 | * @desc_length: pointer to variable to read the length of descriptor | ||
2933 | * | ||
2934 | * Return 0 in case of success, non-zero otherwise | ||
2935 | */ | ||
2936 | static int ufshcd_read_desc_length(struct ufs_hba *hba, | ||
2937 | enum desc_idn desc_id, | ||
2938 | int desc_index, | ||
2939 | int *desc_length) | ||
2940 | { | ||
2941 | int ret; | ||
2942 | u8 header[QUERY_DESC_HDR_SIZE]; | ||
2943 | int header_len = QUERY_DESC_HDR_SIZE; | ||
2944 | |||
2945 | if (desc_id >= QUERY_DESC_IDN_MAX) | ||
2946 | return -EINVAL; | ||
2947 | |||
2948 | ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_READ_DESC, | ||
2949 | desc_id, desc_index, 0, header, | ||
2950 | &header_len); | ||
2951 | |||
2952 | if (ret) { | ||
2953 | dev_err(hba->dev, "%s: Failed to get descriptor header id %d", | ||
2954 | __func__, desc_id); | ||
2955 | return ret; | ||
2956 | } else if (desc_id != header[QUERY_DESC_DESC_TYPE_OFFSET]) { | ||
2957 | dev_warn(hba->dev, "%s: descriptor header id %d and desc_id %d mismatch", | ||
2958 | __func__, header[QUERY_DESC_DESC_TYPE_OFFSET], | ||
2959 | desc_id); | ||
2960 | ret = -EINVAL; | ||
2961 | } | ||
2962 | |||
2963 | *desc_length = header[QUERY_DESC_LENGTH_OFFSET]; | ||
2964 | return ret; | ||
2965 | |||
2966 | } | ||
2967 | |||
2968 | /** | ||
2969 | * ufshcd_map_desc_id_to_length - map descriptor IDN to its length | ||
2970 | * @hba: Pointer to adapter instance | ||
2971 | * @desc_id: descriptor idn value | ||
2972 | * @desc_len: mapped desc length (out) | ||
2973 | * | ||
2974 | * Return 0 in case of success, non-zero otherwise | ||
2975 | */ | ||
2976 | int ufshcd_map_desc_id_to_length(struct ufs_hba *hba, | ||
2977 | enum desc_idn desc_id, int *desc_len) | ||
2978 | { | ||
2979 | switch (desc_id) { | ||
2980 | case QUERY_DESC_IDN_DEVICE: | ||
2981 | *desc_len = hba->desc_size.dev_desc; | ||
2982 | break; | ||
2983 | case QUERY_DESC_IDN_POWER: | ||
2984 | *desc_len = hba->desc_size.pwr_desc; | ||
2985 | break; | ||
2986 | case QUERY_DESC_IDN_GEOMETRY: | ||
2987 | *desc_len = hba->desc_size.geom_desc; | ||
2988 | break; | ||
2989 | case QUERY_DESC_IDN_CONFIGURATION: | ||
2990 | *desc_len = hba->desc_size.conf_desc; | ||
2991 | break; | ||
2992 | case QUERY_DESC_IDN_UNIT: | ||
2993 | *desc_len = hba->desc_size.unit_desc; | ||
2994 | break; | ||
2995 | case QUERY_DESC_IDN_INTERCONNECT: | ||
2996 | *desc_len = hba->desc_size.interc_desc; | ||
2997 | break; | ||
2998 | case QUERY_DESC_IDN_STRING: | ||
2999 | *desc_len = QUERY_DESC_MAX_SIZE; | ||
3000 | break; | ||
3001 | case QUERY_DESC_IDN_RFU_0: | ||
3002 | case QUERY_DESC_IDN_RFU_1: | ||
3003 | *desc_len = 0; | ||
3004 | break; | ||
3005 | default: | ||
3006 | *desc_len = 0; | ||
3007 | return -EINVAL; | ||
3008 | } | ||
3009 | return 0; | ||
3010 | } | ||
3011 | EXPORT_SYMBOL(ufshcd_map_desc_id_to_length); | ||
3012 | |||
3013 | /** | ||
2941 | * ufshcd_read_desc_param - read the specified descriptor parameter | 3014 | * ufshcd_read_desc_param - read the specified descriptor parameter |
2942 | * @hba: Pointer to adapter instance | 3015 | * @hba: Pointer to adapter instance |
2943 | * @desc_id: descriptor idn value | 3016 | * @desc_id: descriptor idn value |
@@ -2951,42 +3024,49 @@ static int ufshcd_query_descriptor_retry(struct ufs_hba *hba, | |||
2951 | static int ufshcd_read_desc_param(struct ufs_hba *hba, | 3024 | static int ufshcd_read_desc_param(struct ufs_hba *hba, |
2952 | enum desc_idn desc_id, | 3025 | enum desc_idn desc_id, |
2953 | int desc_index, | 3026 | int desc_index, |
2954 | u32 param_offset, | 3027 | u8 param_offset, |
2955 | u8 *param_read_buf, | 3028 | u8 *param_read_buf, |
2956 | u32 param_size) | 3029 | u8 param_size) |
2957 | { | 3030 | { |
2958 | int ret; | 3031 | int ret; |
2959 | u8 *desc_buf; | 3032 | u8 *desc_buf; |
2960 | u32 buff_len; | 3033 | int buff_len; |
2961 | bool is_kmalloc = true; | 3034 | bool is_kmalloc = true; |
2962 | 3035 | ||
2963 | /* safety checks */ | 3036 | /* Safety check */ |
2964 | if (desc_id >= QUERY_DESC_IDN_MAX) | 3037 | if (desc_id >= QUERY_DESC_IDN_MAX || !param_size) |
2965 | return -EINVAL; | 3038 | return -EINVAL; |
2966 | 3039 | ||
2967 | buff_len = ufs_query_desc_max_size[desc_id]; | 3040 | /* Get the max length of descriptor from structure filled up at probe |
2968 | if ((param_offset + param_size) > buff_len) | 3041 | * time. |
2969 | return -EINVAL; | 3042 | */ |
3043 | ret = ufshcd_map_desc_id_to_length(hba, desc_id, &buff_len); | ||
2970 | 3044 | ||
2971 | if (!param_offset && (param_size == buff_len)) { | 3045 | /* Sanity checks */ |
2972 | /* memory space already available to hold full descriptor */ | 3046 | if (ret || !buff_len) { |
2973 | desc_buf = param_read_buf; | 3047 | dev_err(hba->dev, "%s: Failed to get full descriptor length", |
2974 | is_kmalloc = false; | 3048 | __func__); |
2975 | } else { | 3049 | return ret; |
2976 | /* allocate memory to hold full descriptor */ | 3050 | } |
3051 | |||
3052 | /* Check whether we need temp memory */ | ||
3053 | if (param_offset != 0 || param_size < buff_len) { | ||
2977 | desc_buf = kmalloc(buff_len, GFP_KERNEL); | 3054 | desc_buf = kmalloc(buff_len, GFP_KERNEL); |
2978 | if (!desc_buf) | 3055 | if (!desc_buf) |
2979 | return -ENOMEM; | 3056 | return -ENOMEM; |
3057 | } else { | ||
3058 | desc_buf = param_read_buf; | ||
3059 | is_kmalloc = false; | ||
2980 | } | 3060 | } |
2981 | 3061 | ||
3062 | /* Request for full descriptor */ | ||
2982 | ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_READ_DESC, | 3063 | ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_READ_DESC, |
2983 | desc_id, desc_index, 0, desc_buf, | 3064 | desc_id, desc_index, 0, |
2984 | &buff_len); | 3065 | desc_buf, &buff_len); |
2985 | 3066 | ||
2986 | if (ret) { | 3067 | if (ret) { |
2987 | dev_err(hba->dev, "%s: Failed reading descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d", | 3068 | dev_err(hba->dev, "%s: Failed reading descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d", |
2988 | __func__, desc_id, desc_index, param_offset, ret); | 3069 | __func__, desc_id, desc_index, param_offset, ret); |
2989 | |||
2990 | goto out; | 3070 | goto out; |
2991 | } | 3071 | } |
2992 | 3072 | ||
@@ -2998,25 +3078,9 @@ static int ufshcd_read_desc_param(struct ufs_hba *hba, | |||
2998 | goto out; | 3078 | goto out; |
2999 | } | 3079 | } |
3000 | 3080 | ||
3001 | /* | 3081 | /* Check wherher we will not copy more data, than available */ |
3002 | * While reading variable size descriptors (like string descriptor), | 3082 | if (is_kmalloc && param_size > buff_len) |
3003 | * some UFS devices may report the "LENGTH" (field in "Transaction | 3083 | param_size = buff_len; |
3004 | * Specific fields" of Query Response UPIU) same as what was requested | ||
3005 | * in Query Request UPIU instead of reporting the actual size of the | ||
3006 | * variable size descriptor. | ||
3007 | * Although it's safe to ignore the "LENGTH" field for variable size | ||
3008 | * descriptors as we can always derive the length of the descriptor from | ||
3009 | * the descriptor header fields. Hence this change impose the length | ||
3010 | * match check only for fixed size descriptors (for which we always | ||
3011 | * request the correct size as part of Query Request UPIU). | ||
3012 | */ | ||
3013 | if ((desc_id != QUERY_DESC_IDN_STRING) && | ||
3014 | (buff_len != desc_buf[QUERY_DESC_LENGTH_OFFSET])) { | ||
3015 | dev_err(hba->dev, "%s: desc_buf length mismatch: buff_len %d, buff_len(desc_header) %d", | ||
3016 | __func__, buff_len, desc_buf[QUERY_DESC_LENGTH_OFFSET]); | ||
3017 | ret = -EINVAL; | ||
3018 | goto out; | ||
3019 | } | ||
3020 | 3084 | ||
3021 | if (is_kmalloc) | 3085 | if (is_kmalloc) |
3022 | memcpy(param_read_buf, &desc_buf[param_offset], param_size); | 3086 | memcpy(param_read_buf, &desc_buf[param_offset], param_size); |
@@ -5919,8 +5983,8 @@ static int ufshcd_set_icc_levels_attr(struct ufs_hba *hba, u32 icc_level) | |||
5919 | static void ufshcd_init_icc_levels(struct ufs_hba *hba) | 5983 | static void ufshcd_init_icc_levels(struct ufs_hba *hba) |
5920 | { | 5984 | { |
5921 | int ret; | 5985 | int ret; |
5922 | int buff_len = QUERY_DESC_POWER_MAX_SIZE; | 5986 | int buff_len = hba->desc_size.pwr_desc; |
5923 | u8 desc_buf[QUERY_DESC_POWER_MAX_SIZE]; | 5987 | u8 desc_buf[hba->desc_size.pwr_desc]; |
5924 | 5988 | ||
5925 | ret = ufshcd_read_power_desc(hba, desc_buf, buff_len); | 5989 | ret = ufshcd_read_power_desc(hba, desc_buf, buff_len); |
5926 | if (ret) { | 5990 | if (ret) { |
@@ -6017,11 +6081,10 @@ static int ufs_get_device_desc(struct ufs_hba *hba, | |||
6017 | { | 6081 | { |
6018 | int err; | 6082 | int err; |
6019 | u8 model_index; | 6083 | u8 model_index; |
6020 | u8 str_desc_buf[QUERY_DESC_STRING_MAX_SIZE + 1] = {0}; | 6084 | u8 str_desc_buf[QUERY_DESC_MAX_SIZE + 1] = {0}; |
6021 | u8 desc_buf[QUERY_DESC_DEVICE_MAX_SIZE]; | 6085 | u8 desc_buf[hba->desc_size.dev_desc]; |
6022 | 6086 | ||
6023 | err = ufshcd_read_device_desc(hba, desc_buf, | 6087 | err = ufshcd_read_device_desc(hba, desc_buf, hba->desc_size.dev_desc); |
6024 | QUERY_DESC_DEVICE_MAX_SIZE); | ||
6025 | if (err) { | 6088 | if (err) { |
6026 | dev_err(hba->dev, "%s: Failed reading Device Desc. err = %d\n", | 6089 | dev_err(hba->dev, "%s: Failed reading Device Desc. err = %d\n", |
6027 | __func__, err); | 6090 | __func__, err); |
@@ -6038,14 +6101,14 @@ static int ufs_get_device_desc(struct ufs_hba *hba, | |||
6038 | model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME]; | 6101 | model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME]; |
6039 | 6102 | ||
6040 | err = ufshcd_read_string_desc(hba, model_index, str_desc_buf, | 6103 | err = ufshcd_read_string_desc(hba, model_index, str_desc_buf, |
6041 | QUERY_DESC_STRING_MAX_SIZE, ASCII_STD); | 6104 | QUERY_DESC_MAX_SIZE, ASCII_STD); |
6042 | if (err) { | 6105 | if (err) { |
6043 | dev_err(hba->dev, "%s: Failed reading Product Name. err = %d\n", | 6106 | dev_err(hba->dev, "%s: Failed reading Product Name. err = %d\n", |
6044 | __func__, err); | 6107 | __func__, err); |
6045 | goto out; | 6108 | goto out; |
6046 | } | 6109 | } |
6047 | 6110 | ||
6048 | str_desc_buf[QUERY_DESC_STRING_MAX_SIZE] = '\0'; | 6111 | str_desc_buf[QUERY_DESC_MAX_SIZE] = '\0'; |
6049 | strlcpy(dev_desc->model, (str_desc_buf + QUERY_DESC_HDR_SIZE), | 6112 | strlcpy(dev_desc->model, (str_desc_buf + QUERY_DESC_HDR_SIZE), |
6050 | min_t(u8, str_desc_buf[QUERY_DESC_LENGTH_OFFSET], | 6113 | min_t(u8, str_desc_buf[QUERY_DESC_LENGTH_OFFSET], |
6051 | MAX_MODEL_LEN)); | 6114 | MAX_MODEL_LEN)); |
@@ -6251,6 +6314,51 @@ static void ufshcd_clear_dbg_ufs_stats(struct ufs_hba *hba) | |||
6251 | hba->req_abort_count = 0; | 6314 | hba->req_abort_count = 0; |
6252 | } | 6315 | } |
6253 | 6316 | ||
6317 | static void ufshcd_init_desc_sizes(struct ufs_hba *hba) | ||
6318 | { | ||
6319 | int err; | ||
6320 | |||
6321 | err = ufshcd_read_desc_length(hba, QUERY_DESC_IDN_DEVICE, 0, | ||
6322 | &hba->desc_size.dev_desc); | ||
6323 | if (err) | ||
6324 | hba->desc_size.dev_desc = QUERY_DESC_DEVICE_DEF_SIZE; | ||
6325 | |||
6326 | err = ufshcd_read_desc_length(hba, QUERY_DESC_IDN_POWER, 0, | ||
6327 | &hba->desc_size.pwr_desc); | ||
6328 | if (err) | ||
6329 | hba->desc_size.pwr_desc = QUERY_DESC_POWER_DEF_SIZE; | ||
6330 | |||
6331 | err = ufshcd_read_desc_length(hba, QUERY_DESC_IDN_INTERCONNECT, 0, | ||
6332 | &hba->desc_size.interc_desc); | ||
6333 | if (err) | ||
6334 | hba->desc_size.interc_desc = QUERY_DESC_INTERCONNECT_DEF_SIZE; | ||
6335 | |||
6336 | err = ufshcd_read_desc_length(hba, QUERY_DESC_IDN_CONFIGURATION, 0, | ||
6337 | &hba->desc_size.conf_desc); | ||
6338 | if (err) | ||
6339 | hba->desc_size.conf_desc = QUERY_DESC_CONFIGURATION_DEF_SIZE; | ||
6340 | |||
6341 | err = ufshcd_read_desc_length(hba, QUERY_DESC_IDN_UNIT, 0, | ||
6342 | &hba->desc_size.unit_desc); | ||
6343 | if (err) | ||
6344 | hba->desc_size.unit_desc = QUERY_DESC_UNIT_DEF_SIZE; | ||
6345 | |||
6346 | err = ufshcd_read_desc_length(hba, QUERY_DESC_IDN_GEOMETRY, 0, | ||
6347 | &hba->desc_size.geom_desc); | ||
6348 | if (err) | ||
6349 | hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE; | ||
6350 | } | ||
6351 | |||
6352 | static void ufshcd_def_desc_sizes(struct ufs_hba *hba) | ||
6353 | { | ||
6354 | hba->desc_size.dev_desc = QUERY_DESC_DEVICE_DEF_SIZE; | ||
6355 | hba->desc_size.pwr_desc = QUERY_DESC_POWER_DEF_SIZE; | ||
6356 | hba->desc_size.interc_desc = QUERY_DESC_INTERCONNECT_DEF_SIZE; | ||
6357 | hba->desc_size.conf_desc = QUERY_DESC_CONFIGURATION_DEF_SIZE; | ||
6358 | hba->desc_size.unit_desc = QUERY_DESC_UNIT_DEF_SIZE; | ||
6359 | hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE; | ||
6360 | } | ||
6361 | |||
6254 | /** | 6362 | /** |
6255 | * ufshcd_probe_hba - probe hba to detect device and initialize | 6363 | * ufshcd_probe_hba - probe hba to detect device and initialize |
6256 | * @hba: per-adapter instance | 6364 | * @hba: per-adapter instance |
@@ -6285,6 +6393,9 @@ static int ufshcd_probe_hba(struct ufs_hba *hba) | |||
6285 | if (ret) | 6393 | if (ret) |
6286 | goto out; | 6394 | goto out; |
6287 | 6395 | ||
6396 | /* Init check for device descriptor sizes */ | ||
6397 | ufshcd_init_desc_sizes(hba); | ||
6398 | |||
6288 | ret = ufs_get_device_desc(hba, &card); | 6399 | ret = ufs_get_device_desc(hba, &card); |
6289 | if (ret) { | 6400 | if (ret) { |
6290 | dev_err(hba->dev, "%s: Failed getting device info. err = %d\n", | 6401 | dev_err(hba->dev, "%s: Failed getting device info. err = %d\n", |
@@ -6320,6 +6431,7 @@ static int ufshcd_probe_hba(struct ufs_hba *hba) | |||
6320 | 6431 | ||
6321 | /* set the state as operational after switching to desired gear */ | 6432 | /* set the state as operational after switching to desired gear */ |
6322 | hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL; | 6433 | hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL; |
6434 | |||
6323 | /* | 6435 | /* |
6324 | * If we are in error handling context or in power management callbacks | 6436 | * If we are in error handling context or in power management callbacks |
6325 | * context, no need to scan the host | 6437 | * context, no need to scan the host |
@@ -7774,6 +7886,9 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) | |||
7774 | hba->mmio_base = mmio_base; | 7886 | hba->mmio_base = mmio_base; |
7775 | hba->irq = irq; | 7887 | hba->irq = irq; |
7776 | 7888 | ||
7889 | /* Set descriptor lengths to specification defaults */ | ||
7890 | ufshcd_def_desc_sizes(hba); | ||
7891 | |||
7777 | err = ufshcd_hba_init(hba); | 7892 | err = ufshcd_hba_init(hba); |
7778 | if (err) | 7893 | if (err) |
7779 | goto out_error; | 7894 | goto out_error; |
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 7630600217a2..cdc8bd05f7df 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h | |||
@@ -220,6 +220,15 @@ struct ufs_dev_cmd { | |||
220 | struct ufs_query query; | 220 | struct ufs_query query; |
221 | }; | 221 | }; |
222 | 222 | ||
223 | struct ufs_desc_size { | ||
224 | int dev_desc; | ||
225 | int pwr_desc; | ||
226 | int geom_desc; | ||
227 | int interc_desc; | ||
228 | int unit_desc; | ||
229 | int conf_desc; | ||
230 | }; | ||
231 | |||
223 | /** | 232 | /** |
224 | * struct ufs_clk_info - UFS clock related info | 233 | * struct ufs_clk_info - UFS clock related info |
225 | * @list: list headed by hba->clk_list_head | 234 | * @list: list headed by hba->clk_list_head |
@@ -483,6 +492,7 @@ struct ufs_stats { | |||
483 | * @clk_list_head: UFS host controller clocks list node head | 492 | * @clk_list_head: UFS host controller clocks list node head |
484 | * @pwr_info: holds current power mode | 493 | * @pwr_info: holds current power mode |
485 | * @max_pwr_info: keeps the device max valid pwm | 494 | * @max_pwr_info: keeps the device max valid pwm |
495 | * @desc_size: descriptor sizes reported by device | ||
486 | * @urgent_bkops_lvl: keeps track of urgent bkops level for device | 496 | * @urgent_bkops_lvl: keeps track of urgent bkops level for device |
487 | * @is_urgent_bkops_lvl_checked: keeps track if the urgent bkops level for | 497 | * @is_urgent_bkops_lvl_checked: keeps track if the urgent bkops level for |
488 | * device is known or not. | 498 | * device is known or not. |
@@ -666,6 +676,7 @@ struct ufs_hba { | |||
666 | bool is_urgent_bkops_lvl_checked; | 676 | bool is_urgent_bkops_lvl_checked; |
667 | 677 | ||
668 | struct rw_semaphore clk_scaling_lock; | 678 | struct rw_semaphore clk_scaling_lock; |
679 | struct ufs_desc_size desc_size; | ||
669 | }; | 680 | }; |
670 | 681 | ||
671 | /* Returns true if clocks can be gated. Otherwise false */ | 682 | /* Returns true if clocks can be gated. Otherwise false */ |
@@ -832,6 +843,10 @@ int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, | |||
832 | enum flag_idn idn, bool *flag_res); | 843 | enum flag_idn idn, bool *flag_res); |
833 | int ufshcd_hold(struct ufs_hba *hba, bool async); | 844 | int ufshcd_hold(struct ufs_hba *hba, bool async); |
834 | void ufshcd_release(struct ufs_hba *hba); | 845 | void ufshcd_release(struct ufs_hba *hba); |
846 | |||
847 | int ufshcd_map_desc_id_to_length(struct ufs_hba *hba, enum desc_idn desc_id, | ||
848 | int *desc_length); | ||
849 | |||
835 | u32 ufshcd_get_local_unipro_ver(struct ufs_hba *hba); | 850 | u32 ufshcd_get_local_unipro_ver(struct ufs_hba *hba); |
836 | 851 | ||
837 | /* Wrapper functions for safely calling variant operations */ | 852 | /* Wrapper functions for safely calling variant operations */ |
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index ef474a748744..c374e3b5c678 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c | |||
@@ -1487,7 +1487,7 @@ static int pvscsi_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1487 | irq_flag &= ~PCI_IRQ_MSI; | 1487 | irq_flag &= ~PCI_IRQ_MSI; |
1488 | 1488 | ||
1489 | error = pci_alloc_irq_vectors(adapter->dev, 1, 1, irq_flag); | 1489 | error = pci_alloc_irq_vectors(adapter->dev, 1, 1, irq_flag); |
1490 | if (error) | 1490 | if (error < 0) |
1491 | goto out_reset_adapter; | 1491 | goto out_reset_adapter; |
1492 | 1492 | ||
1493 | adapter->use_req_threshold = pvscsi_setup_req_threshold(adapter, true); | 1493 | adapter->use_req_threshold = pvscsi_setup_req_threshold(adapter, true); |
diff --git a/drivers/staging/lustre/lnet/lnet/lib-socket.c b/drivers/staging/lustre/lnet/lnet/lib-socket.c index b7b87ecefcdf..9fca8d225ee0 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-socket.c +++ b/drivers/staging/lustre/lnet/lnet/lib-socket.c | |||
@@ -532,7 +532,7 @@ lnet_sock_accept(struct socket **newsockp, struct socket *sock) | |||
532 | 532 | ||
533 | newsock->ops = sock->ops; | 533 | newsock->ops = sock->ops; |
534 | 534 | ||
535 | rc = sock->ops->accept(sock, newsock, O_NONBLOCK); | 535 | rc = sock->ops->accept(sock, newsock, O_NONBLOCK, false); |
536 | if (rc == -EAGAIN) { | 536 | if (rc == -EAGAIN) { |
537 | /* Nothing ready, so wait for activity */ | 537 | /* Nothing ready, so wait for activity */ |
538 | init_waitqueue_entry(&wait, current); | 538 | init_waitqueue_entry(&wait, current); |
@@ -540,7 +540,7 @@ lnet_sock_accept(struct socket **newsockp, struct socket *sock) | |||
540 | set_current_state(TASK_INTERRUPTIBLE); | 540 | set_current_state(TASK_INTERRUPTIBLE); |
541 | schedule(); | 541 | schedule(); |
542 | remove_wait_queue(sk_sleep(sock->sk), &wait); | 542 | remove_wait_queue(sk_sleep(sock->sk), &wait); |
543 | rc = sock->ops->accept(sock, newsock, O_NONBLOCK); | 543 | rc = sock->ops->accept(sock, newsock, O_NONBLOCK, false); |
544 | } | 544 | } |
545 | 545 | ||
546 | if (rc) | 546 | if (rc) |
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index f5e330099bfc..fd7c16a7ca6e 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include "target_core_ua.h" | 43 | #include "target_core_ua.h" |
44 | 44 | ||
45 | static sense_reason_t core_alua_check_transition(int state, int valid, | 45 | static sense_reason_t core_alua_check_transition(int state, int valid, |
46 | int *primary); | 46 | int *primary, int explicit); |
47 | static int core_alua_set_tg_pt_secondary_state( | 47 | static int core_alua_set_tg_pt_secondary_state( |
48 | struct se_lun *lun, int explicit, int offline); | 48 | struct se_lun *lun, int explicit, int offline); |
49 | 49 | ||
@@ -335,8 +335,8 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
335 | * the state is a primary or secondary target port asymmetric | 335 | * the state is a primary or secondary target port asymmetric |
336 | * access state. | 336 | * access state. |
337 | */ | 337 | */ |
338 | rc = core_alua_check_transition(alua_access_state, | 338 | rc = core_alua_check_transition(alua_access_state, valid_states, |
339 | valid_states, &primary); | 339 | &primary, 1); |
340 | if (rc) { | 340 | if (rc) { |
341 | /* | 341 | /* |
342 | * If the SET TARGET PORT GROUPS attempts to establish | 342 | * If the SET TARGET PORT GROUPS attempts to establish |
@@ -691,7 +691,7 @@ target_alua_state_check(struct se_cmd *cmd) | |||
691 | 691 | ||
692 | if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) | 692 | if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) |
693 | return 0; | 693 | return 0; |
694 | if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) | 694 | if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_ALUA) |
695 | return 0; | 695 | return 0; |
696 | 696 | ||
697 | /* | 697 | /* |
@@ -762,7 +762,7 @@ target_alua_state_check(struct se_cmd *cmd) | |||
762 | * Check implicit and explicit ALUA state change request. | 762 | * Check implicit and explicit ALUA state change request. |
763 | */ | 763 | */ |
764 | static sense_reason_t | 764 | static sense_reason_t |
765 | core_alua_check_transition(int state, int valid, int *primary) | 765 | core_alua_check_transition(int state, int valid, int *primary, int explicit) |
766 | { | 766 | { |
767 | /* | 767 | /* |
768 | * OPTIMIZED, NON-OPTIMIZED, STANDBY and UNAVAILABLE are | 768 | * OPTIMIZED, NON-OPTIMIZED, STANDBY and UNAVAILABLE are |
@@ -804,11 +804,14 @@ core_alua_check_transition(int state, int valid, int *primary) | |||
804 | *primary = 0; | 804 | *primary = 0; |
805 | break; | 805 | break; |
806 | case ALUA_ACCESS_STATE_TRANSITION: | 806 | case ALUA_ACCESS_STATE_TRANSITION: |
807 | /* | 807 | if (!(valid & ALUA_T_SUP) || explicit) |
808 | * Transitioning is set internally, and | 808 | /* |
809 | * cannot be selected manually. | 809 | * Transitioning is set internally and by tcmu daemon, |
810 | */ | 810 | * and cannot be selected through a STPG. |
811 | goto not_supported; | 811 | */ |
812 | goto not_supported; | ||
813 | *primary = 0; | ||
814 | break; | ||
812 | default: | 815 | default: |
813 | pr_err("Unknown ALUA access state: 0x%02x\n", state); | 816 | pr_err("Unknown ALUA access state: 0x%02x\n", state); |
814 | return TCM_INVALID_PARAMETER_LIST; | 817 | return TCM_INVALID_PARAMETER_LIST; |
@@ -1013,7 +1016,7 @@ static void core_alua_queue_state_change_ua(struct t10_alua_tg_pt_gp *tg_pt_gp) | |||
1013 | static void core_alua_do_transition_tg_pt_work(struct work_struct *work) | 1016 | static void core_alua_do_transition_tg_pt_work(struct work_struct *work) |
1014 | { | 1017 | { |
1015 | struct t10_alua_tg_pt_gp *tg_pt_gp = container_of(work, | 1018 | struct t10_alua_tg_pt_gp *tg_pt_gp = container_of(work, |
1016 | struct t10_alua_tg_pt_gp, tg_pt_gp_transition_work.work); | 1019 | struct t10_alua_tg_pt_gp, tg_pt_gp_transition_work); |
1017 | struct se_device *dev = tg_pt_gp->tg_pt_gp_dev; | 1020 | struct se_device *dev = tg_pt_gp->tg_pt_gp_dev; |
1018 | bool explicit = (tg_pt_gp->tg_pt_gp_alua_access_status == | 1021 | bool explicit = (tg_pt_gp->tg_pt_gp_alua_access_status == |
1019 | ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG); | 1022 | ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG); |
@@ -1070,32 +1073,19 @@ static int core_alua_do_transition_tg_pt( | |||
1070 | if (atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state) == new_state) | 1073 | if (atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state) == new_state) |
1071 | return 0; | 1074 | return 0; |
1072 | 1075 | ||
1073 | if (new_state == ALUA_ACCESS_STATE_TRANSITION) | 1076 | if (explicit && new_state == ALUA_ACCESS_STATE_TRANSITION) |
1074 | return -EAGAIN; | 1077 | return -EAGAIN; |
1075 | 1078 | ||
1076 | /* | 1079 | /* |
1077 | * Flush any pending transitions | 1080 | * Flush any pending transitions |
1078 | */ | 1081 | */ |
1079 | if (!explicit && tg_pt_gp->tg_pt_gp_implicit_trans_secs && | 1082 | if (!explicit) |
1080 | atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state) == | 1083 | flush_work(&tg_pt_gp->tg_pt_gp_transition_work); |
1081 | ALUA_ACCESS_STATE_TRANSITION) { | ||
1082 | /* Just in case */ | ||
1083 | tg_pt_gp->tg_pt_gp_alua_pending_state = new_state; | ||
1084 | tg_pt_gp->tg_pt_gp_transition_complete = &wait; | ||
1085 | flush_delayed_work(&tg_pt_gp->tg_pt_gp_transition_work); | ||
1086 | wait_for_completion(&wait); | ||
1087 | tg_pt_gp->tg_pt_gp_transition_complete = NULL; | ||
1088 | return 0; | ||
1089 | } | ||
1090 | 1084 | ||
1091 | /* | 1085 | /* |
1092 | * Save the old primary ALUA access state, and set the current state | 1086 | * Save the old primary ALUA access state, and set the current state |
1093 | * to ALUA_ACCESS_STATE_TRANSITION. | 1087 | * to ALUA_ACCESS_STATE_TRANSITION. |
1094 | */ | 1088 | */ |
1095 | tg_pt_gp->tg_pt_gp_alua_previous_state = | ||
1096 | atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state); | ||
1097 | tg_pt_gp->tg_pt_gp_alua_pending_state = new_state; | ||
1098 | |||
1099 | atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state, | 1089 | atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state, |
1100 | ALUA_ACCESS_STATE_TRANSITION); | 1090 | ALUA_ACCESS_STATE_TRANSITION); |
1101 | tg_pt_gp->tg_pt_gp_alua_access_status = (explicit) ? | 1091 | tg_pt_gp->tg_pt_gp_alua_access_status = (explicit) ? |
@@ -1104,6 +1094,13 @@ static int core_alua_do_transition_tg_pt( | |||
1104 | 1094 | ||
1105 | core_alua_queue_state_change_ua(tg_pt_gp); | 1095 | core_alua_queue_state_change_ua(tg_pt_gp); |
1106 | 1096 | ||
1097 | if (new_state == ALUA_ACCESS_STATE_TRANSITION) | ||
1098 | return 0; | ||
1099 | |||
1100 | tg_pt_gp->tg_pt_gp_alua_previous_state = | ||
1101 | atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state); | ||
1102 | tg_pt_gp->tg_pt_gp_alua_pending_state = new_state; | ||
1103 | |||
1107 | /* | 1104 | /* |
1108 | * Check for the optional ALUA primary state transition delay | 1105 | * Check for the optional ALUA primary state transition delay |
1109 | */ | 1106 | */ |
@@ -1117,17 +1114,9 @@ static int core_alua_do_transition_tg_pt( | |||
1117 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); | 1114 | atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); |
1118 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); | 1115 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1119 | 1116 | ||
1120 | if (!explicit && tg_pt_gp->tg_pt_gp_implicit_trans_secs) { | 1117 | schedule_work(&tg_pt_gp->tg_pt_gp_transition_work); |
1121 | unsigned long transition_tmo; | 1118 | if (explicit) { |
1122 | |||
1123 | transition_tmo = tg_pt_gp->tg_pt_gp_implicit_trans_secs * HZ; | ||
1124 | queue_delayed_work(tg_pt_gp->tg_pt_gp_dev->tmr_wq, | ||
1125 | &tg_pt_gp->tg_pt_gp_transition_work, | ||
1126 | transition_tmo); | ||
1127 | } else { | ||
1128 | tg_pt_gp->tg_pt_gp_transition_complete = &wait; | 1119 | tg_pt_gp->tg_pt_gp_transition_complete = &wait; |
1129 | queue_delayed_work(tg_pt_gp->tg_pt_gp_dev->tmr_wq, | ||
1130 | &tg_pt_gp->tg_pt_gp_transition_work, 0); | ||
1131 | wait_for_completion(&wait); | 1120 | wait_for_completion(&wait); |
1132 | tg_pt_gp->tg_pt_gp_transition_complete = NULL; | 1121 | tg_pt_gp->tg_pt_gp_transition_complete = NULL; |
1133 | } | 1122 | } |
@@ -1149,8 +1138,12 @@ int core_alua_do_port_transition( | |||
1149 | struct t10_alua_tg_pt_gp *tg_pt_gp; | 1138 | struct t10_alua_tg_pt_gp *tg_pt_gp; |
1150 | int primary, valid_states, rc = 0; | 1139 | int primary, valid_states, rc = 0; |
1151 | 1140 | ||
1141 | if (l_dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_ALUA) | ||
1142 | return -ENODEV; | ||
1143 | |||
1152 | valid_states = l_tg_pt_gp->tg_pt_gp_alua_supported_states; | 1144 | valid_states = l_tg_pt_gp->tg_pt_gp_alua_supported_states; |
1153 | if (core_alua_check_transition(new_state, valid_states, &primary) != 0) | 1145 | if (core_alua_check_transition(new_state, valid_states, &primary, |
1146 | explicit) != 0) | ||
1154 | return -EINVAL; | 1147 | return -EINVAL; |
1155 | 1148 | ||
1156 | local_lu_gp_mem = l_dev->dev_alua_lu_gp_mem; | 1149 | local_lu_gp_mem = l_dev->dev_alua_lu_gp_mem; |
@@ -1695,8 +1688,8 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(struct se_device *dev, | |||
1695 | mutex_init(&tg_pt_gp->tg_pt_gp_md_mutex); | 1688 | mutex_init(&tg_pt_gp->tg_pt_gp_md_mutex); |
1696 | spin_lock_init(&tg_pt_gp->tg_pt_gp_lock); | 1689 | spin_lock_init(&tg_pt_gp->tg_pt_gp_lock); |
1697 | atomic_set(&tg_pt_gp->tg_pt_gp_ref_cnt, 0); | 1690 | atomic_set(&tg_pt_gp->tg_pt_gp_ref_cnt, 0); |
1698 | INIT_DELAYED_WORK(&tg_pt_gp->tg_pt_gp_transition_work, | 1691 | INIT_WORK(&tg_pt_gp->tg_pt_gp_transition_work, |
1699 | core_alua_do_transition_tg_pt_work); | 1692 | core_alua_do_transition_tg_pt_work); |
1700 | tg_pt_gp->tg_pt_gp_dev = dev; | 1693 | tg_pt_gp->tg_pt_gp_dev = dev; |
1701 | atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state, | 1694 | atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state, |
1702 | ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED); | 1695 | ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED); |
@@ -1804,7 +1797,7 @@ void core_alua_free_tg_pt_gp( | |||
1804 | dev->t10_alua.alua_tg_pt_gps_counter--; | 1797 | dev->t10_alua.alua_tg_pt_gps_counter--; |
1805 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); | 1798 | spin_unlock(&dev->t10_alua.tg_pt_gps_lock); |
1806 | 1799 | ||
1807 | flush_delayed_work(&tg_pt_gp->tg_pt_gp_transition_work); | 1800 | flush_work(&tg_pt_gp->tg_pt_gp_transition_work); |
1808 | 1801 | ||
1809 | /* | 1802 | /* |
1810 | * Allow a struct t10_alua_tg_pt_gp_member * referenced by | 1803 | * Allow a struct t10_alua_tg_pt_gp_member * referenced by |
@@ -1973,7 +1966,7 @@ ssize_t core_alua_store_tg_pt_gp_info( | |||
1973 | unsigned char buf[TG_PT_GROUP_NAME_BUF]; | 1966 | unsigned char buf[TG_PT_GROUP_NAME_BUF]; |
1974 | int move = 0; | 1967 | int move = 0; |
1975 | 1968 | ||
1976 | if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH || | 1969 | if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_ALUA || |
1977 | (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) | 1970 | (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) |
1978 | return -ENODEV; | 1971 | return -ENODEV; |
1979 | 1972 | ||
@@ -2230,7 +2223,7 @@ ssize_t core_alua_store_offline_bit( | |||
2230 | unsigned long tmp; | 2223 | unsigned long tmp; |
2231 | int ret; | 2224 | int ret; |
2232 | 2225 | ||
2233 | if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH || | 2226 | if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_ALUA || |
2234 | (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) | 2227 | (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) |
2235 | return -ENODEV; | 2228 | return -ENODEV; |
2236 | 2229 | ||
@@ -2316,7 +2309,8 @@ ssize_t core_alua_store_secondary_write_metadata( | |||
2316 | 2309 | ||
2317 | int core_setup_alua(struct se_device *dev) | 2310 | int core_setup_alua(struct se_device *dev) |
2318 | { | 2311 | { |
2319 | if (!(dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) && | 2312 | if (!(dev->transport->transport_flags & |
2313 | TRANSPORT_FLAG_PASSTHROUGH_ALUA) && | ||
2320 | !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) { | 2314 | !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) { |
2321 | struct t10_alua_lu_gp_member *lu_gp_mem; | 2315 | struct t10_alua_lu_gp_member *lu_gp_mem; |
2322 | 2316 | ||
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 54b36c9835be..38b5025e4c7a 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
@@ -421,6 +421,10 @@ static int target_fabric_tf_ops_check(const struct target_core_fabric_ops *tfo) | |||
421 | pr_err("Missing tfo->aborted_task()\n"); | 421 | pr_err("Missing tfo->aborted_task()\n"); |
422 | return -EINVAL; | 422 | return -EINVAL; |
423 | } | 423 | } |
424 | if (!tfo->check_stop_free) { | ||
425 | pr_err("Missing tfo->check_stop_free()\n"); | ||
426 | return -EINVAL; | ||
427 | } | ||
424 | /* | 428 | /* |
425 | * We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn() | 429 | * We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn() |
426 | * tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in | 430 | * tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in |
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index a8f8e53f2f57..94cda7991e80 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c | |||
@@ -154,7 +154,7 @@ static void pscsi_tape_read_blocksize(struct se_device *dev, | |||
154 | 154 | ||
155 | buf = kzalloc(12, GFP_KERNEL); | 155 | buf = kzalloc(12, GFP_KERNEL); |
156 | if (!buf) | 156 | if (!buf) |
157 | return; | 157 | goto out_free; |
158 | 158 | ||
159 | memset(cdb, 0, MAX_COMMAND_SIZE); | 159 | memset(cdb, 0, MAX_COMMAND_SIZE); |
160 | cdb[0] = MODE_SENSE; | 160 | cdb[0] = MODE_SENSE; |
@@ -169,9 +169,10 @@ static void pscsi_tape_read_blocksize(struct se_device *dev, | |||
169 | * If MODE_SENSE still returns zero, set the default value to 1024. | 169 | * If MODE_SENSE still returns zero, set the default value to 1024. |
170 | */ | 170 | */ |
171 | sdev->sector_size = (buf[9] << 16) | (buf[10] << 8) | (buf[11]); | 171 | sdev->sector_size = (buf[9] << 16) | (buf[10] << 8) | (buf[11]); |
172 | out_free: | ||
172 | if (!sdev->sector_size) | 173 | if (!sdev->sector_size) |
173 | sdev->sector_size = 1024; | 174 | sdev->sector_size = 1024; |
174 | out_free: | 175 | |
175 | kfree(buf); | 176 | kfree(buf); |
176 | } | 177 | } |
177 | 178 | ||
@@ -314,9 +315,10 @@ static int pscsi_add_device_to_list(struct se_device *dev, | |||
314 | sd->lun, sd->queue_depth); | 315 | sd->lun, sd->queue_depth); |
315 | } | 316 | } |
316 | 317 | ||
317 | dev->dev_attrib.hw_block_size = sd->sector_size; | 318 | dev->dev_attrib.hw_block_size = |
319 | min_not_zero((int)sd->sector_size, 512); | ||
318 | dev->dev_attrib.hw_max_sectors = | 320 | dev->dev_attrib.hw_max_sectors = |
319 | min_t(int, sd->host->max_sectors, queue_max_hw_sectors(q)); | 321 | min_not_zero(sd->host->max_sectors, queue_max_hw_sectors(q)); |
320 | dev->dev_attrib.hw_queue_depth = sd->queue_depth; | 322 | dev->dev_attrib.hw_queue_depth = sd->queue_depth; |
321 | 323 | ||
322 | /* | 324 | /* |
@@ -339,8 +341,10 @@ static int pscsi_add_device_to_list(struct se_device *dev, | |||
339 | /* | 341 | /* |
340 | * For TYPE_TAPE, attempt to determine blocksize with MODE_SENSE. | 342 | * For TYPE_TAPE, attempt to determine blocksize with MODE_SENSE. |
341 | */ | 343 | */ |
342 | if (sd->type == TYPE_TAPE) | 344 | if (sd->type == TYPE_TAPE) { |
343 | pscsi_tape_read_blocksize(dev, sd); | 345 | pscsi_tape_read_blocksize(dev, sd); |
346 | dev->dev_attrib.hw_block_size = sd->sector_size; | ||
347 | } | ||
344 | return 0; | 348 | return 0; |
345 | } | 349 | } |
346 | 350 | ||
@@ -406,7 +410,7 @@ static int pscsi_create_type_disk(struct se_device *dev, struct scsi_device *sd) | |||
406 | /* | 410 | /* |
407 | * Called with struct Scsi_Host->host_lock called. | 411 | * Called with struct Scsi_Host->host_lock called. |
408 | */ | 412 | */ |
409 | static int pscsi_create_type_rom(struct se_device *dev, struct scsi_device *sd) | 413 | static int pscsi_create_type_nondisk(struct se_device *dev, struct scsi_device *sd) |
410 | __releases(sh->host_lock) | 414 | __releases(sh->host_lock) |
411 | { | 415 | { |
412 | struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; | 416 | struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; |
@@ -433,28 +437,6 @@ static int pscsi_create_type_rom(struct se_device *dev, struct scsi_device *sd) | |||
433 | return 0; | 437 | return 0; |
434 | } | 438 | } |
435 | 439 | ||
436 | /* | ||
437 | * Called with struct Scsi_Host->host_lock called. | ||
438 | */ | ||
439 | static int pscsi_create_type_other(struct se_device *dev, | ||
440 | struct scsi_device *sd) | ||
441 | __releases(sh->host_lock) | ||
442 | { | ||
443 | struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; | ||
444 | struct Scsi_Host *sh = sd->host; | ||
445 | int ret; | ||
446 | |||
447 | spin_unlock_irq(sh->host_lock); | ||
448 | ret = pscsi_add_device_to_list(dev, sd); | ||
449 | if (ret) | ||
450 | return ret; | ||
451 | |||
452 | pr_debug("CORE_PSCSI[%d] - Added Type: %s for %d:%d:%d:%llu\n", | ||
453 | phv->phv_host_id, scsi_device_type(sd->type), sh->host_no, | ||
454 | sd->channel, sd->id, sd->lun); | ||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | static int pscsi_configure_device(struct se_device *dev) | 440 | static int pscsi_configure_device(struct se_device *dev) |
459 | { | 441 | { |
460 | struct se_hba *hba = dev->se_hba; | 442 | struct se_hba *hba = dev->se_hba; |
@@ -542,11 +524,8 @@ static int pscsi_configure_device(struct se_device *dev) | |||
542 | case TYPE_DISK: | 524 | case TYPE_DISK: |
543 | ret = pscsi_create_type_disk(dev, sd); | 525 | ret = pscsi_create_type_disk(dev, sd); |
544 | break; | 526 | break; |
545 | case TYPE_ROM: | ||
546 | ret = pscsi_create_type_rom(dev, sd); | ||
547 | break; | ||
548 | default: | 527 | default: |
549 | ret = pscsi_create_type_other(dev, sd); | 528 | ret = pscsi_create_type_nondisk(dev, sd); |
550 | break; | 529 | break; |
551 | } | 530 | } |
552 | 531 | ||
@@ -611,8 +590,7 @@ static void pscsi_free_device(struct se_device *dev) | |||
611 | else if (pdv->pdv_lld_host) | 590 | else if (pdv->pdv_lld_host) |
612 | scsi_host_put(pdv->pdv_lld_host); | 591 | scsi_host_put(pdv->pdv_lld_host); |
613 | 592 | ||
614 | if ((sd->type == TYPE_DISK) || (sd->type == TYPE_ROM)) | 593 | scsi_device_put(sd); |
615 | scsi_device_put(sd); | ||
616 | 594 | ||
617 | pdv->pdv_sd = NULL; | 595 | pdv->pdv_sd = NULL; |
618 | } | 596 | } |
@@ -1064,7 +1042,6 @@ static sector_t pscsi_get_blocks(struct se_device *dev) | |||
1064 | if (pdv->pdv_bd && pdv->pdv_bd->bd_part) | 1042 | if (pdv->pdv_bd && pdv->pdv_bd->bd_part) |
1065 | return pdv->pdv_bd->bd_part->nr_sects; | 1043 | return pdv->pdv_bd->bd_part->nr_sects; |
1066 | 1044 | ||
1067 | dump_stack(); | ||
1068 | return 0; | 1045 | return 0; |
1069 | } | 1046 | } |
1070 | 1047 | ||
@@ -1103,7 +1080,8 @@ static void pscsi_req_done(struct request *req, int uptodate) | |||
1103 | static const struct target_backend_ops pscsi_ops = { | 1080 | static const struct target_backend_ops pscsi_ops = { |
1104 | .name = "pscsi", | 1081 | .name = "pscsi", |
1105 | .owner = THIS_MODULE, | 1082 | .owner = THIS_MODULE, |
1106 | .transport_flags = TRANSPORT_FLAG_PASSTHROUGH, | 1083 | .transport_flags = TRANSPORT_FLAG_PASSTHROUGH | |
1084 | TRANSPORT_FLAG_PASSTHROUGH_ALUA, | ||
1107 | .attach_hba = pscsi_attach_hba, | 1085 | .attach_hba = pscsi_attach_hba, |
1108 | .detach_hba = pscsi_detach_hba, | 1086 | .detach_hba = pscsi_detach_hba, |
1109 | .pmode_enable_hba = pscsi_pmode_enable_hba, | 1087 | .pmode_enable_hba = pscsi_pmode_enable_hba, |
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 68d8aef7ab78..c194063f169b 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -1105,9 +1105,15 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
1105 | return ret; | 1105 | return ret; |
1106 | break; | 1106 | break; |
1107 | case VERIFY: | 1107 | case VERIFY: |
1108 | case VERIFY_16: | ||
1108 | size = 0; | 1109 | size = 0; |
1109 | sectors = transport_get_sectors_10(cdb); | 1110 | if (cdb[0] == VERIFY) { |
1110 | cmd->t_task_lba = transport_lba_32(cdb); | 1111 | sectors = transport_get_sectors_10(cdb); |
1112 | cmd->t_task_lba = transport_lba_32(cdb); | ||
1113 | } else { | ||
1114 | sectors = transport_get_sectors_16(cdb); | ||
1115 | cmd->t_task_lba = transport_lba_64(cdb); | ||
1116 | } | ||
1111 | cmd->execute_cmd = sbc_emulate_noop; | 1117 | cmd->execute_cmd = sbc_emulate_noop; |
1112 | goto check_lba; | 1118 | goto check_lba; |
1113 | case REZERO_UNIT: | 1119 | case REZERO_UNIT: |
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index c0dbfa016575..6fb191914f45 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c | |||
@@ -602,7 +602,8 @@ int core_tpg_add_lun( | |||
602 | if (ret) | 602 | if (ret) |
603 | goto out_kill_ref; | 603 | goto out_kill_ref; |
604 | 604 | ||
605 | if (!(dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) && | 605 | if (!(dev->transport->transport_flags & |
606 | TRANSPORT_FLAG_PASSTHROUGH_ALUA) && | ||
606 | !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) | 607 | !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) |
607 | target_attach_tg_pt_gp(lun, dev->t10_alua.default_tg_pt_gp); | 608 | target_attach_tg_pt_gp(lun, dev->t10_alua.default_tg_pt_gp); |
608 | 609 | ||
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 434d9d693989..b1a3cdb29468 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -636,8 +636,7 @@ static int transport_cmd_check_stop_to_fabric(struct se_cmd *cmd) | |||
636 | * Fabric modules are expected to return '1' here if the se_cmd being | 636 | * Fabric modules are expected to return '1' here if the se_cmd being |
637 | * passed is released at this point, or zero if not being released. | 637 | * passed is released at this point, or zero if not being released. |
638 | */ | 638 | */ |
639 | return cmd->se_tfo->check_stop_free ? cmd->se_tfo->check_stop_free(cmd) | 639 | return cmd->se_tfo->check_stop_free(cmd); |
640 | : 0; | ||
641 | } | 640 | } |
642 | 641 | ||
643 | static void transport_lun_remove_cmd(struct se_cmd *cmd) | 642 | static void transport_lun_remove_cmd(struct se_cmd *cmd) |
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index c3adefe95e50..c6874c38a10b 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/stringify.h> | 28 | #include <linux/stringify.h> |
29 | #include <linux/bitops.h> | 29 | #include <linux/bitops.h> |
30 | #include <linux/highmem.h> | 30 | #include <linux/highmem.h> |
31 | #include <linux/configfs.h> | ||
31 | #include <net/genetlink.h> | 32 | #include <net/genetlink.h> |
32 | #include <scsi/scsi_common.h> | 33 | #include <scsi/scsi_common.h> |
33 | #include <scsi/scsi_proto.h> | 34 | #include <scsi/scsi_proto.h> |
@@ -112,6 +113,7 @@ struct tcmu_dev { | |||
112 | spinlock_t commands_lock; | 113 | spinlock_t commands_lock; |
113 | 114 | ||
114 | struct timer_list timeout; | 115 | struct timer_list timeout; |
116 | unsigned int cmd_time_out; | ||
115 | 117 | ||
116 | char dev_config[TCMU_CONFIG_LEN]; | 118 | char dev_config[TCMU_CONFIG_LEN]; |
117 | }; | 119 | }; |
@@ -172,7 +174,9 @@ static struct tcmu_cmd *tcmu_alloc_cmd(struct se_cmd *se_cmd) | |||
172 | 174 | ||
173 | tcmu_cmd->se_cmd = se_cmd; | 175 | tcmu_cmd->se_cmd = se_cmd; |
174 | tcmu_cmd->tcmu_dev = udev; | 176 | tcmu_cmd->tcmu_dev = udev; |
175 | tcmu_cmd->deadline = jiffies + msecs_to_jiffies(TCMU_TIME_OUT); | 177 | if (udev->cmd_time_out) |
178 | tcmu_cmd->deadline = jiffies + | ||
179 | msecs_to_jiffies(udev->cmd_time_out); | ||
176 | 180 | ||
177 | idr_preload(GFP_KERNEL); | 181 | idr_preload(GFP_KERNEL); |
178 | spin_lock_irq(&udev->commands_lock); | 182 | spin_lock_irq(&udev->commands_lock); |
@@ -451,7 +455,11 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd) | |||
451 | 455 | ||
452 | pr_debug("sleeping for ring space\n"); | 456 | pr_debug("sleeping for ring space\n"); |
453 | spin_unlock_irq(&udev->cmdr_lock); | 457 | spin_unlock_irq(&udev->cmdr_lock); |
454 | ret = schedule_timeout(msecs_to_jiffies(TCMU_TIME_OUT)); | 458 | if (udev->cmd_time_out) |
459 | ret = schedule_timeout( | ||
460 | msecs_to_jiffies(udev->cmd_time_out)); | ||
461 | else | ||
462 | ret = schedule_timeout(msecs_to_jiffies(TCMU_TIME_OUT)); | ||
455 | finish_wait(&udev->wait_cmdr, &__wait); | 463 | finish_wait(&udev->wait_cmdr, &__wait); |
456 | if (!ret) { | 464 | if (!ret) { |
457 | pr_warn("tcmu: command timed out\n"); | 465 | pr_warn("tcmu: command timed out\n"); |
@@ -526,8 +534,9 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd) | |||
526 | /* TODO: only if FLUSH and FUA? */ | 534 | /* TODO: only if FLUSH and FUA? */ |
527 | uio_event_notify(&udev->uio_info); | 535 | uio_event_notify(&udev->uio_info); |
528 | 536 | ||
529 | mod_timer(&udev->timeout, | 537 | if (udev->cmd_time_out) |
530 | round_jiffies_up(jiffies + msecs_to_jiffies(TCMU_TIME_OUT))); | 538 | mod_timer(&udev->timeout, round_jiffies_up(jiffies + |
539 | msecs_to_jiffies(udev->cmd_time_out))); | ||
531 | 540 | ||
532 | return TCM_NO_SENSE; | 541 | return TCM_NO_SENSE; |
533 | } | 542 | } |
@@ -742,6 +751,7 @@ static struct se_device *tcmu_alloc_device(struct se_hba *hba, const char *name) | |||
742 | } | 751 | } |
743 | 752 | ||
744 | udev->hba = hba; | 753 | udev->hba = hba; |
754 | udev->cmd_time_out = TCMU_TIME_OUT; | ||
745 | 755 | ||
746 | init_waitqueue_head(&udev->wait_cmdr); | 756 | init_waitqueue_head(&udev->wait_cmdr); |
747 | spin_lock_init(&udev->cmdr_lock); | 757 | spin_lock_init(&udev->cmdr_lock); |
@@ -960,7 +970,8 @@ static int tcmu_configure_device(struct se_device *dev) | |||
960 | if (dev->dev_attrib.hw_block_size == 0) | 970 | if (dev->dev_attrib.hw_block_size == 0) |
961 | dev->dev_attrib.hw_block_size = 512; | 971 | dev->dev_attrib.hw_block_size = 512; |
962 | /* Other attributes can be configured in userspace */ | 972 | /* Other attributes can be configured in userspace */ |
963 | dev->dev_attrib.hw_max_sectors = 128; | 973 | if (!dev->dev_attrib.hw_max_sectors) |
974 | dev->dev_attrib.hw_max_sectors = 128; | ||
964 | dev->dev_attrib.hw_queue_depth = 128; | 975 | dev->dev_attrib.hw_queue_depth = 128; |
965 | 976 | ||
966 | ret = tcmu_netlink_event(TCMU_CMD_ADDED_DEVICE, udev->uio_info.name, | 977 | ret = tcmu_netlink_event(TCMU_CMD_ADDED_DEVICE, udev->uio_info.name, |
@@ -997,6 +1008,11 @@ static void tcmu_dev_call_rcu(struct rcu_head *p) | |||
997 | kfree(udev); | 1008 | kfree(udev); |
998 | } | 1009 | } |
999 | 1010 | ||
1011 | static bool tcmu_dev_configured(struct tcmu_dev *udev) | ||
1012 | { | ||
1013 | return udev->uio_info.uio_dev ? true : false; | ||
1014 | } | ||
1015 | |||
1000 | static void tcmu_free_device(struct se_device *dev) | 1016 | static void tcmu_free_device(struct se_device *dev) |
1001 | { | 1017 | { |
1002 | struct tcmu_dev *udev = TCMU_DEV(dev); | 1018 | struct tcmu_dev *udev = TCMU_DEV(dev); |
@@ -1018,8 +1034,7 @@ static void tcmu_free_device(struct se_device *dev) | |||
1018 | spin_unlock_irq(&udev->commands_lock); | 1034 | spin_unlock_irq(&udev->commands_lock); |
1019 | WARN_ON(!all_expired); | 1035 | WARN_ON(!all_expired); |
1020 | 1036 | ||
1021 | /* Device was configured */ | 1037 | if (tcmu_dev_configured(udev)) { |
1022 | if (udev->uio_info.uio_dev) { | ||
1023 | tcmu_netlink_event(TCMU_CMD_REMOVED_DEVICE, udev->uio_info.name, | 1038 | tcmu_netlink_event(TCMU_CMD_REMOVED_DEVICE, udev->uio_info.name, |
1024 | udev->uio_info.uio_dev->minor); | 1039 | udev->uio_info.uio_dev->minor); |
1025 | 1040 | ||
@@ -1031,16 +1046,42 @@ static void tcmu_free_device(struct se_device *dev) | |||
1031 | } | 1046 | } |
1032 | 1047 | ||
1033 | enum { | 1048 | enum { |
1034 | Opt_dev_config, Opt_dev_size, Opt_hw_block_size, Opt_err, | 1049 | Opt_dev_config, Opt_dev_size, Opt_hw_block_size, Opt_hw_max_sectors, |
1050 | Opt_err, | ||
1035 | }; | 1051 | }; |
1036 | 1052 | ||
1037 | static match_table_t tokens = { | 1053 | static match_table_t tokens = { |
1038 | {Opt_dev_config, "dev_config=%s"}, | 1054 | {Opt_dev_config, "dev_config=%s"}, |
1039 | {Opt_dev_size, "dev_size=%u"}, | 1055 | {Opt_dev_size, "dev_size=%u"}, |
1040 | {Opt_hw_block_size, "hw_block_size=%u"}, | 1056 | {Opt_hw_block_size, "hw_block_size=%u"}, |
1057 | {Opt_hw_max_sectors, "hw_max_sectors=%u"}, | ||
1041 | {Opt_err, NULL} | 1058 | {Opt_err, NULL} |
1042 | }; | 1059 | }; |
1043 | 1060 | ||
1061 | static int tcmu_set_dev_attrib(substring_t *arg, u32 *dev_attrib) | ||
1062 | { | ||
1063 | unsigned long tmp_ul; | ||
1064 | char *arg_p; | ||
1065 | int ret; | ||
1066 | |||
1067 | arg_p = match_strdup(arg); | ||
1068 | if (!arg_p) | ||
1069 | return -ENOMEM; | ||
1070 | |||
1071 | ret = kstrtoul(arg_p, 0, &tmp_ul); | ||
1072 | kfree(arg_p); | ||
1073 | if (ret < 0) { | ||
1074 | pr_err("kstrtoul() failed for dev attrib\n"); | ||
1075 | return ret; | ||
1076 | } | ||
1077 | if (!tmp_ul) { | ||
1078 | pr_err("dev attrib must be nonzero\n"); | ||
1079 | return -EINVAL; | ||
1080 | } | ||
1081 | *dev_attrib = tmp_ul; | ||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1044 | static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev, | 1085 | static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev, |
1045 | const char *page, ssize_t count) | 1086 | const char *page, ssize_t count) |
1046 | { | 1087 | { |
@@ -1048,7 +1089,6 @@ static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev, | |||
1048 | char *orig, *ptr, *opts, *arg_p; | 1089 | char *orig, *ptr, *opts, *arg_p; |
1049 | substring_t args[MAX_OPT_ARGS]; | 1090 | substring_t args[MAX_OPT_ARGS]; |
1050 | int ret = 0, token; | 1091 | int ret = 0, token; |
1051 | unsigned long tmp_ul; | ||
1052 | 1092 | ||
1053 | opts = kstrdup(page, GFP_KERNEL); | 1093 | opts = kstrdup(page, GFP_KERNEL); |
1054 | if (!opts) | 1094 | if (!opts) |
@@ -1082,26 +1122,19 @@ static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev, | |||
1082 | pr_err("kstrtoul() failed for dev_size=\n"); | 1122 | pr_err("kstrtoul() failed for dev_size=\n"); |
1083 | break; | 1123 | break; |
1084 | case Opt_hw_block_size: | 1124 | case Opt_hw_block_size: |
1085 | arg_p = match_strdup(&args[0]); | 1125 | ret = tcmu_set_dev_attrib(&args[0], |
1086 | if (!arg_p) { | 1126 | &(dev->dev_attrib.hw_block_size)); |
1087 | ret = -ENOMEM; | 1127 | break; |
1088 | break; | 1128 | case Opt_hw_max_sectors: |
1089 | } | 1129 | ret = tcmu_set_dev_attrib(&args[0], |
1090 | ret = kstrtoul(arg_p, 0, &tmp_ul); | 1130 | &(dev->dev_attrib.hw_max_sectors)); |
1091 | kfree(arg_p); | ||
1092 | if (ret < 0) { | ||
1093 | pr_err("kstrtoul() failed for hw_block_size=\n"); | ||
1094 | break; | ||
1095 | } | ||
1096 | if (!tmp_ul) { | ||
1097 | pr_err("hw_block_size must be nonzero\n"); | ||
1098 | break; | ||
1099 | } | ||
1100 | dev->dev_attrib.hw_block_size = tmp_ul; | ||
1101 | break; | 1131 | break; |
1102 | default: | 1132 | default: |
1103 | break; | 1133 | break; |
1104 | } | 1134 | } |
1135 | |||
1136 | if (ret) | ||
1137 | break; | ||
1105 | } | 1138 | } |
1106 | 1139 | ||
1107 | kfree(orig); | 1140 | kfree(orig); |
@@ -1134,7 +1167,48 @@ tcmu_parse_cdb(struct se_cmd *cmd) | |||
1134 | return passthrough_parse_cdb(cmd, tcmu_queue_cmd); | 1167 | return passthrough_parse_cdb(cmd, tcmu_queue_cmd); |
1135 | } | 1168 | } |
1136 | 1169 | ||
1137 | static const struct target_backend_ops tcmu_ops = { | 1170 | static ssize_t tcmu_cmd_time_out_show(struct config_item *item, char *page) |
1171 | { | ||
1172 | struct se_dev_attrib *da = container_of(to_config_group(item), | ||
1173 | struct se_dev_attrib, da_group); | ||
1174 | struct tcmu_dev *udev = container_of(da->da_dev, | ||
1175 | struct tcmu_dev, se_dev); | ||
1176 | |||
1177 | return snprintf(page, PAGE_SIZE, "%lu\n", udev->cmd_time_out / MSEC_PER_SEC); | ||
1178 | } | ||
1179 | |||
1180 | static ssize_t tcmu_cmd_time_out_store(struct config_item *item, const char *page, | ||
1181 | size_t count) | ||
1182 | { | ||
1183 | struct se_dev_attrib *da = container_of(to_config_group(item), | ||
1184 | struct se_dev_attrib, da_group); | ||
1185 | struct tcmu_dev *udev = container_of(da->da_dev, | ||
1186 | struct tcmu_dev, se_dev); | ||
1187 | u32 val; | ||
1188 | int ret; | ||
1189 | |||
1190 | if (da->da_dev->export_count) { | ||
1191 | pr_err("Unable to set tcmu cmd_time_out while exports exist\n"); | ||
1192 | return -EINVAL; | ||
1193 | } | ||
1194 | |||
1195 | ret = kstrtou32(page, 0, &val); | ||
1196 | if (ret < 0) | ||
1197 | return ret; | ||
1198 | |||
1199 | if (!val) { | ||
1200 | pr_err("Illegal value for cmd_time_out\n"); | ||
1201 | return -EINVAL; | ||
1202 | } | ||
1203 | |||
1204 | udev->cmd_time_out = val * MSEC_PER_SEC; | ||
1205 | return count; | ||
1206 | } | ||
1207 | CONFIGFS_ATTR(tcmu_, cmd_time_out); | ||
1208 | |||
1209 | static struct configfs_attribute **tcmu_attrs; | ||
1210 | |||
1211 | static struct target_backend_ops tcmu_ops = { | ||
1138 | .name = "user", | 1212 | .name = "user", |
1139 | .owner = THIS_MODULE, | 1213 | .owner = THIS_MODULE, |
1140 | .transport_flags = TRANSPORT_FLAG_PASSTHROUGH, | 1214 | .transport_flags = TRANSPORT_FLAG_PASSTHROUGH, |
@@ -1148,12 +1222,12 @@ static const struct target_backend_ops tcmu_ops = { | |||
1148 | .show_configfs_dev_params = tcmu_show_configfs_dev_params, | 1222 | .show_configfs_dev_params = tcmu_show_configfs_dev_params, |
1149 | .get_device_type = sbc_get_device_type, | 1223 | .get_device_type = sbc_get_device_type, |
1150 | .get_blocks = tcmu_get_blocks, | 1224 | .get_blocks = tcmu_get_blocks, |
1151 | .tb_dev_attrib_attrs = passthrough_attrib_attrs, | 1225 | .tb_dev_attrib_attrs = NULL, |
1152 | }; | 1226 | }; |
1153 | 1227 | ||
1154 | static int __init tcmu_module_init(void) | 1228 | static int __init tcmu_module_init(void) |
1155 | { | 1229 | { |
1156 | int ret; | 1230 | int ret, i, len = 0; |
1157 | 1231 | ||
1158 | BUILD_BUG_ON((sizeof(struct tcmu_cmd_entry) % TCMU_OP_ALIGN_SIZE) != 0); | 1232 | BUILD_BUG_ON((sizeof(struct tcmu_cmd_entry) % TCMU_OP_ALIGN_SIZE) != 0); |
1159 | 1233 | ||
@@ -1175,12 +1249,31 @@ static int __init tcmu_module_init(void) | |||
1175 | goto out_unreg_device; | 1249 | goto out_unreg_device; |
1176 | } | 1250 | } |
1177 | 1251 | ||
1252 | for (i = 0; passthrough_attrib_attrs[i] != NULL; i++) { | ||
1253 | len += sizeof(struct configfs_attribute *); | ||
1254 | } | ||
1255 | len += sizeof(struct configfs_attribute *) * 2; | ||
1256 | |||
1257 | tcmu_attrs = kzalloc(len, GFP_KERNEL); | ||
1258 | if (!tcmu_attrs) { | ||
1259 | ret = -ENOMEM; | ||
1260 | goto out_unreg_genl; | ||
1261 | } | ||
1262 | |||
1263 | for (i = 0; passthrough_attrib_attrs[i] != NULL; i++) { | ||
1264 | tcmu_attrs[i] = passthrough_attrib_attrs[i]; | ||
1265 | } | ||
1266 | tcmu_attrs[i] = &tcmu_attr_cmd_time_out; | ||
1267 | tcmu_ops.tb_dev_attrib_attrs = tcmu_attrs; | ||
1268 | |||
1178 | ret = transport_backend_register(&tcmu_ops); | 1269 | ret = transport_backend_register(&tcmu_ops); |
1179 | if (ret) | 1270 | if (ret) |
1180 | goto out_unreg_genl; | 1271 | goto out_attrs; |
1181 | 1272 | ||
1182 | return 0; | 1273 | return 0; |
1183 | 1274 | ||
1275 | out_attrs: | ||
1276 | kfree(tcmu_attrs); | ||
1184 | out_unreg_genl: | 1277 | out_unreg_genl: |
1185 | genl_unregister_family(&tcmu_genl_family); | 1278 | genl_unregister_family(&tcmu_genl_family); |
1186 | out_unreg_device: | 1279 | out_unreg_device: |
@@ -1194,6 +1287,7 @@ out_free_cache: | |||
1194 | static void __exit tcmu_module_exit(void) | 1287 | static void __exit tcmu_module_exit(void) |
1195 | { | 1288 | { |
1196 | target_backend_unregister(&tcmu_ops); | 1289 | target_backend_unregister(&tcmu_ops); |
1290 | kfree(tcmu_attrs); | ||
1197 | genl_unregister_family(&tcmu_genl_family); | 1291 | genl_unregister_family(&tcmu_genl_family); |
1198 | root_device_unregister(tcmu_root_device); | 1292 | root_device_unregister(tcmu_root_device); |
1199 | kmem_cache_destroy(tcmu_cmd_cache); | 1293 | kmem_cache_destroy(tcmu_cmd_cache); |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 0d75158e43fe..79e7a3480d51 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -171,6 +171,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | |||
171 | int status) | 171 | int status) |
172 | { | 172 | { |
173 | struct dwc3 *dwc = dep->dwc; | 173 | struct dwc3 *dwc = dep->dwc; |
174 | unsigned int unmap_after_complete = false; | ||
174 | 175 | ||
175 | req->started = false; | 176 | req->started = false; |
176 | list_del(&req->list); | 177 | list_del(&req->list); |
@@ -180,11 +181,19 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | |||
180 | if (req->request.status == -EINPROGRESS) | 181 | if (req->request.status == -EINPROGRESS) |
181 | req->request.status = status; | 182 | req->request.status = status; |
182 | 183 | ||
183 | if (dwc->ep0_bounced && dep->number <= 1) | 184 | /* |
185 | * NOTICE we don't want to unmap before calling ->complete() if we're | ||
186 | * dealing with a bounced ep0 request. If we unmap it here, we would end | ||
187 | * up overwritting the contents of req->buf and this could confuse the | ||
188 | * gadget driver. | ||
189 | */ | ||
190 | if (dwc->ep0_bounced && dep->number <= 1) { | ||
184 | dwc->ep0_bounced = false; | 191 | dwc->ep0_bounced = false; |
185 | 192 | unmap_after_complete = true; | |
186 | usb_gadget_unmap_request_by_dev(dwc->sysdev, | 193 | } else { |
187 | &req->request, req->direction); | 194 | usb_gadget_unmap_request_by_dev(dwc->sysdev, |
195 | &req->request, req->direction); | ||
196 | } | ||
188 | 197 | ||
189 | trace_dwc3_gadget_giveback(req); | 198 | trace_dwc3_gadget_giveback(req); |
190 | 199 | ||
@@ -192,6 +201,10 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | |||
192 | usb_gadget_giveback_request(&dep->endpoint, &req->request); | 201 | usb_gadget_giveback_request(&dep->endpoint, &req->request); |
193 | spin_lock(&dwc->lock); | 202 | spin_lock(&dwc->lock); |
194 | 203 | ||
204 | if (unmap_after_complete) | ||
205 | usb_gadget_unmap_request_by_dev(dwc->sysdev, | ||
206 | &req->request, req->direction); | ||
207 | |||
195 | if (dep->number > 1) | 208 | if (dep->number > 1) |
196 | pm_runtime_put(dwc->dev); | 209 | pm_runtime_put(dwc->dev); |
197 | } | 210 | } |
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 89b48bcc377a..5eea44823ca0 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c | |||
@@ -367,7 +367,7 @@ try_again: | |||
367 | count = min_t(unsigned, count, hidg->report_length); | 367 | count = min_t(unsigned, count, hidg->report_length); |
368 | 368 | ||
369 | spin_unlock_irqrestore(&hidg->write_spinlock, flags); | 369 | spin_unlock_irqrestore(&hidg->write_spinlock, flags); |
370 | status = copy_from_user(hidg->req->buf, buffer, count); | 370 | status = copy_from_user(req->buf, buffer, count); |
371 | 371 | ||
372 | if (status != 0) { | 372 | if (status != 0) { |
373 | ERROR(hidg->func.config->cdev, | 373 | ERROR(hidg->func.config->cdev, |
@@ -378,9 +378,9 @@ try_again: | |||
378 | 378 | ||
379 | spin_lock_irqsave(&hidg->write_spinlock, flags); | 379 | spin_lock_irqsave(&hidg->write_spinlock, flags); |
380 | 380 | ||
381 | /* we our function has been disabled by host */ | 381 | /* when our function has been disabled by host */ |
382 | if (!hidg->req) { | 382 | if (!hidg->req) { |
383 | free_ep_req(hidg->in_ep, hidg->req); | 383 | free_ep_req(hidg->in_ep, req); |
384 | /* | 384 | /* |
385 | * TODO | 385 | * TODO |
386 | * Should we fail with error here? | 386 | * Should we fail with error here? |
@@ -394,7 +394,7 @@ try_again: | |||
394 | req->complete = f_hidg_req_complete; | 394 | req->complete = f_hidg_req_complete; |
395 | req->context = hidg; | 395 | req->context = hidg; |
396 | 396 | ||
397 | status = usb_ep_queue(hidg->in_ep, hidg->req, GFP_ATOMIC); | 397 | status = usb_ep_queue(hidg->in_ep, req, GFP_ATOMIC); |
398 | if (status < 0) { | 398 | if (status < 0) { |
399 | ERROR(hidg->func.config->cdev, | 399 | ERROR(hidg->func.config->cdev, |
400 | "usb_ep_queue error on int endpoint %zd\n", status); | 400 | "usb_ep_queue error on int endpoint %zd\n", status); |
diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 29b41b5dee04..f8a1881609a2 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c | |||
@@ -594,6 +594,14 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) | |||
594 | opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U); | 594 | opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U); |
595 | opts->streaming_maxburst = min(opts->streaming_maxburst, 15U); | 595 | opts->streaming_maxburst = min(opts->streaming_maxburst, 15U); |
596 | 596 | ||
597 | /* For SS, wMaxPacketSize has to be 1024 if bMaxBurst is not 0 */ | ||
598 | if (opts->streaming_maxburst && | ||
599 | (opts->streaming_maxpacket % 1024) != 0) { | ||
600 | opts->streaming_maxpacket = roundup(opts->streaming_maxpacket, 1024); | ||
601 | INFO(cdev, "overriding streaming_maxpacket to %d\n", | ||
602 | opts->streaming_maxpacket); | ||
603 | } | ||
604 | |||
597 | /* Fill in the FS/HS/SS Video Streaming specific descriptors from the | 605 | /* Fill in the FS/HS/SS Video Streaming specific descriptors from the |
598 | * module parameters. | 606 | * module parameters. |
599 | * | 607 | * |
@@ -625,7 +633,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) | |||
625 | uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst; | 633 | uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst; |
626 | uvc_ss_streaming_comp.wBytesPerInterval = | 634 | uvc_ss_streaming_comp.wBytesPerInterval = |
627 | cpu_to_le16(max_packet_size * max_packet_mult * | 635 | cpu_to_le16(max_packet_size * max_packet_mult * |
628 | opts->streaming_maxburst); | 636 | (opts->streaming_maxburst + 1)); |
629 | 637 | ||
630 | /* Allocate endpoints. */ | 638 | /* Allocate endpoints. */ |
631 | ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep); | 639 | ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep); |
diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index a97da645c1b9..8a365aad66fe 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c | |||
@@ -1523,7 +1523,6 @@ static void pch_udc_free_dma_chain(struct pch_udc_dev *dev, | |||
1523 | td = phys_to_virt(addr); | 1523 | td = phys_to_virt(addr); |
1524 | addr2 = (dma_addr_t)td->next; | 1524 | addr2 = (dma_addr_t)td->next; |
1525 | pci_pool_free(dev->data_requests, td, addr); | 1525 | pci_pool_free(dev->data_requests, td, addr); |
1526 | td->next = 0x00; | ||
1527 | addr = addr2; | 1526 | addr = addr2; |
1528 | } | 1527 | } |
1529 | req->chain_len = 1; | 1528 | req->chain_len = 1; |
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index c77a0751a311..f3bf8f4e2d6c 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <linux/highmem.h> | 38 | #include <linux/highmem.h> |
39 | #include <linux/refcount.h> | ||
39 | 40 | ||
40 | #include <xen/xen.h> | 41 | #include <xen/xen.h> |
41 | #include <xen/grant_table.h> | 42 | #include <xen/grant_table.h> |
@@ -86,7 +87,7 @@ struct grant_map { | |||
86 | int index; | 87 | int index; |
87 | int count; | 88 | int count; |
88 | int flags; | 89 | int flags; |
89 | atomic_t users; | 90 | refcount_t users; |
90 | struct unmap_notify notify; | 91 | struct unmap_notify notify; |
91 | struct ioctl_gntdev_grant_ref *grants; | 92 | struct ioctl_gntdev_grant_ref *grants; |
92 | struct gnttab_map_grant_ref *map_ops; | 93 | struct gnttab_map_grant_ref *map_ops; |
@@ -166,7 +167,7 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) | |||
166 | 167 | ||
167 | add->index = 0; | 168 | add->index = 0; |
168 | add->count = count; | 169 | add->count = count; |
169 | atomic_set(&add->users, 1); | 170 | refcount_set(&add->users, 1); |
170 | 171 | ||
171 | return add; | 172 | return add; |
172 | 173 | ||
@@ -212,7 +213,7 @@ static void gntdev_put_map(struct gntdev_priv *priv, struct grant_map *map) | |||
212 | if (!map) | 213 | if (!map) |
213 | return; | 214 | return; |
214 | 215 | ||
215 | if (!atomic_dec_and_test(&map->users)) | 216 | if (!refcount_dec_and_test(&map->users)) |
216 | return; | 217 | return; |
217 | 218 | ||
218 | atomic_sub(map->count, &pages_mapped); | 219 | atomic_sub(map->count, &pages_mapped); |
@@ -400,7 +401,7 @@ static void gntdev_vma_open(struct vm_area_struct *vma) | |||
400 | struct grant_map *map = vma->vm_private_data; | 401 | struct grant_map *map = vma->vm_private_data; |
401 | 402 | ||
402 | pr_debug("gntdev_vma_open %p\n", vma); | 403 | pr_debug("gntdev_vma_open %p\n", vma); |
403 | atomic_inc(&map->users); | 404 | refcount_inc(&map->users); |
404 | } | 405 | } |
405 | 406 | ||
406 | static void gntdev_vma_close(struct vm_area_struct *vma) | 407 | static void gntdev_vma_close(struct vm_area_struct *vma) |
@@ -1004,7 +1005,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) | |||
1004 | goto unlock_out; | 1005 | goto unlock_out; |
1005 | } | 1006 | } |
1006 | 1007 | ||
1007 | atomic_inc(&map->users); | 1008 | refcount_inc(&map->users); |
1008 | 1009 | ||
1009 | vma->vm_ops = &gntdev_vmops; | 1010 | vma->vm_ops = &gntdev_vmops; |
1010 | 1011 | ||
diff --git a/fs/afs/callback.c b/fs/afs/callback.c index b29447e03ede..25d404d22cae 100644 --- a/fs/afs/callback.c +++ b/fs/afs/callback.c | |||
@@ -362,7 +362,7 @@ static void afs_callback_updater(struct work_struct *work) | |||
362 | { | 362 | { |
363 | struct afs_server *server; | 363 | struct afs_server *server; |
364 | struct afs_vnode *vnode, *xvnode; | 364 | struct afs_vnode *vnode, *xvnode; |
365 | time_t now; | 365 | time64_t now; |
366 | long timeout; | 366 | long timeout; |
367 | int ret; | 367 | int ret; |
368 | 368 | ||
@@ -370,7 +370,7 @@ static void afs_callback_updater(struct work_struct *work) | |||
370 | 370 | ||
371 | _enter(""); | 371 | _enter(""); |
372 | 372 | ||
373 | now = get_seconds(); | 373 | now = ktime_get_real_seconds(); |
374 | 374 | ||
375 | /* find the first vnode to update */ | 375 | /* find the first vnode to update */ |
376 | spin_lock(&server->cb_lock); | 376 | spin_lock(&server->cb_lock); |
@@ -424,7 +424,8 @@ static void afs_callback_updater(struct work_struct *work) | |||
424 | 424 | ||
425 | /* and then reschedule */ | 425 | /* and then reschedule */ |
426 | _debug("reschedule"); | 426 | _debug("reschedule"); |
427 | vnode->update_at = get_seconds() + afs_vnode_update_timeout; | 427 | vnode->update_at = ktime_get_real_seconds() + |
428 | afs_vnode_update_timeout; | ||
428 | 429 | ||
429 | spin_lock(&server->cb_lock); | 430 | spin_lock(&server->cb_lock); |
430 | 431 | ||
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index 2edbdcbf6432..3062cceb5c2a 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c | |||
@@ -187,7 +187,6 @@ static int afs_deliver_cb_callback(struct afs_call *call) | |||
187 | struct afs_callback *cb; | 187 | struct afs_callback *cb; |
188 | struct afs_server *server; | 188 | struct afs_server *server; |
189 | __be32 *bp; | 189 | __be32 *bp; |
190 | u32 tmp; | ||
191 | int ret, loop; | 190 | int ret, loop; |
192 | 191 | ||
193 | _enter("{%u}", call->unmarshall); | 192 | _enter("{%u}", call->unmarshall); |
@@ -249,9 +248,9 @@ static int afs_deliver_cb_callback(struct afs_call *call) | |||
249 | if (ret < 0) | 248 | if (ret < 0) |
250 | return ret; | 249 | return ret; |
251 | 250 | ||
252 | tmp = ntohl(call->tmp); | 251 | call->count2 = ntohl(call->tmp); |
253 | _debug("CB count: %u", tmp); | 252 | _debug("CB count: %u", call->count2); |
254 | if (tmp != call->count && tmp != 0) | 253 | if (call->count2 != call->count && call->count2 != 0) |
255 | return -EBADMSG; | 254 | return -EBADMSG; |
256 | call->offset = 0; | 255 | call->offset = 0; |
257 | call->unmarshall++; | 256 | call->unmarshall++; |
@@ -259,14 +258,14 @@ static int afs_deliver_cb_callback(struct afs_call *call) | |||
259 | case 4: | 258 | case 4: |
260 | _debug("extract CB array"); | 259 | _debug("extract CB array"); |
261 | ret = afs_extract_data(call, call->buffer, | 260 | ret = afs_extract_data(call, call->buffer, |
262 | call->count * 3 * 4, false); | 261 | call->count2 * 3 * 4, false); |
263 | if (ret < 0) | 262 | if (ret < 0) |
264 | return ret; | 263 | return ret; |
265 | 264 | ||
266 | _debug("unmarshall CB array"); | 265 | _debug("unmarshall CB array"); |
267 | cb = call->request; | 266 | cb = call->request; |
268 | bp = call->buffer; | 267 | bp = call->buffer; |
269 | for (loop = call->count; loop > 0; loop--, cb++) { | 268 | for (loop = call->count2; loop > 0; loop--, cb++) { |
270 | cb->version = ntohl(*bp++); | 269 | cb->version = ntohl(*bp++); |
271 | cb->expiry = ntohl(*bp++); | 270 | cb->expiry = ntohl(*bp++); |
272 | cb->type = ntohl(*bp++); | 271 | cb->type = ntohl(*bp++); |
diff --git a/fs/afs/file.c b/fs/afs/file.c index ba7b71fba34b..0d5b8508869b 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c | |||
@@ -30,6 +30,7 @@ static int afs_readpages(struct file *filp, struct address_space *mapping, | |||
30 | 30 | ||
31 | const struct file_operations afs_file_operations = { | 31 | const struct file_operations afs_file_operations = { |
32 | .open = afs_open, | 32 | .open = afs_open, |
33 | .flush = afs_flush, | ||
33 | .release = afs_release, | 34 | .release = afs_release, |
34 | .llseek = generic_file_llseek, | 35 | .llseek = generic_file_llseek, |
35 | .read_iter = generic_file_read_iter, | 36 | .read_iter = generic_file_read_iter, |
@@ -184,10 +185,13 @@ int afs_page_filler(void *data, struct page *page) | |||
184 | if (!req) | 185 | if (!req) |
185 | goto enomem; | 186 | goto enomem; |
186 | 187 | ||
188 | /* We request a full page. If the page is a partial one at the | ||
189 | * end of the file, the server will return a short read and the | ||
190 | * unmarshalling code will clear the unfilled space. | ||
191 | */ | ||
187 | atomic_set(&req->usage, 1); | 192 | atomic_set(&req->usage, 1); |
188 | req->pos = (loff_t)page->index << PAGE_SHIFT; | 193 | req->pos = (loff_t)page->index << PAGE_SHIFT; |
189 | req->len = min_t(size_t, i_size_read(inode) - req->pos, | 194 | req->len = PAGE_SIZE; |
190 | PAGE_SIZE); | ||
191 | req->nr_pages = 1; | 195 | req->nr_pages = 1; |
192 | req->pages[0] = page; | 196 | req->pages[0] = page; |
193 | get_page(page); | 197 | get_page(page); |
@@ -208,7 +212,13 @@ int afs_page_filler(void *data, struct page *page) | |||
208 | fscache_uncache_page(vnode->cache, page); | 212 | fscache_uncache_page(vnode->cache, page); |
209 | #endif | 213 | #endif |
210 | BUG_ON(PageFsCache(page)); | 214 | BUG_ON(PageFsCache(page)); |
211 | goto error; | 215 | |
216 | if (ret == -EINTR || | ||
217 | ret == -ENOMEM || | ||
218 | ret == -ERESTARTSYS || | ||
219 | ret == -EAGAIN) | ||
220 | goto error; | ||
221 | goto io_error; | ||
212 | } | 222 | } |
213 | 223 | ||
214 | SetPageUptodate(page); | 224 | SetPageUptodate(page); |
@@ -227,10 +237,12 @@ int afs_page_filler(void *data, struct page *page) | |||
227 | _leave(" = 0"); | 237 | _leave(" = 0"); |
228 | return 0; | 238 | return 0; |
229 | 239 | ||
240 | io_error: | ||
241 | SetPageError(page); | ||
242 | goto error; | ||
230 | enomem: | 243 | enomem: |
231 | ret = -ENOMEM; | 244 | ret = -ENOMEM; |
232 | error: | 245 | error: |
233 | SetPageError(page); | ||
234 | unlock_page(page); | 246 | unlock_page(page); |
235 | _leave(" = %d", ret); | 247 | _leave(" = %d", ret); |
236 | return ret; | 248 | return ret; |
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index ac8e766978dc..19f76ae36982 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c | |||
@@ -17,6 +17,12 @@ | |||
17 | #include "afs_fs.h" | 17 | #include "afs_fs.h" |
18 | 18 | ||
19 | /* | 19 | /* |
20 | * We need somewhere to discard into in case the server helpfully returns more | ||
21 | * than we asked for in FS.FetchData{,64}. | ||
22 | */ | ||
23 | static u8 afs_discard_buffer[64]; | ||
24 | |||
25 | /* | ||
20 | * decode an AFSFid block | 26 | * decode an AFSFid block |
21 | */ | 27 | */ |
22 | static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid) | 28 | static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid) |
@@ -105,7 +111,7 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp, | |||
105 | vnode->vfs_inode.i_mode = mode; | 111 | vnode->vfs_inode.i_mode = mode; |
106 | } | 112 | } |
107 | 113 | ||
108 | vnode->vfs_inode.i_ctime.tv_sec = status->mtime_server; | 114 | vnode->vfs_inode.i_ctime.tv_sec = status->mtime_client; |
109 | vnode->vfs_inode.i_mtime = vnode->vfs_inode.i_ctime; | 115 | vnode->vfs_inode.i_mtime = vnode->vfs_inode.i_ctime; |
110 | vnode->vfs_inode.i_atime = vnode->vfs_inode.i_ctime; | 116 | vnode->vfs_inode.i_atime = vnode->vfs_inode.i_ctime; |
111 | vnode->vfs_inode.i_version = data_version; | 117 | vnode->vfs_inode.i_version = data_version; |
@@ -139,7 +145,7 @@ static void xdr_decode_AFSCallBack(const __be32 **_bp, struct afs_vnode *vnode) | |||
139 | vnode->cb_version = ntohl(*bp++); | 145 | vnode->cb_version = ntohl(*bp++); |
140 | vnode->cb_expiry = ntohl(*bp++); | 146 | vnode->cb_expiry = ntohl(*bp++); |
141 | vnode->cb_type = ntohl(*bp++); | 147 | vnode->cb_type = ntohl(*bp++); |
142 | vnode->cb_expires = vnode->cb_expiry + get_seconds(); | 148 | vnode->cb_expires = vnode->cb_expiry + ktime_get_real_seconds(); |
143 | *_bp = bp; | 149 | *_bp = bp; |
144 | } | 150 | } |
145 | 151 | ||
@@ -315,7 +321,7 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call) | |||
315 | void *buffer; | 321 | void *buffer; |
316 | int ret; | 322 | int ret; |
317 | 323 | ||
318 | _enter("{%u,%zu/%u;%u/%llu}", | 324 | _enter("{%u,%zu/%u;%llu/%llu}", |
319 | call->unmarshall, call->offset, call->count, | 325 | call->unmarshall, call->offset, call->count, |
320 | req->remain, req->actual_len); | 326 | req->remain, req->actual_len); |
321 | 327 | ||
@@ -353,12 +359,6 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call) | |||
353 | 359 | ||
354 | req->actual_len |= ntohl(call->tmp); | 360 | req->actual_len |= ntohl(call->tmp); |
355 | _debug("DATA length: %llu", req->actual_len); | 361 | _debug("DATA length: %llu", req->actual_len); |
356 | /* Check that the server didn't want to send us extra. We | ||
357 | * might want to just discard instead, but that requires | ||
358 | * cooperation from AF_RXRPC. | ||
359 | */ | ||
360 | if (req->actual_len > req->len) | ||
361 | return -EBADMSG; | ||
362 | 362 | ||
363 | req->remain = req->actual_len; | 363 | req->remain = req->actual_len; |
364 | call->offset = req->pos & (PAGE_SIZE - 1); | 364 | call->offset = req->pos & (PAGE_SIZE - 1); |
@@ -368,6 +368,7 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call) | |||
368 | call->unmarshall++; | 368 | call->unmarshall++; |
369 | 369 | ||
370 | begin_page: | 370 | begin_page: |
371 | ASSERTCMP(req->index, <, req->nr_pages); | ||
371 | if (req->remain > PAGE_SIZE - call->offset) | 372 | if (req->remain > PAGE_SIZE - call->offset) |
372 | size = PAGE_SIZE - call->offset; | 373 | size = PAGE_SIZE - call->offset; |
373 | else | 374 | else |
@@ -378,7 +379,7 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call) | |||
378 | 379 | ||
379 | /* extract the returned data */ | 380 | /* extract the returned data */ |
380 | case 3: | 381 | case 3: |
381 | _debug("extract data %u/%llu %zu/%u", | 382 | _debug("extract data %llu/%llu %zu/%u", |
382 | req->remain, req->actual_len, call->offset, call->count); | 383 | req->remain, req->actual_len, call->offset, call->count); |
383 | 384 | ||
384 | buffer = kmap(req->pages[req->index]); | 385 | buffer = kmap(req->pages[req->index]); |
@@ -389,19 +390,40 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call) | |||
389 | if (call->offset == PAGE_SIZE) { | 390 | if (call->offset == PAGE_SIZE) { |
390 | if (req->page_done) | 391 | if (req->page_done) |
391 | req->page_done(call, req); | 392 | req->page_done(call, req); |
393 | req->index++; | ||
392 | if (req->remain > 0) { | 394 | if (req->remain > 0) { |
393 | req->index++; | ||
394 | call->offset = 0; | 395 | call->offset = 0; |
396 | if (req->index >= req->nr_pages) { | ||
397 | call->unmarshall = 4; | ||
398 | goto begin_discard; | ||
399 | } | ||
395 | goto begin_page; | 400 | goto begin_page; |
396 | } | 401 | } |
397 | } | 402 | } |
403 | goto no_more_data; | ||
404 | |||
405 | /* Discard any excess data the server gave us */ | ||
406 | begin_discard: | ||
407 | case 4: | ||
408 | size = min_t(loff_t, sizeof(afs_discard_buffer), req->remain); | ||
409 | call->count = size; | ||
410 | _debug("extract discard %llu/%llu %zu/%u", | ||
411 | req->remain, req->actual_len, call->offset, call->count); | ||
412 | |||
413 | call->offset = 0; | ||
414 | ret = afs_extract_data(call, afs_discard_buffer, call->count, true); | ||
415 | req->remain -= call->offset; | ||
416 | if (ret < 0) | ||
417 | return ret; | ||
418 | if (req->remain > 0) | ||
419 | goto begin_discard; | ||
398 | 420 | ||
399 | no_more_data: | 421 | no_more_data: |
400 | call->offset = 0; | 422 | call->offset = 0; |
401 | call->unmarshall++; | 423 | call->unmarshall = 5; |
402 | 424 | ||
403 | /* extract the metadata */ | 425 | /* extract the metadata */ |
404 | case 4: | 426 | case 5: |
405 | ret = afs_extract_data(call, call->buffer, | 427 | ret = afs_extract_data(call, call->buffer, |
406 | (21 + 3 + 6) * 4, false); | 428 | (21 + 3 + 6) * 4, false); |
407 | if (ret < 0) | 429 | if (ret < 0) |
@@ -416,16 +438,17 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call) | |||
416 | call->offset = 0; | 438 | call->offset = 0; |
417 | call->unmarshall++; | 439 | call->unmarshall++; |
418 | 440 | ||
419 | case 5: | 441 | case 6: |
420 | break; | 442 | break; |
421 | } | 443 | } |
422 | 444 | ||
423 | if (call->count < PAGE_SIZE) { | 445 | for (; req->index < req->nr_pages; req->index++) { |
424 | buffer = kmap(req->pages[req->index]); | 446 | if (call->count < PAGE_SIZE) |
425 | memset(buffer + call->count, 0, PAGE_SIZE - call->count); | 447 | zero_user_segment(req->pages[req->index], |
426 | kunmap(req->pages[req->index]); | 448 | call->count, PAGE_SIZE); |
427 | if (req->page_done) | 449 | if (req->page_done) |
428 | req->page_done(call, req); | 450 | req->page_done(call, req); |
451 | call->count = 0; | ||
429 | } | 452 | } |
430 | 453 | ||
431 | _leave(" = 0 [done]"); | 454 | _leave(" = 0 [done]"); |
@@ -711,8 +734,8 @@ int afs_fs_create(struct afs_server *server, | |||
711 | memset(bp, 0, padsz); | 734 | memset(bp, 0, padsz); |
712 | bp = (void *) bp + padsz; | 735 | bp = (void *) bp + padsz; |
713 | } | 736 | } |
714 | *bp++ = htonl(AFS_SET_MODE); | 737 | *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME); |
715 | *bp++ = 0; /* mtime */ | 738 | *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */ |
716 | *bp++ = 0; /* owner */ | 739 | *bp++ = 0; /* owner */ |
717 | *bp++ = 0; /* group */ | 740 | *bp++ = 0; /* group */ |
718 | *bp++ = htonl(mode & S_IALLUGO); /* unix mode */ | 741 | *bp++ = htonl(mode & S_IALLUGO); /* unix mode */ |
@@ -980,8 +1003,8 @@ int afs_fs_symlink(struct afs_server *server, | |||
980 | memset(bp, 0, c_padsz); | 1003 | memset(bp, 0, c_padsz); |
981 | bp = (void *) bp + c_padsz; | 1004 | bp = (void *) bp + c_padsz; |
982 | } | 1005 | } |
983 | *bp++ = htonl(AFS_SET_MODE); | 1006 | *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME); |
984 | *bp++ = 0; /* mtime */ | 1007 | *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */ |
985 | *bp++ = 0; /* owner */ | 1008 | *bp++ = 0; /* owner */ |
986 | *bp++ = 0; /* group */ | 1009 | *bp++ = 0; /* group */ |
987 | *bp++ = htonl(S_IRWXUGO); /* unix mode */ | 1010 | *bp++ = htonl(S_IRWXUGO); /* unix mode */ |
@@ -1180,8 +1203,8 @@ static int afs_fs_store_data64(struct afs_server *server, | |||
1180 | *bp++ = htonl(vnode->fid.vnode); | 1203 | *bp++ = htonl(vnode->fid.vnode); |
1181 | *bp++ = htonl(vnode->fid.unique); | 1204 | *bp++ = htonl(vnode->fid.unique); |
1182 | 1205 | ||
1183 | *bp++ = 0; /* mask */ | 1206 | *bp++ = htonl(AFS_SET_MTIME); /* mask */ |
1184 | *bp++ = 0; /* mtime */ | 1207 | *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */ |
1185 | *bp++ = 0; /* owner */ | 1208 | *bp++ = 0; /* owner */ |
1186 | *bp++ = 0; /* group */ | 1209 | *bp++ = 0; /* group */ |
1187 | *bp++ = 0; /* unix mode */ | 1210 | *bp++ = 0; /* unix mode */ |
@@ -1213,7 +1236,7 @@ int afs_fs_store_data(struct afs_server *server, struct afs_writeback *wb, | |||
1213 | _enter(",%x,{%x:%u},,", | 1236 | _enter(",%x,{%x:%u},,", |
1214 | key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode); | 1237 | key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode); |
1215 | 1238 | ||
1216 | size = to - offset; | 1239 | size = (loff_t)to - (loff_t)offset; |
1217 | if (first != last) | 1240 | if (first != last) |
1218 | size += (loff_t)(last - first) << PAGE_SHIFT; | 1241 | size += (loff_t)(last - first) << PAGE_SHIFT; |
1219 | pos = (loff_t)first << PAGE_SHIFT; | 1242 | pos = (loff_t)first << PAGE_SHIFT; |
@@ -1257,8 +1280,8 @@ int afs_fs_store_data(struct afs_server *server, struct afs_writeback *wb, | |||
1257 | *bp++ = htonl(vnode->fid.vnode); | 1280 | *bp++ = htonl(vnode->fid.vnode); |
1258 | *bp++ = htonl(vnode->fid.unique); | 1281 | *bp++ = htonl(vnode->fid.unique); |
1259 | 1282 | ||
1260 | *bp++ = 0; /* mask */ | 1283 | *bp++ = htonl(AFS_SET_MTIME); /* mask */ |
1261 | *bp++ = 0; /* mtime */ | 1284 | *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */ |
1262 | *bp++ = 0; /* owner */ | 1285 | *bp++ = 0; /* owner */ |
1263 | *bp++ = 0; /* group */ | 1286 | *bp++ = 0; /* group */ |
1264 | *bp++ = 0; /* unix mode */ | 1287 | *bp++ = 0; /* unix mode */ |
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 1e4897a048d2..aae55dd15108 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c | |||
@@ -54,8 +54,21 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key) | |||
54 | inode->i_fop = &afs_dir_file_operations; | 54 | inode->i_fop = &afs_dir_file_operations; |
55 | break; | 55 | break; |
56 | case AFS_FTYPE_SYMLINK: | 56 | case AFS_FTYPE_SYMLINK: |
57 | inode->i_mode = S_IFLNK | vnode->status.mode; | 57 | /* Symlinks with a mode of 0644 are actually mountpoints. */ |
58 | inode->i_op = &page_symlink_inode_operations; | 58 | if ((vnode->status.mode & 0777) == 0644) { |
59 | inode->i_flags |= S_AUTOMOUNT; | ||
60 | |||
61 | spin_lock(&vnode->lock); | ||
62 | set_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags); | ||
63 | spin_unlock(&vnode->lock); | ||
64 | |||
65 | inode->i_mode = S_IFDIR | 0555; | ||
66 | inode->i_op = &afs_mntpt_inode_operations; | ||
67 | inode->i_fop = &afs_mntpt_file_operations; | ||
68 | } else { | ||
69 | inode->i_mode = S_IFLNK | vnode->status.mode; | ||
70 | inode->i_op = &page_symlink_inode_operations; | ||
71 | } | ||
59 | inode_nohighmem(inode); | 72 | inode_nohighmem(inode); |
60 | break; | 73 | break; |
61 | default: | 74 | default: |
@@ -70,27 +83,15 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key) | |||
70 | 83 | ||
71 | set_nlink(inode, vnode->status.nlink); | 84 | set_nlink(inode, vnode->status.nlink); |
72 | inode->i_uid = vnode->status.owner; | 85 | inode->i_uid = vnode->status.owner; |
73 | inode->i_gid = GLOBAL_ROOT_GID; | 86 | inode->i_gid = vnode->status.group; |
74 | inode->i_size = vnode->status.size; | 87 | inode->i_size = vnode->status.size; |
75 | inode->i_ctime.tv_sec = vnode->status.mtime_server; | 88 | inode->i_ctime.tv_sec = vnode->status.mtime_client; |
76 | inode->i_ctime.tv_nsec = 0; | 89 | inode->i_ctime.tv_nsec = 0; |
77 | inode->i_atime = inode->i_mtime = inode->i_ctime; | 90 | inode->i_atime = inode->i_mtime = inode->i_ctime; |
78 | inode->i_blocks = 0; | 91 | inode->i_blocks = 0; |
79 | inode->i_generation = vnode->fid.unique; | 92 | inode->i_generation = vnode->fid.unique; |
80 | inode->i_version = vnode->status.data_version; | 93 | inode->i_version = vnode->status.data_version; |
81 | inode->i_mapping->a_ops = &afs_fs_aops; | 94 | inode->i_mapping->a_ops = &afs_fs_aops; |
82 | |||
83 | /* check to see whether a symbolic link is really a mountpoint */ | ||
84 | if (vnode->status.type == AFS_FTYPE_SYMLINK) { | ||
85 | afs_mntpt_check_symlink(vnode, key); | ||
86 | |||
87 | if (test_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags)) { | ||
88 | inode->i_mode = S_IFDIR | vnode->status.mode; | ||
89 | inode->i_op = &afs_mntpt_inode_operations; | ||
90 | inode->i_fop = &afs_mntpt_file_operations; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | return 0; | 95 | return 0; |
95 | } | 96 | } |
96 | 97 | ||
@@ -245,12 +246,13 @@ struct inode *afs_iget(struct super_block *sb, struct key *key, | |||
245 | vnode->cb_version = 0; | 246 | vnode->cb_version = 0; |
246 | vnode->cb_expiry = 0; | 247 | vnode->cb_expiry = 0; |
247 | vnode->cb_type = 0; | 248 | vnode->cb_type = 0; |
248 | vnode->cb_expires = get_seconds(); | 249 | vnode->cb_expires = ktime_get_real_seconds(); |
249 | } else { | 250 | } else { |
250 | vnode->cb_version = cb->version; | 251 | vnode->cb_version = cb->version; |
251 | vnode->cb_expiry = cb->expiry; | 252 | vnode->cb_expiry = cb->expiry; |
252 | vnode->cb_type = cb->type; | 253 | vnode->cb_type = cb->type; |
253 | vnode->cb_expires = vnode->cb_expiry + get_seconds(); | 254 | vnode->cb_expires = vnode->cb_expiry + |
255 | ktime_get_real_seconds(); | ||
254 | } | 256 | } |
255 | } | 257 | } |
256 | 258 | ||
@@ -323,7 +325,7 @@ int afs_validate(struct afs_vnode *vnode, struct key *key) | |||
323 | !test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags) && | 325 | !test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags) && |
324 | !test_bit(AFS_VNODE_MODIFIED, &vnode->flags) && | 326 | !test_bit(AFS_VNODE_MODIFIED, &vnode->flags) && |
325 | !test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) { | 327 | !test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) { |
326 | if (vnode->cb_expires < get_seconds() + 10) { | 328 | if (vnode->cb_expires < ktime_get_real_seconds() + 10) { |
327 | _debug("callback expired"); | 329 | _debug("callback expired"); |
328 | set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags); | 330 | set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags); |
329 | } else { | 331 | } else { |
@@ -444,7 +446,7 @@ void afs_evict_inode(struct inode *inode) | |||
444 | 446 | ||
445 | mutex_lock(&vnode->permits_lock); | 447 | mutex_lock(&vnode->permits_lock); |
446 | permits = vnode->permits; | 448 | permits = vnode->permits; |
447 | rcu_assign_pointer(vnode->permits, NULL); | 449 | RCU_INIT_POINTER(vnode->permits, NULL); |
448 | mutex_unlock(&vnode->permits_lock); | 450 | mutex_unlock(&vnode->permits_lock); |
449 | if (permits) | 451 | if (permits) |
450 | call_rcu(&permits->rcu, afs_zap_permits); | 452 | call_rcu(&permits->rcu, afs_zap_permits); |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 5dfa56903a2d..a6901360fb81 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/ktime.h> | ||
14 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
15 | #include <linux/pagemap.h> | 16 | #include <linux/pagemap.h> |
16 | #include <linux/rxrpc.h> | 17 | #include <linux/rxrpc.h> |
@@ -90,7 +91,10 @@ struct afs_call { | |||
90 | unsigned request_size; /* size of request data */ | 91 | unsigned request_size; /* size of request data */ |
91 | unsigned reply_max; /* maximum size of reply */ | 92 | unsigned reply_max; /* maximum size of reply */ |
92 | unsigned first_offset; /* offset into mapping[first] */ | 93 | unsigned first_offset; /* offset into mapping[first] */ |
93 | unsigned last_to; /* amount of mapping[last] */ | 94 | union { |
95 | unsigned last_to; /* amount of mapping[last] */ | ||
96 | unsigned count2; /* count used in unmarshalling */ | ||
97 | }; | ||
94 | unsigned char unmarshall; /* unmarshalling phase */ | 98 | unsigned char unmarshall; /* unmarshalling phase */ |
95 | bool incoming; /* T if incoming call */ | 99 | bool incoming; /* T if incoming call */ |
96 | bool send_pages; /* T if data from mapping should be sent */ | 100 | bool send_pages; /* T if data from mapping should be sent */ |
@@ -127,12 +131,11 @@ struct afs_call_type { | |||
127 | */ | 131 | */ |
128 | struct afs_read { | 132 | struct afs_read { |
129 | loff_t pos; /* Where to start reading */ | 133 | loff_t pos; /* Where to start reading */ |
130 | loff_t len; /* How much to read */ | 134 | loff_t len; /* How much we're asking for */ |
131 | loff_t actual_len; /* How much we're actually getting */ | 135 | loff_t actual_len; /* How much we're actually getting */ |
136 | loff_t remain; /* Amount remaining */ | ||
132 | atomic_t usage; | 137 | atomic_t usage; |
133 | unsigned int remain; /* Amount remaining */ | ||
134 | unsigned int index; /* Which page we're reading into */ | 138 | unsigned int index; /* Which page we're reading into */ |
135 | unsigned int pg_offset; /* Offset in page we're at */ | ||
136 | unsigned int nr_pages; | 139 | unsigned int nr_pages; |
137 | void (*page_done)(struct afs_call *, struct afs_read *); | 140 | void (*page_done)(struct afs_call *, struct afs_read *); |
138 | struct page *pages[]; | 141 | struct page *pages[]; |
@@ -247,7 +250,7 @@ struct afs_cache_vhash { | |||
247 | */ | 250 | */ |
248 | struct afs_vlocation { | 251 | struct afs_vlocation { |
249 | atomic_t usage; | 252 | atomic_t usage; |
250 | time_t time_of_death; /* time at which put reduced usage to 0 */ | 253 | time64_t time_of_death; /* time at which put reduced usage to 0 */ |
251 | struct list_head link; /* link in cell volume location list */ | 254 | struct list_head link; /* link in cell volume location list */ |
252 | struct list_head grave; /* link in master graveyard list */ | 255 | struct list_head grave; /* link in master graveyard list */ |
253 | struct list_head update; /* link in master update list */ | 256 | struct list_head update; /* link in master update list */ |
@@ -258,7 +261,7 @@ struct afs_vlocation { | |||
258 | struct afs_cache_vlocation vldb; /* volume information DB record */ | 261 | struct afs_cache_vlocation vldb; /* volume information DB record */ |
259 | struct afs_volume *vols[3]; /* volume access record pointer (index by type) */ | 262 | struct afs_volume *vols[3]; /* volume access record pointer (index by type) */ |
260 | wait_queue_head_t waitq; /* status change waitqueue */ | 263 | wait_queue_head_t waitq; /* status change waitqueue */ |
261 | time_t update_at; /* time at which record should be updated */ | 264 | time64_t update_at; /* time at which record should be updated */ |
262 | spinlock_t lock; /* access lock */ | 265 | spinlock_t lock; /* access lock */ |
263 | afs_vlocation_state_t state; /* volume location state */ | 266 | afs_vlocation_state_t state; /* volume location state */ |
264 | unsigned short upd_rej_cnt; /* ENOMEDIUM count during update */ | 267 | unsigned short upd_rej_cnt; /* ENOMEDIUM count during update */ |
@@ -271,7 +274,7 @@ struct afs_vlocation { | |||
271 | */ | 274 | */ |
272 | struct afs_server { | 275 | struct afs_server { |
273 | atomic_t usage; | 276 | atomic_t usage; |
274 | time_t time_of_death; /* time at which put reduced usage to 0 */ | 277 | time64_t time_of_death; /* time at which put reduced usage to 0 */ |
275 | struct in_addr addr; /* server address */ | 278 | struct in_addr addr; /* server address */ |
276 | struct afs_cell *cell; /* cell in which server resides */ | 279 | struct afs_cell *cell; /* cell in which server resides */ |
277 | struct list_head link; /* link in cell's server list */ | 280 | struct list_head link; /* link in cell's server list */ |
@@ -374,8 +377,8 @@ struct afs_vnode { | |||
374 | struct rb_node server_rb; /* link in server->fs_vnodes */ | 377 | struct rb_node server_rb; /* link in server->fs_vnodes */ |
375 | struct rb_node cb_promise; /* link in server->cb_promises */ | 378 | struct rb_node cb_promise; /* link in server->cb_promises */ |
376 | struct work_struct cb_broken_work; /* work to be done on callback break */ | 379 | struct work_struct cb_broken_work; /* work to be done on callback break */ |
377 | time_t cb_expires; /* time at which callback expires */ | 380 | time64_t cb_expires; /* time at which callback expires */ |
378 | time_t cb_expires_at; /* time used to order cb_promise */ | 381 | time64_t cb_expires_at; /* time used to order cb_promise */ |
379 | unsigned cb_version; /* callback version */ | 382 | unsigned cb_version; /* callback version */ |
380 | unsigned cb_expiry; /* callback expiry time */ | 383 | unsigned cb_expiry; /* callback expiry time */ |
381 | afs_callback_type_t cb_type; /* type of callback */ | 384 | afs_callback_type_t cb_type; /* type of callback */ |
@@ -557,7 +560,6 @@ extern const struct inode_operations afs_autocell_inode_operations; | |||
557 | extern const struct file_operations afs_mntpt_file_operations; | 560 | extern const struct file_operations afs_mntpt_file_operations; |
558 | 561 | ||
559 | extern struct vfsmount *afs_d_automount(struct path *); | 562 | extern struct vfsmount *afs_d_automount(struct path *); |
560 | extern int afs_mntpt_check_symlink(struct afs_vnode *, struct key *); | ||
561 | extern void afs_mntpt_kill_timer(void); | 563 | extern void afs_mntpt_kill_timer(void); |
562 | 564 | ||
563 | /* | 565 | /* |
@@ -718,6 +720,7 @@ extern int afs_writepages(struct address_space *, struct writeback_control *); | |||
718 | extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *); | 720 | extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *); |
719 | extern ssize_t afs_file_write(struct kiocb *, struct iov_iter *); | 721 | extern ssize_t afs_file_write(struct kiocb *, struct iov_iter *); |
720 | extern int afs_writeback_all(struct afs_vnode *); | 722 | extern int afs_writeback_all(struct afs_vnode *); |
723 | extern int afs_flush(struct file *, fl_owner_t); | ||
721 | extern int afs_fsync(struct file *, loff_t, loff_t, int); | 724 | extern int afs_fsync(struct file *, loff_t, loff_t, int); |
722 | 725 | ||
723 | 726 | ||
diff --git a/fs/afs/misc.c b/fs/afs/misc.c index 91ea1aa0d8b3..100b207efc9e 100644 --- a/fs/afs/misc.c +++ b/fs/afs/misc.c | |||
@@ -84,6 +84,8 @@ int afs_abort_to_error(u32 abort_code) | |||
84 | case RXKADDATALEN: return -EKEYREJECTED; | 84 | case RXKADDATALEN: return -EKEYREJECTED; |
85 | case RXKADILLEGALLEVEL: return -EKEYREJECTED; | 85 | case RXKADILLEGALLEVEL: return -EKEYREJECTED; |
86 | 86 | ||
87 | case RXGEN_OPCODE: return -ENOTSUPP; | ||
88 | |||
87 | default: return -EREMOTEIO; | 89 | default: return -EREMOTEIO; |
88 | } | 90 | } |
89 | } | 91 | } |
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c index d4fb0afc0097..bd3b65cde282 100644 --- a/fs/afs/mntpt.c +++ b/fs/afs/mntpt.c | |||
@@ -47,59 +47,6 @@ static DECLARE_DELAYED_WORK(afs_mntpt_expiry_timer, afs_mntpt_expiry_timed_out); | |||
47 | static unsigned long afs_mntpt_expiry_timeout = 10 * 60; | 47 | static unsigned long afs_mntpt_expiry_timeout = 10 * 60; |
48 | 48 | ||
49 | /* | 49 | /* |
50 | * check a symbolic link to see whether it actually encodes a mountpoint | ||
51 | * - sets the AFS_VNODE_MOUNTPOINT flag on the vnode appropriately | ||
52 | */ | ||
53 | int afs_mntpt_check_symlink(struct afs_vnode *vnode, struct key *key) | ||
54 | { | ||
55 | struct page *page; | ||
56 | size_t size; | ||
57 | char *buf; | ||
58 | int ret; | ||
59 | |||
60 | _enter("{%x:%u,%u}", | ||
61 | vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); | ||
62 | |||
63 | /* read the contents of the symlink into the pagecache */ | ||
64 | page = read_cache_page(AFS_VNODE_TO_I(vnode)->i_mapping, 0, | ||
65 | afs_page_filler, key); | ||
66 | if (IS_ERR(page)) { | ||
67 | ret = PTR_ERR(page); | ||
68 | goto out; | ||
69 | } | ||
70 | |||
71 | ret = -EIO; | ||
72 | if (PageError(page)) | ||
73 | goto out_free; | ||
74 | |||
75 | buf = kmap(page); | ||
76 | |||
77 | /* examine the symlink's contents */ | ||
78 | size = vnode->status.size; | ||
79 | _debug("symlink to %*.*s", (int) size, (int) size, buf); | ||
80 | |||
81 | if (size > 2 && | ||
82 | (buf[0] == '%' || buf[0] == '#') && | ||
83 | buf[size - 1] == '.' | ||
84 | ) { | ||
85 | _debug("symlink is a mountpoint"); | ||
86 | spin_lock(&vnode->lock); | ||
87 | set_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags); | ||
88 | vnode->vfs_inode.i_flags |= S_AUTOMOUNT; | ||
89 | spin_unlock(&vnode->lock); | ||
90 | } | ||
91 | |||
92 | ret = 0; | ||
93 | |||
94 | kunmap(page); | ||
95 | out_free: | ||
96 | put_page(page); | ||
97 | out: | ||
98 | _leave(" = %d", ret); | ||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * no valid lookup procedure on this sort of dir | 50 | * no valid lookup procedure on this sort of dir |
104 | */ | 51 | */ |
105 | static struct dentry *afs_mntpt_lookup(struct inode *dir, | 52 | static struct dentry *afs_mntpt_lookup(struct inode *dir, |
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index 419ef05dcb5e..8f76b13d5549 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c | |||
@@ -259,67 +259,74 @@ void afs_flat_call_destructor(struct afs_call *call) | |||
259 | call->buffer = NULL; | 259 | call->buffer = NULL; |
260 | } | 260 | } |
261 | 261 | ||
262 | #define AFS_BVEC_MAX 8 | ||
263 | |||
264 | /* | ||
265 | * Load the given bvec with the next few pages. | ||
266 | */ | ||
267 | static void afs_load_bvec(struct afs_call *call, struct msghdr *msg, | ||
268 | struct bio_vec *bv, pgoff_t first, pgoff_t last, | ||
269 | unsigned offset) | ||
270 | { | ||
271 | struct page *pages[AFS_BVEC_MAX]; | ||
272 | unsigned int nr, n, i, to, bytes = 0; | ||
273 | |||
274 | nr = min_t(pgoff_t, last - first + 1, AFS_BVEC_MAX); | ||
275 | n = find_get_pages_contig(call->mapping, first, nr, pages); | ||
276 | ASSERTCMP(n, ==, nr); | ||
277 | |||
278 | msg->msg_flags |= MSG_MORE; | ||
279 | for (i = 0; i < nr; i++) { | ||
280 | to = PAGE_SIZE; | ||
281 | if (first + i >= last) { | ||
282 | to = call->last_to; | ||
283 | msg->msg_flags &= ~MSG_MORE; | ||
284 | } | ||
285 | bv[i].bv_page = pages[i]; | ||
286 | bv[i].bv_len = to - offset; | ||
287 | bv[i].bv_offset = offset; | ||
288 | bytes += to - offset; | ||
289 | offset = 0; | ||
290 | } | ||
291 | |||
292 | iov_iter_bvec(&msg->msg_iter, WRITE | ITER_BVEC, bv, nr, bytes); | ||
293 | } | ||
294 | |||
262 | /* | 295 | /* |
263 | * attach the data from a bunch of pages on an inode to a call | 296 | * attach the data from a bunch of pages on an inode to a call |
264 | */ | 297 | */ |
265 | static int afs_send_pages(struct afs_call *call, struct msghdr *msg) | 298 | static int afs_send_pages(struct afs_call *call, struct msghdr *msg) |
266 | { | 299 | { |
267 | struct page *pages[8]; | 300 | struct bio_vec bv[AFS_BVEC_MAX]; |
268 | unsigned count, n, loop, offset, to; | 301 | unsigned int bytes, nr, loop, offset; |
269 | pgoff_t first = call->first, last = call->last; | 302 | pgoff_t first = call->first, last = call->last; |
270 | int ret; | 303 | int ret; |
271 | 304 | ||
272 | _enter(""); | ||
273 | |||
274 | offset = call->first_offset; | 305 | offset = call->first_offset; |
275 | call->first_offset = 0; | 306 | call->first_offset = 0; |
276 | 307 | ||
277 | do { | 308 | do { |
278 | _debug("attach %lx-%lx", first, last); | 309 | afs_load_bvec(call, msg, bv, first, last, offset); |
279 | 310 | offset = 0; | |
280 | count = last - first + 1; | 311 | bytes = msg->msg_iter.count; |
281 | if (count > ARRAY_SIZE(pages)) | 312 | nr = msg->msg_iter.nr_segs; |
282 | count = ARRAY_SIZE(pages); | 313 | |
283 | n = find_get_pages_contig(call->mapping, first, count, pages); | 314 | /* Have to change the state *before* sending the last |
284 | ASSERTCMP(n, ==, count); | 315 | * packet as RxRPC might give us the reply before it |
285 | 316 | * returns from sending the request. | |
286 | loop = 0; | 317 | */ |
287 | do { | 318 | if (first + nr - 1 >= last) |
288 | struct bio_vec bvec = {.bv_page = pages[loop], | 319 | call->state = AFS_CALL_AWAIT_REPLY; |
289 | .bv_offset = offset}; | 320 | ret = rxrpc_kernel_send_data(afs_socket, call->rxcall, |
290 | msg->msg_flags = 0; | 321 | msg, bytes); |
291 | to = PAGE_SIZE; | 322 | for (loop = 0; loop < nr; loop++) |
292 | if (first + loop >= last) | 323 | put_page(bv[loop].bv_page); |
293 | to = call->last_to; | ||
294 | else | ||
295 | msg->msg_flags = MSG_MORE; | ||
296 | bvec.bv_len = to - offset; | ||
297 | offset = 0; | ||
298 | |||
299 | _debug("- range %u-%u%s", | ||
300 | offset, to, msg->msg_flags ? " [more]" : ""); | ||
301 | iov_iter_bvec(&msg->msg_iter, WRITE | ITER_BVEC, | ||
302 | &bvec, 1, to - offset); | ||
303 | |||
304 | /* have to change the state *before* sending the last | ||
305 | * packet as RxRPC might give us the reply before it | ||
306 | * returns from sending the request */ | ||
307 | if (first + loop >= last) | ||
308 | call->state = AFS_CALL_AWAIT_REPLY; | ||
309 | ret = rxrpc_kernel_send_data(afs_socket, call->rxcall, | ||
310 | msg, to - offset); | ||
311 | if (ret < 0) | ||
312 | break; | ||
313 | } while (++loop < count); | ||
314 | first += count; | ||
315 | |||
316 | for (loop = 0; loop < count; loop++) | ||
317 | put_page(pages[loop]); | ||
318 | if (ret < 0) | 324 | if (ret < 0) |
319 | break; | 325 | break; |
326 | |||
327 | first += nr; | ||
320 | } while (first <= last); | 328 | } while (first <= last); |
321 | 329 | ||
322 | _leave(" = %d", ret); | ||
323 | return ret; | 330 | return ret; |
324 | } | 331 | } |
325 | 332 | ||
@@ -333,6 +340,8 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp, | |||
333 | struct rxrpc_call *rxcall; | 340 | struct rxrpc_call *rxcall; |
334 | struct msghdr msg; | 341 | struct msghdr msg; |
335 | struct kvec iov[1]; | 342 | struct kvec iov[1]; |
343 | size_t offset; | ||
344 | u32 abort_code; | ||
336 | int ret; | 345 | int ret; |
337 | 346 | ||
338 | _enter("%x,{%d},", addr->s_addr, ntohs(call->port)); | 347 | _enter("%x,{%d},", addr->s_addr, ntohs(call->port)); |
@@ -381,9 +390,11 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp, | |||
381 | msg.msg_controllen = 0; | 390 | msg.msg_controllen = 0; |
382 | msg.msg_flags = (call->send_pages ? MSG_MORE : 0); | 391 | msg.msg_flags = (call->send_pages ? MSG_MORE : 0); |
383 | 392 | ||
384 | /* have to change the state *before* sending the last packet as RxRPC | 393 | /* We have to change the state *before* sending the last packet as |
385 | * might give us the reply before it returns from sending the | 394 | * rxrpc might give us the reply before it returns from sending the |
386 | * request */ | 395 | * request. Further, if the send fails, we may already have been given |
396 | * a notification and may have collected it. | ||
397 | */ | ||
387 | if (!call->send_pages) | 398 | if (!call->send_pages) |
388 | call->state = AFS_CALL_AWAIT_REPLY; | 399 | call->state = AFS_CALL_AWAIT_REPLY; |
389 | ret = rxrpc_kernel_send_data(afs_socket, rxcall, | 400 | ret = rxrpc_kernel_send_data(afs_socket, rxcall, |
@@ -405,7 +416,17 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp, | |||
405 | return afs_wait_for_call_to_complete(call); | 416 | return afs_wait_for_call_to_complete(call); |
406 | 417 | ||
407 | error_do_abort: | 418 | error_do_abort: |
408 | rxrpc_kernel_abort_call(afs_socket, rxcall, RX_USER_ABORT, -ret, "KSD"); | 419 | call->state = AFS_CALL_COMPLETE; |
420 | if (ret != -ECONNABORTED) { | ||
421 | rxrpc_kernel_abort_call(afs_socket, rxcall, RX_USER_ABORT, | ||
422 | -ret, "KSD"); | ||
423 | } else { | ||
424 | abort_code = 0; | ||
425 | offset = 0; | ||
426 | rxrpc_kernel_recv_data(afs_socket, rxcall, NULL, 0, &offset, | ||
427 | false, &abort_code); | ||
428 | ret = call->type->abort_to_error(abort_code); | ||
429 | } | ||
409 | error_kill_call: | 430 | error_kill_call: |
410 | afs_put_call(call); | 431 | afs_put_call(call); |
411 | _leave(" = %d", ret); | 432 | _leave(" = %d", ret); |
@@ -452,16 +473,18 @@ static void afs_deliver_to_call(struct afs_call *call) | |||
452 | case -EINPROGRESS: | 473 | case -EINPROGRESS: |
453 | case -EAGAIN: | 474 | case -EAGAIN: |
454 | goto out; | 475 | goto out; |
476 | case -ECONNABORTED: | ||
477 | goto call_complete; | ||
455 | case -ENOTCONN: | 478 | case -ENOTCONN: |
456 | abort_code = RX_CALL_DEAD; | 479 | abort_code = RX_CALL_DEAD; |
457 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, | 480 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, |
458 | abort_code, -ret, "KNC"); | 481 | abort_code, -ret, "KNC"); |
459 | goto do_abort; | 482 | goto save_error; |
460 | case -ENOTSUPP: | 483 | case -ENOTSUPP: |
461 | abort_code = RX_INVALID_OPERATION; | 484 | abort_code = RXGEN_OPCODE; |
462 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, | 485 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, |
463 | abort_code, -ret, "KIV"); | 486 | abort_code, -ret, "KIV"); |
464 | goto do_abort; | 487 | goto save_error; |
465 | case -ENODATA: | 488 | case -ENODATA: |
466 | case -EBADMSG: | 489 | case -EBADMSG: |
467 | case -EMSGSIZE: | 490 | case -EMSGSIZE: |
@@ -471,7 +494,7 @@ static void afs_deliver_to_call(struct afs_call *call) | |||
471 | abort_code = RXGEN_SS_UNMARSHAL; | 494 | abort_code = RXGEN_SS_UNMARSHAL; |
472 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, | 495 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, |
473 | abort_code, EBADMSG, "KUM"); | 496 | abort_code, EBADMSG, "KUM"); |
474 | goto do_abort; | 497 | goto save_error; |
475 | } | 498 | } |
476 | } | 499 | } |
477 | 500 | ||
@@ -482,8 +505,9 @@ out: | |||
482 | _leave(""); | 505 | _leave(""); |
483 | return; | 506 | return; |
484 | 507 | ||
485 | do_abort: | 508 | save_error: |
486 | call->error = ret; | 509 | call->error = ret; |
510 | call_complete: | ||
487 | call->state = AFS_CALL_COMPLETE; | 511 | call->state = AFS_CALL_COMPLETE; |
488 | goto done; | 512 | goto done; |
489 | } | 513 | } |
@@ -493,7 +517,6 @@ do_abort: | |||
493 | */ | 517 | */ |
494 | static int afs_wait_for_call_to_complete(struct afs_call *call) | 518 | static int afs_wait_for_call_to_complete(struct afs_call *call) |
495 | { | 519 | { |
496 | const char *abort_why; | ||
497 | int ret; | 520 | int ret; |
498 | 521 | ||
499 | DECLARE_WAITQUEUE(myself, current); | 522 | DECLARE_WAITQUEUE(myself, current); |
@@ -512,13 +535,8 @@ static int afs_wait_for_call_to_complete(struct afs_call *call) | |||
512 | continue; | 535 | continue; |
513 | } | 536 | } |
514 | 537 | ||
515 | abort_why = "KWC"; | 538 | if (call->state == AFS_CALL_COMPLETE || |
516 | ret = call->error; | 539 | signal_pending(current)) |
517 | if (call->state == AFS_CALL_COMPLETE) | ||
518 | break; | ||
519 | abort_why = "KWI"; | ||
520 | ret = -EINTR; | ||
521 | if (signal_pending(current)) | ||
522 | break; | 540 | break; |
523 | schedule(); | 541 | schedule(); |
524 | } | 542 | } |
@@ -526,13 +544,14 @@ static int afs_wait_for_call_to_complete(struct afs_call *call) | |||
526 | remove_wait_queue(&call->waitq, &myself); | 544 | remove_wait_queue(&call->waitq, &myself); |
527 | __set_current_state(TASK_RUNNING); | 545 | __set_current_state(TASK_RUNNING); |
528 | 546 | ||
529 | /* kill the call */ | 547 | /* Kill off the call if it's still live. */ |
530 | if (call->state < AFS_CALL_COMPLETE) { | 548 | if (call->state < AFS_CALL_COMPLETE) { |
531 | _debug("call incomplete"); | 549 | _debug("call interrupted"); |
532 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, | 550 | rxrpc_kernel_abort_call(afs_socket, call->rxcall, |
533 | RX_CALL_DEAD, -ret, abort_why); | 551 | RX_USER_ABORT, -EINTR, "KWI"); |
534 | } | 552 | } |
535 | 553 | ||
554 | ret = call->error; | ||
536 | _debug("call complete"); | 555 | _debug("call complete"); |
537 | afs_put_call(call); | 556 | afs_put_call(call); |
538 | _leave(" = %d", ret); | 557 | _leave(" = %d", ret); |
diff --git a/fs/afs/security.c b/fs/afs/security.c index 8d010422dc89..ecb86a670180 100644 --- a/fs/afs/security.c +++ b/fs/afs/security.c | |||
@@ -114,7 +114,7 @@ void afs_clear_permits(struct afs_vnode *vnode) | |||
114 | 114 | ||
115 | mutex_lock(&vnode->permits_lock); | 115 | mutex_lock(&vnode->permits_lock); |
116 | permits = vnode->permits; | 116 | permits = vnode->permits; |
117 | rcu_assign_pointer(vnode->permits, NULL); | 117 | RCU_INIT_POINTER(vnode->permits, NULL); |
118 | mutex_unlock(&vnode->permits_lock); | 118 | mutex_unlock(&vnode->permits_lock); |
119 | 119 | ||
120 | if (permits) | 120 | if (permits) |
@@ -340,17 +340,22 @@ int afs_permission(struct inode *inode, int mask) | |||
340 | } else { | 340 | } else { |
341 | if (!(access & AFS_ACE_LOOKUP)) | 341 | if (!(access & AFS_ACE_LOOKUP)) |
342 | goto permission_denied; | 342 | goto permission_denied; |
343 | if ((mask & MAY_EXEC) && !(inode->i_mode & S_IXUSR)) | ||
344 | goto permission_denied; | ||
343 | if (mask & (MAY_EXEC | MAY_READ)) { | 345 | if (mask & (MAY_EXEC | MAY_READ)) { |
344 | if (!(access & AFS_ACE_READ)) | 346 | if (!(access & AFS_ACE_READ)) |
345 | goto permission_denied; | 347 | goto permission_denied; |
348 | if (!(inode->i_mode & S_IRUSR)) | ||
349 | goto permission_denied; | ||
346 | } else if (mask & MAY_WRITE) { | 350 | } else if (mask & MAY_WRITE) { |
347 | if (!(access & AFS_ACE_WRITE)) | 351 | if (!(access & AFS_ACE_WRITE)) |
348 | goto permission_denied; | 352 | goto permission_denied; |
353 | if (!(inode->i_mode & S_IWUSR)) | ||
354 | goto permission_denied; | ||
349 | } | 355 | } |
350 | } | 356 | } |
351 | 357 | ||
352 | key_put(key); | 358 | key_put(key); |
353 | ret = generic_permission(inode, mask); | ||
354 | _leave(" = %d", ret); | 359 | _leave(" = %d", ret); |
355 | return ret; | 360 | return ret; |
356 | 361 | ||
diff --git a/fs/afs/server.c b/fs/afs/server.c index d4066ab7dd55..c001b1f2455f 100644 --- a/fs/afs/server.c +++ b/fs/afs/server.c | |||
@@ -242,7 +242,7 @@ void afs_put_server(struct afs_server *server) | |||
242 | spin_lock(&afs_server_graveyard_lock); | 242 | spin_lock(&afs_server_graveyard_lock); |
243 | if (atomic_read(&server->usage) == 0) { | 243 | if (atomic_read(&server->usage) == 0) { |
244 | list_move_tail(&server->grave, &afs_server_graveyard); | 244 | list_move_tail(&server->grave, &afs_server_graveyard); |
245 | server->time_of_death = get_seconds(); | 245 | server->time_of_death = ktime_get_real_seconds(); |
246 | queue_delayed_work(afs_wq, &afs_server_reaper, | 246 | queue_delayed_work(afs_wq, &afs_server_reaper, |
247 | afs_server_timeout * HZ); | 247 | afs_server_timeout * HZ); |
248 | } | 248 | } |
@@ -277,9 +277,9 @@ static void afs_reap_server(struct work_struct *work) | |||
277 | LIST_HEAD(corpses); | 277 | LIST_HEAD(corpses); |
278 | struct afs_server *server; | 278 | struct afs_server *server; |
279 | unsigned long delay, expiry; | 279 | unsigned long delay, expiry; |
280 | time_t now; | 280 | time64_t now; |
281 | 281 | ||
282 | now = get_seconds(); | 282 | now = ktime_get_real_seconds(); |
283 | spin_lock(&afs_server_graveyard_lock); | 283 | spin_lock(&afs_server_graveyard_lock); |
284 | 284 | ||
285 | while (!list_empty(&afs_server_graveyard)) { | 285 | while (!list_empty(&afs_server_graveyard)) { |
diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c index d7d8dd8c0b31..37b7c3b342a6 100644 --- a/fs/afs/vlocation.c +++ b/fs/afs/vlocation.c | |||
@@ -340,7 +340,8 @@ static void afs_vlocation_queue_for_updates(struct afs_vlocation *vl) | |||
340 | struct afs_vlocation *xvl; | 340 | struct afs_vlocation *xvl; |
341 | 341 | ||
342 | /* wait at least 10 minutes before updating... */ | 342 | /* wait at least 10 minutes before updating... */ |
343 | vl->update_at = get_seconds() + afs_vlocation_update_timeout; | 343 | vl->update_at = ktime_get_real_seconds() + |
344 | afs_vlocation_update_timeout; | ||
344 | 345 | ||
345 | spin_lock(&afs_vlocation_updates_lock); | 346 | spin_lock(&afs_vlocation_updates_lock); |
346 | 347 | ||
@@ -506,7 +507,7 @@ void afs_put_vlocation(struct afs_vlocation *vl) | |||
506 | if (atomic_read(&vl->usage) == 0) { | 507 | if (atomic_read(&vl->usage) == 0) { |
507 | _debug("buried"); | 508 | _debug("buried"); |
508 | list_move_tail(&vl->grave, &afs_vlocation_graveyard); | 509 | list_move_tail(&vl->grave, &afs_vlocation_graveyard); |
509 | vl->time_of_death = get_seconds(); | 510 | vl->time_of_death = ktime_get_real_seconds(); |
510 | queue_delayed_work(afs_wq, &afs_vlocation_reap, | 511 | queue_delayed_work(afs_wq, &afs_vlocation_reap, |
511 | afs_vlocation_timeout * HZ); | 512 | afs_vlocation_timeout * HZ); |
512 | 513 | ||
@@ -543,11 +544,11 @@ static void afs_vlocation_reaper(struct work_struct *work) | |||
543 | LIST_HEAD(corpses); | 544 | LIST_HEAD(corpses); |
544 | struct afs_vlocation *vl; | 545 | struct afs_vlocation *vl; |
545 | unsigned long delay, expiry; | 546 | unsigned long delay, expiry; |
546 | time_t now; | 547 | time64_t now; |
547 | 548 | ||
548 | _enter(""); | 549 | _enter(""); |
549 | 550 | ||
550 | now = get_seconds(); | 551 | now = ktime_get_real_seconds(); |
551 | spin_lock(&afs_vlocation_graveyard_lock); | 552 | spin_lock(&afs_vlocation_graveyard_lock); |
552 | 553 | ||
553 | while (!list_empty(&afs_vlocation_graveyard)) { | 554 | while (!list_empty(&afs_vlocation_graveyard)) { |
@@ -622,13 +623,13 @@ static void afs_vlocation_updater(struct work_struct *work) | |||
622 | { | 623 | { |
623 | struct afs_cache_vlocation vldb; | 624 | struct afs_cache_vlocation vldb; |
624 | struct afs_vlocation *vl, *xvl; | 625 | struct afs_vlocation *vl, *xvl; |
625 | time_t now; | 626 | time64_t now; |
626 | long timeout; | 627 | long timeout; |
627 | int ret; | 628 | int ret; |
628 | 629 | ||
629 | _enter(""); | 630 | _enter(""); |
630 | 631 | ||
631 | now = get_seconds(); | 632 | now = ktime_get_real_seconds(); |
632 | 633 | ||
633 | /* find a record to update */ | 634 | /* find a record to update */ |
634 | spin_lock(&afs_vlocation_updates_lock); | 635 | spin_lock(&afs_vlocation_updates_lock); |
@@ -684,7 +685,8 @@ static void afs_vlocation_updater(struct work_struct *work) | |||
684 | 685 | ||
685 | /* and then reschedule */ | 686 | /* and then reschedule */ |
686 | _debug("reschedule"); | 687 | _debug("reschedule"); |
687 | vl->update_at = get_seconds() + afs_vlocation_update_timeout; | 688 | vl->update_at = ktime_get_real_seconds() + |
689 | afs_vlocation_update_timeout; | ||
688 | 690 | ||
689 | spin_lock(&afs_vlocation_updates_lock); | 691 | spin_lock(&afs_vlocation_updates_lock); |
690 | 692 | ||
diff --git a/fs/afs/write.c b/fs/afs/write.c index c83c1a0e851f..2d2fccd5044b 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c | |||
@@ -84,10 +84,9 @@ void afs_put_writeback(struct afs_writeback *wb) | |||
84 | * partly or wholly fill a page that's under preparation for writing | 84 | * partly or wholly fill a page that's under preparation for writing |
85 | */ | 85 | */ |
86 | static int afs_fill_page(struct afs_vnode *vnode, struct key *key, | 86 | static int afs_fill_page(struct afs_vnode *vnode, struct key *key, |
87 | loff_t pos, struct page *page) | 87 | loff_t pos, unsigned int len, struct page *page) |
88 | { | 88 | { |
89 | struct afs_read *req; | 89 | struct afs_read *req; |
90 | loff_t i_size; | ||
91 | int ret; | 90 | int ret; |
92 | 91 | ||
93 | _enter(",,%llu", (unsigned long long)pos); | 92 | _enter(",,%llu", (unsigned long long)pos); |
@@ -99,14 +98,10 @@ static int afs_fill_page(struct afs_vnode *vnode, struct key *key, | |||
99 | 98 | ||
100 | atomic_set(&req->usage, 1); | 99 | atomic_set(&req->usage, 1); |
101 | req->pos = pos; | 100 | req->pos = pos; |
101 | req->len = len; | ||
102 | req->nr_pages = 1; | 102 | req->nr_pages = 1; |
103 | req->pages[0] = page; | 103 | req->pages[0] = page; |
104 | 104 | get_page(page); | |
105 | i_size = i_size_read(&vnode->vfs_inode); | ||
106 | if (pos + PAGE_SIZE > i_size) | ||
107 | req->len = i_size - pos; | ||
108 | else | ||
109 | req->len = PAGE_SIZE; | ||
110 | 105 | ||
111 | ret = afs_vnode_fetch_data(vnode, key, req); | 106 | ret = afs_vnode_fetch_data(vnode, key, req); |
112 | afs_put_read(req); | 107 | afs_put_read(req); |
@@ -159,12 +154,12 @@ int afs_write_begin(struct file *file, struct address_space *mapping, | |||
159 | kfree(candidate); | 154 | kfree(candidate); |
160 | return -ENOMEM; | 155 | return -ENOMEM; |
161 | } | 156 | } |
162 | *pagep = page; | ||
163 | /* page won't leak in error case: it eventually gets cleaned off LRU */ | ||
164 | 157 | ||
165 | if (!PageUptodate(page) && len != PAGE_SIZE) { | 158 | if (!PageUptodate(page) && len != PAGE_SIZE) { |
166 | ret = afs_fill_page(vnode, key, index << PAGE_SHIFT, page); | 159 | ret = afs_fill_page(vnode, key, pos & PAGE_MASK, PAGE_SIZE, page); |
167 | if (ret < 0) { | 160 | if (ret < 0) { |
161 | unlock_page(page); | ||
162 | put_page(page); | ||
168 | kfree(candidate); | 163 | kfree(candidate); |
169 | _leave(" = %d [prep]", ret); | 164 | _leave(" = %d [prep]", ret); |
170 | return ret; | 165 | return ret; |
@@ -172,6 +167,9 @@ int afs_write_begin(struct file *file, struct address_space *mapping, | |||
172 | SetPageUptodate(page); | 167 | SetPageUptodate(page); |
173 | } | 168 | } |
174 | 169 | ||
170 | /* page won't leak in error case: it eventually gets cleaned off LRU */ | ||
171 | *pagep = page; | ||
172 | |||
175 | try_again: | 173 | try_again: |
176 | spin_lock(&vnode->writeback_lock); | 174 | spin_lock(&vnode->writeback_lock); |
177 | 175 | ||
@@ -233,7 +231,7 @@ flush_conflicting_wb: | |||
233 | if (wb->state == AFS_WBACK_PENDING) | 231 | if (wb->state == AFS_WBACK_PENDING) |
234 | wb->state = AFS_WBACK_CONFLICTING; | 232 | wb->state = AFS_WBACK_CONFLICTING; |
235 | spin_unlock(&vnode->writeback_lock); | 233 | spin_unlock(&vnode->writeback_lock); |
236 | if (PageDirty(page)) { | 234 | if (clear_page_dirty_for_io(page)) { |
237 | ret = afs_write_back_from_locked_page(wb, page); | 235 | ret = afs_write_back_from_locked_page(wb, page); |
238 | if (ret < 0) { | 236 | if (ret < 0) { |
239 | afs_put_writeback(candidate); | 237 | afs_put_writeback(candidate); |
@@ -257,7 +255,9 @@ int afs_write_end(struct file *file, struct address_space *mapping, | |||
257 | struct page *page, void *fsdata) | 255 | struct page *page, void *fsdata) |
258 | { | 256 | { |
259 | struct afs_vnode *vnode = AFS_FS_I(file_inode(file)); | 257 | struct afs_vnode *vnode = AFS_FS_I(file_inode(file)); |
258 | struct key *key = file->private_data; | ||
260 | loff_t i_size, maybe_i_size; | 259 | loff_t i_size, maybe_i_size; |
260 | int ret; | ||
261 | 261 | ||
262 | _enter("{%x:%u},{%lx}", | 262 | _enter("{%x:%u},{%lx}", |
263 | vnode->fid.vid, vnode->fid.vnode, page->index); | 263 | vnode->fid.vid, vnode->fid.vnode, page->index); |
@@ -273,6 +273,20 @@ int afs_write_end(struct file *file, struct address_space *mapping, | |||
273 | spin_unlock(&vnode->writeback_lock); | 273 | spin_unlock(&vnode->writeback_lock); |
274 | } | 274 | } |
275 | 275 | ||
276 | if (!PageUptodate(page)) { | ||
277 | if (copied < len) { | ||
278 | /* Try and load any missing data from the server. The | ||
279 | * unmarshalling routine will take care of clearing any | ||
280 | * bits that are beyond the EOF. | ||
281 | */ | ||
282 | ret = afs_fill_page(vnode, key, pos + copied, | ||
283 | len - copied, page); | ||
284 | if (ret < 0) | ||
285 | return ret; | ||
286 | } | ||
287 | SetPageUptodate(page); | ||
288 | } | ||
289 | |||
276 | set_page_dirty(page); | 290 | set_page_dirty(page); |
277 | if (PageDirty(page)) | 291 | if (PageDirty(page)) |
278 | _debug("dirtied"); | 292 | _debug("dirtied"); |
@@ -307,10 +321,14 @@ static void afs_kill_pages(struct afs_vnode *vnode, bool error, | |||
307 | ASSERTCMP(pv.nr, ==, count); | 321 | ASSERTCMP(pv.nr, ==, count); |
308 | 322 | ||
309 | for (loop = 0; loop < count; loop++) { | 323 | for (loop = 0; loop < count; loop++) { |
310 | ClearPageUptodate(pv.pages[loop]); | 324 | struct page *page = pv.pages[loop]; |
325 | ClearPageUptodate(page); | ||
311 | if (error) | 326 | if (error) |
312 | SetPageError(pv.pages[loop]); | 327 | SetPageError(page); |
313 | end_page_writeback(pv.pages[loop]); | 328 | if (PageWriteback(page)) |
329 | end_page_writeback(page); | ||
330 | if (page->index >= first) | ||
331 | first = page->index + 1; | ||
314 | } | 332 | } |
315 | 333 | ||
316 | __pagevec_release(&pv); | 334 | __pagevec_release(&pv); |
@@ -335,8 +353,6 @@ static int afs_write_back_from_locked_page(struct afs_writeback *wb, | |||
335 | _enter(",%lx", primary_page->index); | 353 | _enter(",%lx", primary_page->index); |
336 | 354 | ||
337 | count = 1; | 355 | count = 1; |
338 | if (!clear_page_dirty_for_io(primary_page)) | ||
339 | BUG(); | ||
340 | if (test_set_page_writeback(primary_page)) | 356 | if (test_set_page_writeback(primary_page)) |
341 | BUG(); | 357 | BUG(); |
342 | 358 | ||
@@ -502,17 +518,17 @@ static int afs_writepages_region(struct address_space *mapping, | |||
502 | */ | 518 | */ |
503 | lock_page(page); | 519 | lock_page(page); |
504 | 520 | ||
505 | if (page->mapping != mapping) { | 521 | if (page->mapping != mapping || !PageDirty(page)) { |
506 | unlock_page(page); | 522 | unlock_page(page); |
507 | put_page(page); | 523 | put_page(page); |
508 | continue; | 524 | continue; |
509 | } | 525 | } |
510 | 526 | ||
511 | if (wbc->sync_mode != WB_SYNC_NONE) | 527 | if (PageWriteback(page)) { |
512 | wait_on_page_writeback(page); | ||
513 | |||
514 | if (PageWriteback(page) || !PageDirty(page)) { | ||
515 | unlock_page(page); | 528 | unlock_page(page); |
529 | if (wbc->sync_mode != WB_SYNC_NONE) | ||
530 | wait_on_page_writeback(page); | ||
531 | put_page(page); | ||
516 | continue; | 532 | continue; |
517 | } | 533 | } |
518 | 534 | ||
@@ -523,6 +539,8 @@ static int afs_writepages_region(struct address_space *mapping, | |||
523 | wb->state = AFS_WBACK_WRITING; | 539 | wb->state = AFS_WBACK_WRITING; |
524 | spin_unlock(&wb->vnode->writeback_lock); | 540 | spin_unlock(&wb->vnode->writeback_lock); |
525 | 541 | ||
542 | if (!clear_page_dirty_for_io(page)) | ||
543 | BUG(); | ||
526 | ret = afs_write_back_from_locked_page(wb, page); | 544 | ret = afs_write_back_from_locked_page(wb, page); |
527 | unlock_page(page); | 545 | unlock_page(page); |
528 | put_page(page); | 546 | put_page(page); |
@@ -746,6 +764,20 @@ out: | |||
746 | } | 764 | } |
747 | 765 | ||
748 | /* | 766 | /* |
767 | * Flush out all outstanding writes on a file opened for writing when it is | ||
768 | * closed. | ||
769 | */ | ||
770 | int afs_flush(struct file *file, fl_owner_t id) | ||
771 | { | ||
772 | _enter(""); | ||
773 | |||
774 | if ((file->f_mode & FMODE_WRITE) == 0) | ||
775 | return 0; | ||
776 | |||
777 | return vfs_fsync(file, 0); | ||
778 | } | ||
779 | |||
780 | /* | ||
749 | * notification that a previously read-only page is about to become writable | 781 | * notification that a previously read-only page is about to become writable |
750 | * - if it returns an error, the caller will deliver a bus error signal | 782 | * - if it returns an error, the caller will deliver a bus error signal |
751 | */ | 783 | */ |
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 7d398d300e97..9382db998ec9 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c | |||
@@ -743,7 +743,7 @@ static int tcp_accept_from_sock(struct connection *con) | |||
743 | newsock->type = con->sock->type; | 743 | newsock->type = con->sock->type; |
744 | newsock->ops = con->sock->ops; | 744 | newsock->ops = con->sock->ops; |
745 | 745 | ||
746 | result = con->sock->ops->accept(con->sock, newsock, O_NONBLOCK); | 746 | result = con->sock->ops->accept(con->sock, newsock, O_NONBLOCK, true); |
747 | if (result < 0) | 747 | if (result < 0) |
748 | goto accept_err; | 748 | goto accept_err; |
749 | 749 | ||
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index ef600591d96f..63ee2940775c 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -173,19 +173,33 @@ static void wb_wakeup(struct bdi_writeback *wb) | |||
173 | spin_unlock_bh(&wb->work_lock); | 173 | spin_unlock_bh(&wb->work_lock); |
174 | } | 174 | } |
175 | 175 | ||
176 | static void finish_writeback_work(struct bdi_writeback *wb, | ||
177 | struct wb_writeback_work *work) | ||
178 | { | ||
179 | struct wb_completion *done = work->done; | ||
180 | |||
181 | if (work->auto_free) | ||
182 | kfree(work); | ||
183 | if (done && atomic_dec_and_test(&done->cnt)) | ||
184 | wake_up_all(&wb->bdi->wb_waitq); | ||
185 | } | ||
186 | |||
176 | static void wb_queue_work(struct bdi_writeback *wb, | 187 | static void wb_queue_work(struct bdi_writeback *wb, |
177 | struct wb_writeback_work *work) | 188 | struct wb_writeback_work *work) |
178 | { | 189 | { |
179 | trace_writeback_queue(wb, work); | 190 | trace_writeback_queue(wb, work); |
180 | 191 | ||
181 | spin_lock_bh(&wb->work_lock); | ||
182 | if (!test_bit(WB_registered, &wb->state)) | ||
183 | goto out_unlock; | ||
184 | if (work->done) | 192 | if (work->done) |
185 | atomic_inc(&work->done->cnt); | 193 | atomic_inc(&work->done->cnt); |
186 | list_add_tail(&work->list, &wb->work_list); | 194 | |
187 | mod_delayed_work(bdi_wq, &wb->dwork, 0); | 195 | spin_lock_bh(&wb->work_lock); |
188 | out_unlock: | 196 | |
197 | if (test_bit(WB_registered, &wb->state)) { | ||
198 | list_add_tail(&work->list, &wb->work_list); | ||
199 | mod_delayed_work(bdi_wq, &wb->dwork, 0); | ||
200 | } else | ||
201 | finish_writeback_work(wb, work); | ||
202 | |||
189 | spin_unlock_bh(&wb->work_lock); | 203 | spin_unlock_bh(&wb->work_lock); |
190 | } | 204 | } |
191 | 205 | ||
@@ -1873,16 +1887,9 @@ static long wb_do_writeback(struct bdi_writeback *wb) | |||
1873 | 1887 | ||
1874 | set_bit(WB_writeback_running, &wb->state); | 1888 | set_bit(WB_writeback_running, &wb->state); |
1875 | while ((work = get_next_work_item(wb)) != NULL) { | 1889 | while ((work = get_next_work_item(wb)) != NULL) { |
1876 | struct wb_completion *done = work->done; | ||
1877 | |||
1878 | trace_writeback_exec(wb, work); | 1890 | trace_writeback_exec(wb, work); |
1879 | |||
1880 | wrote += wb_writeback(wb, work); | 1891 | wrote += wb_writeback(wb, work); |
1881 | 1892 | finish_writeback_work(wb, work); | |
1882 | if (work->auto_free) | ||
1883 | kfree(work); | ||
1884 | if (done && atomic_dec_and_test(&done->cnt)) | ||
1885 | wake_up_all(&wb->bdi->wb_waitq); | ||
1886 | } | 1893 | } |
1887 | 1894 | ||
1888 | /* | 1895 | /* |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index c45084ac642d..511e1ed7e2de 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -207,7 +207,7 @@ struct lm_lockname { | |||
207 | struct gfs2_sbd *ln_sbd; | 207 | struct gfs2_sbd *ln_sbd; |
208 | u64 ln_number; | 208 | u64 ln_number; |
209 | unsigned int ln_type; | 209 | unsigned int ln_type; |
210 | }; | 210 | } __packed __aligned(sizeof(int)); |
211 | 211 | ||
212 | #define lm_name_equal(name1, name2) \ | 212 | #define lm_name_equal(name1, name2) \ |
213 | (((name1)->ln_number == (name2)->ln_number) && \ | 213 | (((name1)->ln_number == (name2)->ln_number) && \ |
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index bb79972dc638..773774531aff 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -232,12 +232,12 @@ static struct svc_serv_ops nfs41_cb_sv_ops = { | |||
232 | .svo_module = THIS_MODULE, | 232 | .svo_module = THIS_MODULE, |
233 | }; | 233 | }; |
234 | 234 | ||
235 | struct svc_serv_ops *nfs4_cb_sv_ops[] = { | 235 | static struct svc_serv_ops *nfs4_cb_sv_ops[] = { |
236 | [0] = &nfs40_cb_sv_ops, | 236 | [0] = &nfs40_cb_sv_ops, |
237 | [1] = &nfs41_cb_sv_ops, | 237 | [1] = &nfs41_cb_sv_ops, |
238 | }; | 238 | }; |
239 | #else | 239 | #else |
240 | struct svc_serv_ops *nfs4_cb_sv_ops[] = { | 240 | static struct svc_serv_ops *nfs4_cb_sv_ops[] = { |
241 | [0] = &nfs40_cb_sv_ops, | 241 | [0] = &nfs40_cb_sv_ops, |
242 | [1] = NULL, | 242 | [1] = NULL, |
243 | }; | 243 | }; |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 91a8d610ba0f..390ada8741bc 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -325,10 +325,33 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat | |||
325 | return NULL; | 325 | return NULL; |
326 | } | 326 | } |
327 | 327 | ||
328 | static bool nfs_client_init_is_complete(const struct nfs_client *clp) | 328 | /* |
329 | * Return true if @clp is done initializing, false if still working on it. | ||
330 | * | ||
331 | * Use nfs_client_init_status to check if it was successful. | ||
332 | */ | ||
333 | bool nfs_client_init_is_complete(const struct nfs_client *clp) | ||
329 | { | 334 | { |
330 | return clp->cl_cons_state <= NFS_CS_READY; | 335 | return clp->cl_cons_state <= NFS_CS_READY; |
331 | } | 336 | } |
337 | EXPORT_SYMBOL_GPL(nfs_client_init_is_complete); | ||
338 | |||
339 | /* | ||
340 | * Return 0 if @clp was successfully initialized, -errno otherwise. | ||
341 | * | ||
342 | * This must be called *after* nfs_client_init_is_complete() returns true, | ||
343 | * otherwise it will pop WARN_ON_ONCE and return -EINVAL | ||
344 | */ | ||
345 | int nfs_client_init_status(const struct nfs_client *clp) | ||
346 | { | ||
347 | /* called without checking nfs_client_init_is_complete */ | ||
348 | if (clp->cl_cons_state > NFS_CS_READY) { | ||
349 | WARN_ON_ONCE(1); | ||
350 | return -EINVAL; | ||
351 | } | ||
352 | return clp->cl_cons_state; | ||
353 | } | ||
354 | EXPORT_SYMBOL_GPL(nfs_client_init_status); | ||
332 | 355 | ||
333 | int nfs_wait_client_init_complete(const struct nfs_client *clp) | 356 | int nfs_wait_client_init_complete(const struct nfs_client *clp) |
334 | { | 357 | { |
diff --git a/fs/nfs/filelayout/filelayoutdev.c b/fs/nfs/filelayout/filelayoutdev.c index f956ca20a8a3..d913e818858f 100644 --- a/fs/nfs/filelayout/filelayoutdev.c +++ b/fs/nfs/filelayout/filelayoutdev.c | |||
@@ -266,6 +266,7 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx) | |||
266 | struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg); | 266 | struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg); |
267 | struct nfs4_pnfs_ds *ret = ds; | 267 | struct nfs4_pnfs_ds *ret = ds; |
268 | struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode); | 268 | struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode); |
269 | int status; | ||
269 | 270 | ||
270 | if (ds == NULL) { | 271 | if (ds == NULL) { |
271 | printk(KERN_ERR "NFS: %s: No data server for offset index %d\n", | 272 | printk(KERN_ERR "NFS: %s: No data server for offset index %d\n", |
@@ -277,9 +278,14 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx) | |||
277 | if (ds->ds_clp) | 278 | if (ds->ds_clp) |
278 | goto out_test_devid; | 279 | goto out_test_devid; |
279 | 280 | ||
280 | nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo, | 281 | status = nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo, |
281 | dataserver_retrans, 4, | 282 | dataserver_retrans, 4, |
282 | s->nfs_client->cl_minorversion); | 283 | s->nfs_client->cl_minorversion); |
284 | if (status) { | ||
285 | nfs4_mark_deviceid_unavailable(devid); | ||
286 | ret = NULL; | ||
287 | goto out; | ||
288 | } | ||
283 | 289 | ||
284 | out_test_devid: | 290 | out_test_devid: |
285 | if (ret->ds_clp == NULL || | 291 | if (ret->ds_clp == NULL || |
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.h b/fs/nfs/flexfilelayout/flexfilelayout.h index f4f39b0ab09b..98b34c9b0564 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.h +++ b/fs/nfs/flexfilelayout/flexfilelayout.h | |||
@@ -175,7 +175,19 @@ ff_layout_no_read_on_rw(struct pnfs_layout_segment *lseg) | |||
175 | static inline bool | 175 | static inline bool |
176 | ff_layout_test_devid_unavailable(struct nfs4_deviceid_node *node) | 176 | ff_layout_test_devid_unavailable(struct nfs4_deviceid_node *node) |
177 | { | 177 | { |
178 | return nfs4_test_deviceid_unavailable(node); | 178 | /* |
179 | * Flexfiles should never mark a DS unavailable, but if it does | ||
180 | * print a (ratelimited) warning as this can affect performance. | ||
181 | */ | ||
182 | if (nfs4_test_deviceid_unavailable(node)) { | ||
183 | u32 *p = (u32 *)node->deviceid.data; | ||
184 | |||
185 | pr_warn_ratelimited("NFS: flexfiles layout referencing an " | ||
186 | "unavailable device [%x%x%x%x]\n", | ||
187 | p[0], p[1], p[2], p[3]); | ||
188 | return true; | ||
189 | } | ||
190 | return false; | ||
179 | } | 191 | } |
180 | 192 | ||
181 | static inline int | 193 | static inline int |
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c index e5a6f248697b..85fde93dff77 100644 --- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c +++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c | |||
@@ -384,6 +384,7 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx, | |||
384 | struct inode *ino = lseg->pls_layout->plh_inode; | 384 | struct inode *ino = lseg->pls_layout->plh_inode; |
385 | struct nfs_server *s = NFS_SERVER(ino); | 385 | struct nfs_server *s = NFS_SERVER(ino); |
386 | unsigned int max_payload; | 386 | unsigned int max_payload; |
387 | int status; | ||
387 | 388 | ||
388 | if (!ff_layout_mirror_valid(lseg, mirror, true)) { | 389 | if (!ff_layout_mirror_valid(lseg, mirror, true)) { |
389 | pr_err_ratelimited("NFS: %s: No data server for offset index %d\n", | 390 | pr_err_ratelimited("NFS: %s: No data server for offset index %d\n", |
@@ -404,7 +405,7 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx, | |||
404 | /* FIXME: For now we assume the server sent only one version of NFS | 405 | /* FIXME: For now we assume the server sent only one version of NFS |
405 | * to use for the DS. | 406 | * to use for the DS. |
406 | */ | 407 | */ |
407 | nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo, | 408 | status = nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo, |
408 | dataserver_retrans, | 409 | dataserver_retrans, |
409 | mirror->mirror_ds->ds_versions[0].version, | 410 | mirror->mirror_ds->ds_versions[0].version, |
410 | mirror->mirror_ds->ds_versions[0].minor_version); | 411 | mirror->mirror_ds->ds_versions[0].minor_version); |
@@ -420,11 +421,11 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx, | |||
420 | mirror->mirror_ds->ds_versions[0].wsize = max_payload; | 421 | mirror->mirror_ds->ds_versions[0].wsize = max_payload; |
421 | goto out; | 422 | goto out; |
422 | } | 423 | } |
424 | out_fail: | ||
423 | ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout), | 425 | ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout), |
424 | mirror, lseg->pls_range.offset, | 426 | mirror, lseg->pls_range.offset, |
425 | lseg->pls_range.length, NFS4ERR_NXIO, | 427 | lseg->pls_range.length, NFS4ERR_NXIO, |
426 | OP_ILLEGAL, GFP_NOIO); | 428 | OP_ILLEGAL, GFP_NOIO); |
427 | out_fail: | ||
428 | if (fail_return || !ff_layout_has_available_ds(lseg)) | 429 | if (fail_return || !ff_layout_has_available_ds(lseg)) |
429 | pnfs_error_mark_layout_for_return(ino, lseg); | 430 | pnfs_error_mark_layout_for_return(ino, lseg); |
430 | ds = NULL; | 431 | ds = NULL; |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 09ca5095c04e..7b38fedb7e03 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -186,6 +186,8 @@ extern struct nfs_server *nfs_clone_server(struct nfs_server *, | |||
186 | struct nfs_fh *, | 186 | struct nfs_fh *, |
187 | struct nfs_fattr *, | 187 | struct nfs_fattr *, |
188 | rpc_authflavor_t); | 188 | rpc_authflavor_t); |
189 | extern bool nfs_client_init_is_complete(const struct nfs_client *clp); | ||
190 | extern int nfs_client_init_status(const struct nfs_client *clp); | ||
189 | extern int nfs_wait_client_init_complete(const struct nfs_client *clp); | 191 | extern int nfs_wait_client_init_complete(const struct nfs_client *clp); |
190 | extern void nfs_mark_client_ready(struct nfs_client *clp, int state); | 192 | extern void nfs_mark_client_ready(struct nfs_client *clp, int state); |
191 | extern struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv, | 193 | extern struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv, |
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 5ae9d64ea08b..8346ccbf2d52 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c | |||
@@ -1023,9 +1023,9 @@ static void nfs4_session_set_rwsize(struct nfs_server *server) | |||
1023 | server_resp_sz = sess->fc_attrs.max_resp_sz - nfs41_maxread_overhead; | 1023 | server_resp_sz = sess->fc_attrs.max_resp_sz - nfs41_maxread_overhead; |
1024 | server_rqst_sz = sess->fc_attrs.max_rqst_sz - nfs41_maxwrite_overhead; | 1024 | server_rqst_sz = sess->fc_attrs.max_rqst_sz - nfs41_maxwrite_overhead; |
1025 | 1025 | ||
1026 | if (server->rsize > server_resp_sz) | 1026 | if (!server->rsize || server->rsize > server_resp_sz) |
1027 | server->rsize = server_resp_sz; | 1027 | server->rsize = server_resp_sz; |
1028 | if (server->wsize > server_rqst_sz) | 1028 | if (!server->wsize || server->wsize > server_rqst_sz) |
1029 | server->wsize = server_rqst_sz; | 1029 | server->wsize = server_rqst_sz; |
1030 | #endif /* CONFIG_NFS_V4_1 */ | 1030 | #endif /* CONFIG_NFS_V4_1 */ |
1031 | } | 1031 | } |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 1b183686c6d4..c780d98035cc 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2258,8 +2258,6 @@ static int nfs4_opendata_access(struct rpc_cred *cred, | |||
2258 | if ((mask & ~cache.mask & (MAY_READ | MAY_EXEC)) == 0) | 2258 | if ((mask & ~cache.mask & (MAY_READ | MAY_EXEC)) == 0) |
2259 | return 0; | 2259 | return 0; |
2260 | 2260 | ||
2261 | /* even though OPEN succeeded, access is denied. Close the file */ | ||
2262 | nfs4_close_state(state, fmode); | ||
2263 | return -EACCES; | 2261 | return -EACCES; |
2264 | } | 2262 | } |
2265 | 2263 | ||
@@ -7427,11 +7425,11 @@ static void nfs4_exchange_id_release(void *data) | |||
7427 | struct nfs41_exchange_id_data *cdata = | 7425 | struct nfs41_exchange_id_data *cdata = |
7428 | (struct nfs41_exchange_id_data *)data; | 7426 | (struct nfs41_exchange_id_data *)data; |
7429 | 7427 | ||
7430 | nfs_put_client(cdata->args.client); | ||
7431 | if (cdata->xprt) { | 7428 | if (cdata->xprt) { |
7432 | xprt_put(cdata->xprt); | 7429 | xprt_put(cdata->xprt); |
7433 | rpc_clnt_xprt_switch_put(cdata->args.client->cl_rpcclient); | 7430 | rpc_clnt_xprt_switch_put(cdata->args.client->cl_rpcclient); |
7434 | } | 7431 | } |
7432 | nfs_put_client(cdata->args.client); | ||
7435 | kfree(cdata->res.impl_id); | 7433 | kfree(cdata->res.impl_id); |
7436 | kfree(cdata->res.server_scope); | 7434 | kfree(cdata->res.server_scope); |
7437 | kfree(cdata->res.server_owner); | 7435 | kfree(cdata->res.server_owner); |
@@ -7538,10 +7536,8 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred, | |||
7538 | task_setup_data.callback_data = calldata; | 7536 | task_setup_data.callback_data = calldata; |
7539 | 7537 | ||
7540 | task = rpc_run_task(&task_setup_data); | 7538 | task = rpc_run_task(&task_setup_data); |
7541 | if (IS_ERR(task)) { | 7539 | if (IS_ERR(task)) |
7542 | status = PTR_ERR(task); | 7540 | return PTR_ERR(task); |
7543 | goto out_impl_id; | ||
7544 | } | ||
7545 | 7541 | ||
7546 | if (!xprt) { | 7542 | if (!xprt) { |
7547 | status = rpc_wait_for_completion_task(task); | 7543 | status = rpc_wait_for_completion_task(task); |
@@ -7569,6 +7565,7 @@ out_server_owner: | |||
7569 | kfree(calldata->res.server_owner); | 7565 | kfree(calldata->res.server_owner); |
7570 | out_calldata: | 7566 | out_calldata: |
7571 | kfree(calldata); | 7567 | kfree(calldata); |
7568 | nfs_put_client(clp); | ||
7572 | goto out; | 7569 | goto out; |
7573 | } | 7570 | } |
7574 | 7571 | ||
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index f0369e362753..80ce289eea05 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -3942,7 +3942,7 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, | |||
3942 | if (len <= 0) | 3942 | if (len <= 0) |
3943 | goto out; | 3943 | goto out; |
3944 | dprintk("%s: name=%s\n", __func__, group_name->data); | 3944 | dprintk("%s: name=%s\n", __func__, group_name->data); |
3945 | return NFS_ATTR_FATTR_OWNER_NAME; | 3945 | return NFS_ATTR_FATTR_GROUP_NAME; |
3946 | } else { | 3946 | } else { |
3947 | len = xdr_stream_decode_opaque_inline(xdr, (void **)&p, | 3947 | len = xdr_stream_decode_opaque_inline(xdr, (void **)&p, |
3948 | XDR_MAX_NETOBJ); | 3948 | XDR_MAX_NETOBJ); |
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 63f77b49a586..590e1e35781f 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h | |||
@@ -367,7 +367,7 @@ void nfs4_pnfs_ds_put(struct nfs4_pnfs_ds *ds); | |||
367 | struct nfs4_pnfs_ds *nfs4_pnfs_ds_add(struct list_head *dsaddrs, | 367 | struct nfs4_pnfs_ds *nfs4_pnfs_ds_add(struct list_head *dsaddrs, |
368 | gfp_t gfp_flags); | 368 | gfp_t gfp_flags); |
369 | void nfs4_pnfs_v3_ds_connect_unload(void); | 369 | void nfs4_pnfs_v3_ds_connect_unload(void); |
370 | void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, | 370 | int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, |
371 | struct nfs4_deviceid_node *devid, unsigned int timeo, | 371 | struct nfs4_deviceid_node *devid, unsigned int timeo, |
372 | unsigned int retrans, u32 version, u32 minor_version); | 372 | unsigned int retrans, u32 version, u32 minor_version); |
373 | struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net, | 373 | struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net, |
diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c index 9414b492439f..7250b95549ec 100644 --- a/fs/nfs/pnfs_nfs.c +++ b/fs/nfs/pnfs_nfs.c | |||
@@ -745,15 +745,17 @@ out: | |||
745 | /* | 745 | /* |
746 | * Create an rpc connection to the nfs4_pnfs_ds data server. | 746 | * Create an rpc connection to the nfs4_pnfs_ds data server. |
747 | * Currently only supports IPv4 and IPv6 addresses. | 747 | * Currently only supports IPv4 and IPv6 addresses. |
748 | * If connection fails, make devid unavailable. | 748 | * If connection fails, make devid unavailable and return a -errno. |
749 | */ | 749 | */ |
750 | void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, | 750 | int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, |
751 | struct nfs4_deviceid_node *devid, unsigned int timeo, | 751 | struct nfs4_deviceid_node *devid, unsigned int timeo, |
752 | unsigned int retrans, u32 version, u32 minor_version) | 752 | unsigned int retrans, u32 version, u32 minor_version) |
753 | { | 753 | { |
754 | if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) { | 754 | int err; |
755 | int err = 0; | ||
756 | 755 | ||
756 | again: | ||
757 | err = 0; | ||
758 | if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) { | ||
757 | if (version == 3) { | 759 | if (version == 3) { |
758 | err = _nfs4_pnfs_v3_ds_connect(mds_srv, ds, timeo, | 760 | err = _nfs4_pnfs_v3_ds_connect(mds_srv, ds, timeo, |
759 | retrans); | 761 | retrans); |
@@ -766,12 +768,29 @@ void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, | |||
766 | err = -EPROTONOSUPPORT; | 768 | err = -EPROTONOSUPPORT; |
767 | } | 769 | } |
768 | 770 | ||
769 | if (err) | ||
770 | nfs4_mark_deviceid_unavailable(devid); | ||
771 | nfs4_clear_ds_conn_bit(ds); | 771 | nfs4_clear_ds_conn_bit(ds); |
772 | } else { | 772 | } else { |
773 | nfs4_wait_ds_connect(ds); | 773 | nfs4_wait_ds_connect(ds); |
774 | |||
775 | /* what was waited on didn't connect AND didn't mark unavail */ | ||
776 | if (!ds->ds_clp && !nfs4_test_deviceid_unavailable(devid)) | ||
777 | goto again; | ||
774 | } | 778 | } |
779 | |||
780 | /* | ||
781 | * At this point the ds->ds_clp should be ready, but it might have | ||
782 | * hit an error. | ||
783 | */ | ||
784 | if (!err) { | ||
785 | if (!ds->ds_clp || !nfs_client_init_is_complete(ds->ds_clp)) { | ||
786 | WARN_ON_ONCE(ds->ds_clp || | ||
787 | !nfs4_test_deviceid_unavailable(devid)); | ||
788 | return -EINVAL; | ||
789 | } | ||
790 | err = nfs_client_init_status(ds->ds_clp); | ||
791 | } | ||
792 | |||
793 | return err; | ||
775 | } | 794 | } |
776 | EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_connect); | 795 | EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_connect); |
777 | 796 | ||
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index e75b056f46f4..abb2c8a3be42 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -1784,7 +1784,8 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data) | |||
1784 | (long long)req_offset(req)); | 1784 | (long long)req_offset(req)); |
1785 | if (status < 0) { | 1785 | if (status < 0) { |
1786 | nfs_context_set_write_error(req->wb_context, status); | 1786 | nfs_context_set_write_error(req->wb_context, status); |
1787 | nfs_inode_remove_request(req); | 1787 | if (req->wb_page) |
1788 | nfs_inode_remove_request(req); | ||
1788 | dprintk_cont(", error = %d\n", status); | 1789 | dprintk_cont(", error = %d\n", status); |
1789 | goto next; | 1790 | goto next; |
1790 | } | 1791 | } |
@@ -1793,7 +1794,8 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data) | |||
1793 | * returned by the server against all stored verfs. */ | 1794 | * returned by the server against all stored verfs. */ |
1794 | if (!nfs_write_verifier_cmp(&req->wb_verf, &data->verf.verifier)) { | 1795 | if (!nfs_write_verifier_cmp(&req->wb_verf, &data->verf.verifier)) { |
1795 | /* We have a match */ | 1796 | /* We have a match */ |
1796 | nfs_inode_remove_request(req); | 1797 | if (req->wb_page) |
1798 | nfs_inode_remove_request(req); | ||
1797 | dprintk_cont(" OK\n"); | 1799 | dprintk_cont(" OK\n"); |
1798 | goto next; | 1800 | goto next; |
1799 | } | 1801 | } |
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 4348027384f5..d0ab7e56d0b4 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
@@ -1863,7 +1863,7 @@ static int o2net_accept_one(struct socket *sock, int *more) | |||
1863 | 1863 | ||
1864 | new_sock->type = sock->type; | 1864 | new_sock->type = sock->type; |
1865 | new_sock->ops = sock->ops; | 1865 | new_sock->ops = sock->ops; |
1866 | ret = sock->ops->accept(sock, new_sock, O_NONBLOCK); | 1866 | ret = sock->ops->accept(sock, new_sock, O_NONBLOCK, false); |
1867 | if (ret < 0) | 1867 | if (ret < 0) |
1868 | goto out; | 1868 | goto out; |
1869 | 1869 | ||
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h index d04547fcf274..eb00bc133bca 100644 --- a/fs/xfs/libxfs/xfs_dir2_priv.h +++ b/fs/xfs/libxfs/xfs_dir2_priv.h | |||
@@ -125,6 +125,8 @@ extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino); | |||
125 | extern int xfs_dir2_sf_lookup(struct xfs_da_args *args); | 125 | extern int xfs_dir2_sf_lookup(struct xfs_da_args *args); |
126 | extern int xfs_dir2_sf_removename(struct xfs_da_args *args); | 126 | extern int xfs_dir2_sf_removename(struct xfs_da_args *args); |
127 | extern int xfs_dir2_sf_replace(struct xfs_da_args *args); | 127 | extern int xfs_dir2_sf_replace(struct xfs_da_args *args); |
128 | extern int xfs_dir2_sf_verify(struct xfs_mount *mp, struct xfs_dir2_sf_hdr *sfp, | ||
129 | int size); | ||
128 | 130 | ||
129 | /* xfs_dir2_readdir.c */ | 131 | /* xfs_dir2_readdir.c */ |
130 | extern int xfs_readdir(struct xfs_inode *dp, struct dir_context *ctx, | 132 | extern int xfs_readdir(struct xfs_inode *dp, struct dir_context *ctx, |
diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c index c6809ff41197..96b45cd6c63f 100644 --- a/fs/xfs/libxfs/xfs_dir2_sf.c +++ b/fs/xfs/libxfs/xfs_dir2_sf.c | |||
@@ -629,6 +629,93 @@ xfs_dir2_sf_check( | |||
629 | } | 629 | } |
630 | #endif /* DEBUG */ | 630 | #endif /* DEBUG */ |
631 | 631 | ||
632 | /* Verify the consistency of an inline directory. */ | ||
633 | int | ||
634 | xfs_dir2_sf_verify( | ||
635 | struct xfs_mount *mp, | ||
636 | struct xfs_dir2_sf_hdr *sfp, | ||
637 | int size) | ||
638 | { | ||
639 | struct xfs_dir2_sf_entry *sfep; | ||
640 | struct xfs_dir2_sf_entry *next_sfep; | ||
641 | char *endp; | ||
642 | const struct xfs_dir_ops *dops; | ||
643 | xfs_ino_t ino; | ||
644 | int i; | ||
645 | int i8count; | ||
646 | int offset; | ||
647 | __uint8_t filetype; | ||
648 | |||
649 | dops = xfs_dir_get_ops(mp, NULL); | ||
650 | |||
651 | /* | ||
652 | * Give up if the directory is way too short. | ||
653 | */ | ||
654 | XFS_WANT_CORRUPTED_RETURN(mp, size > | ||
655 | offsetof(struct xfs_dir2_sf_hdr, parent)); | ||
656 | XFS_WANT_CORRUPTED_RETURN(mp, size >= | ||
657 | xfs_dir2_sf_hdr_size(sfp->i8count)); | ||
658 | |||
659 | endp = (char *)sfp + size; | ||
660 | |||
661 | /* Check .. entry */ | ||
662 | ino = dops->sf_get_parent_ino(sfp); | ||
663 | i8count = ino > XFS_DIR2_MAX_SHORT_INUM; | ||
664 | XFS_WANT_CORRUPTED_RETURN(mp, !xfs_dir_ino_validate(mp, ino)); | ||
665 | offset = dops->data_first_offset; | ||
666 | |||
667 | /* Check all reported entries */ | ||
668 | sfep = xfs_dir2_sf_firstentry(sfp); | ||
669 | for (i = 0; i < sfp->count; i++) { | ||
670 | /* | ||
671 | * struct xfs_dir2_sf_entry has a variable length. | ||
672 | * Check the fixed-offset parts of the structure are | ||
673 | * within the data buffer. | ||
674 | */ | ||
675 | XFS_WANT_CORRUPTED_RETURN(mp, | ||
676 | ((char *)sfep + sizeof(*sfep)) < endp); | ||
677 | |||
678 | /* Don't allow names with known bad length. */ | ||
679 | XFS_WANT_CORRUPTED_RETURN(mp, sfep->namelen > 0); | ||
680 | XFS_WANT_CORRUPTED_RETURN(mp, sfep->namelen < MAXNAMELEN); | ||
681 | |||
682 | /* | ||
683 | * Check that the variable-length part of the structure is | ||
684 | * within the data buffer. The next entry starts after the | ||
685 | * name component, so nextentry is an acceptable test. | ||
686 | */ | ||
687 | next_sfep = dops->sf_nextentry(sfp, sfep); | ||
688 | XFS_WANT_CORRUPTED_RETURN(mp, endp >= (char *)next_sfep); | ||
689 | |||
690 | /* Check that the offsets always increase. */ | ||
691 | XFS_WANT_CORRUPTED_RETURN(mp, | ||
692 | xfs_dir2_sf_get_offset(sfep) >= offset); | ||
693 | |||
694 | /* Check the inode number. */ | ||
695 | ino = dops->sf_get_ino(sfp, sfep); | ||
696 | i8count += ino > XFS_DIR2_MAX_SHORT_INUM; | ||
697 | XFS_WANT_CORRUPTED_RETURN(mp, !xfs_dir_ino_validate(mp, ino)); | ||
698 | |||
699 | /* Check the file type. */ | ||
700 | filetype = dops->sf_get_ftype(sfep); | ||
701 | XFS_WANT_CORRUPTED_RETURN(mp, filetype < XFS_DIR3_FT_MAX); | ||
702 | |||
703 | offset = xfs_dir2_sf_get_offset(sfep) + | ||
704 | dops->data_entsize(sfep->namelen); | ||
705 | |||
706 | sfep = next_sfep; | ||
707 | } | ||
708 | XFS_WANT_CORRUPTED_RETURN(mp, i8count == sfp->i8count); | ||
709 | XFS_WANT_CORRUPTED_RETURN(mp, (void *)sfep == (void *)endp); | ||
710 | |||
711 | /* Make sure this whole thing ought to be in local format. */ | ||
712 | XFS_WANT_CORRUPTED_RETURN(mp, offset + | ||
713 | (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) + | ||
714 | (uint)sizeof(xfs_dir2_block_tail_t) <= mp->m_dir_geo->blksize); | ||
715 | |||
716 | return 0; | ||
717 | } | ||
718 | |||
632 | /* | 719 | /* |
633 | * Create a new (shortform) directory. | 720 | * Create a new (shortform) directory. |
634 | */ | 721 | */ |
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c index 25c1e078aef6..9653e964eda4 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.c +++ b/fs/xfs/libxfs/xfs_inode_fork.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include "xfs_trace.h" | 33 | #include "xfs_trace.h" |
34 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
35 | #include "xfs_da_format.h" | 35 | #include "xfs_da_format.h" |
36 | #include "xfs_da_btree.h" | ||
37 | #include "xfs_dir2_priv.h" | ||
36 | 38 | ||
37 | kmem_zone_t *xfs_ifork_zone; | 39 | kmem_zone_t *xfs_ifork_zone; |
38 | 40 | ||
@@ -320,6 +322,7 @@ xfs_iformat_local( | |||
320 | int whichfork, | 322 | int whichfork, |
321 | int size) | 323 | int size) |
322 | { | 324 | { |
325 | int error; | ||
323 | 326 | ||
324 | /* | 327 | /* |
325 | * If the size is unreasonable, then something | 328 | * If the size is unreasonable, then something |
@@ -336,6 +339,14 @@ xfs_iformat_local( | |||
336 | return -EFSCORRUPTED; | 339 | return -EFSCORRUPTED; |
337 | } | 340 | } |
338 | 341 | ||
342 | if (S_ISDIR(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK) { | ||
343 | error = xfs_dir2_sf_verify(ip->i_mount, | ||
344 | (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip), | ||
345 | size); | ||
346 | if (error) | ||
347 | return error; | ||
348 | } | ||
349 | |||
339 | xfs_init_local_fork(ip, whichfork, XFS_DFORK_PTR(dip, whichfork), size); | 350 | xfs_init_local_fork(ip, whichfork, XFS_DFORK_PTR(dip, whichfork), size); |
340 | return 0; | 351 | return 0; |
341 | } | 352 | } |
@@ -856,7 +867,7 @@ xfs_iextents_copy( | |||
856 | * In these cases, the format always takes precedence, because the | 867 | * In these cases, the format always takes precedence, because the |
857 | * format indicates the current state of the fork. | 868 | * format indicates the current state of the fork. |
858 | */ | 869 | */ |
859 | void | 870 | int |
860 | xfs_iflush_fork( | 871 | xfs_iflush_fork( |
861 | xfs_inode_t *ip, | 872 | xfs_inode_t *ip, |
862 | xfs_dinode_t *dip, | 873 | xfs_dinode_t *dip, |
@@ -866,6 +877,7 @@ xfs_iflush_fork( | |||
866 | char *cp; | 877 | char *cp; |
867 | xfs_ifork_t *ifp; | 878 | xfs_ifork_t *ifp; |
868 | xfs_mount_t *mp; | 879 | xfs_mount_t *mp; |
880 | int error; | ||
869 | static const short brootflag[2] = | 881 | static const short brootflag[2] = |
870 | { XFS_ILOG_DBROOT, XFS_ILOG_ABROOT }; | 882 | { XFS_ILOG_DBROOT, XFS_ILOG_ABROOT }; |
871 | static const short dataflag[2] = | 883 | static const short dataflag[2] = |
@@ -874,7 +886,7 @@ xfs_iflush_fork( | |||
874 | { XFS_ILOG_DEXT, XFS_ILOG_AEXT }; | 886 | { XFS_ILOG_DEXT, XFS_ILOG_AEXT }; |
875 | 887 | ||
876 | if (!iip) | 888 | if (!iip) |
877 | return; | 889 | return 0; |
878 | ifp = XFS_IFORK_PTR(ip, whichfork); | 890 | ifp = XFS_IFORK_PTR(ip, whichfork); |
879 | /* | 891 | /* |
880 | * This can happen if we gave up in iformat in an error path, | 892 | * This can happen if we gave up in iformat in an error path, |
@@ -882,12 +894,19 @@ xfs_iflush_fork( | |||
882 | */ | 894 | */ |
883 | if (!ifp) { | 895 | if (!ifp) { |
884 | ASSERT(whichfork == XFS_ATTR_FORK); | 896 | ASSERT(whichfork == XFS_ATTR_FORK); |
885 | return; | 897 | return 0; |
886 | } | 898 | } |
887 | cp = XFS_DFORK_PTR(dip, whichfork); | 899 | cp = XFS_DFORK_PTR(dip, whichfork); |
888 | mp = ip->i_mount; | 900 | mp = ip->i_mount; |
889 | switch (XFS_IFORK_FORMAT(ip, whichfork)) { | 901 | switch (XFS_IFORK_FORMAT(ip, whichfork)) { |
890 | case XFS_DINODE_FMT_LOCAL: | 902 | case XFS_DINODE_FMT_LOCAL: |
903 | if (S_ISDIR(VFS_I(ip)->i_mode) && whichfork == XFS_DATA_FORK) { | ||
904 | error = xfs_dir2_sf_verify(mp, | ||
905 | (struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data, | ||
906 | ifp->if_bytes); | ||
907 | if (error) | ||
908 | return error; | ||
909 | } | ||
891 | if ((iip->ili_fields & dataflag[whichfork]) && | 910 | if ((iip->ili_fields & dataflag[whichfork]) && |
892 | (ifp->if_bytes > 0)) { | 911 | (ifp->if_bytes > 0)) { |
893 | ASSERT(ifp->if_u1.if_data != NULL); | 912 | ASSERT(ifp->if_u1.if_data != NULL); |
@@ -940,6 +959,7 @@ xfs_iflush_fork( | |||
940 | ASSERT(0); | 959 | ASSERT(0); |
941 | break; | 960 | break; |
942 | } | 961 | } |
962 | return 0; | ||
943 | } | 963 | } |
944 | 964 | ||
945 | /* | 965 | /* |
diff --git a/fs/xfs/libxfs/xfs_inode_fork.h b/fs/xfs/libxfs/xfs_inode_fork.h index 7fb8365326d1..132dc59fdde6 100644 --- a/fs/xfs/libxfs/xfs_inode_fork.h +++ b/fs/xfs/libxfs/xfs_inode_fork.h | |||
@@ -140,7 +140,7 @@ typedef struct xfs_ifork { | |||
140 | struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state); | 140 | struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state); |
141 | 141 | ||
142 | int xfs_iformat_fork(struct xfs_inode *, struct xfs_dinode *); | 142 | int xfs_iformat_fork(struct xfs_inode *, struct xfs_dinode *); |
143 | void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, | 143 | int xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, |
144 | struct xfs_inode_log_item *, int); | 144 | struct xfs_inode_log_item *, int); |
145 | void xfs_idestroy_fork(struct xfs_inode *, int); | 145 | void xfs_idestroy_fork(struct xfs_inode *, int); |
146 | void xfs_idata_realloc(struct xfs_inode *, int, int); | 146 | void xfs_idata_realloc(struct xfs_inode *, int, int); |
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index 003a99b83bd8..ad9396e516f6 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c | |||
@@ -71,22 +71,11 @@ xfs_dir2_sf_getdents( | |||
71 | struct xfs_da_geometry *geo = args->geo; | 71 | struct xfs_da_geometry *geo = args->geo; |
72 | 72 | ||
73 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); | 73 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); |
74 | /* | ||
75 | * Give up if the directory is way too short. | ||
76 | */ | ||
77 | if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { | ||
78 | ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); | ||
79 | return -EIO; | ||
80 | } | ||
81 | |||
82 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | 74 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); |
83 | ASSERT(dp->i_df.if_u1.if_data != NULL); | 75 | ASSERT(dp->i_df.if_u1.if_data != NULL); |
84 | 76 | ||
85 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; | 77 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
86 | 78 | ||
87 | if (dp->i_d.di_size < xfs_dir2_sf_hdr_size(sfp->i8count)) | ||
88 | return -EFSCORRUPTED; | ||
89 | |||
90 | /* | 79 | /* |
91 | * If the block number in the offset is out of range, we're done. | 80 | * If the block number in the offset is out of range, we're done. |
92 | */ | 81 | */ |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 7eaf1ef74e3c..c7fe2c2123ab 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -3475,6 +3475,7 @@ xfs_iflush_int( | |||
3475 | struct xfs_inode_log_item *iip = ip->i_itemp; | 3475 | struct xfs_inode_log_item *iip = ip->i_itemp; |
3476 | struct xfs_dinode *dip; | 3476 | struct xfs_dinode *dip; |
3477 | struct xfs_mount *mp = ip->i_mount; | 3477 | struct xfs_mount *mp = ip->i_mount; |
3478 | int error; | ||
3478 | 3479 | ||
3479 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); | 3480 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); |
3480 | ASSERT(xfs_isiflocked(ip)); | 3481 | ASSERT(xfs_isiflocked(ip)); |
@@ -3557,9 +3558,14 @@ xfs_iflush_int( | |||
3557 | if (ip->i_d.di_flushiter == DI_MAX_FLUSH) | 3558 | if (ip->i_d.di_flushiter == DI_MAX_FLUSH) |
3558 | ip->i_d.di_flushiter = 0; | 3559 | ip->i_d.di_flushiter = 0; |
3559 | 3560 | ||
3560 | xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK); | 3561 | error = xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK); |
3561 | if (XFS_IFORK_Q(ip)) | 3562 | if (error) |
3562 | xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK); | 3563 | return error; |
3564 | if (XFS_IFORK_Q(ip)) { | ||
3565 | error = xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK); | ||
3566 | if (error) | ||
3567 | return error; | ||
3568 | } | ||
3563 | xfs_inobp_check(mp, bp); | 3569 | xfs_inobp_check(mp, bp); |
3564 | 3570 | ||
3565 | /* | 3571 | /* |
diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h index a2bfd7843f18..e2b9c6fe2714 100644 --- a/include/crypto/if_alg.h +++ b/include/crypto/if_alg.h | |||
@@ -73,7 +73,7 @@ int af_alg_unregister_type(const struct af_alg_type *type); | |||
73 | 73 | ||
74 | int af_alg_release(struct socket *sock); | 74 | int af_alg_release(struct socket *sock); |
75 | void af_alg_release_parent(struct sock *sk); | 75 | void af_alg_release_parent(struct sock *sk); |
76 | int af_alg_accept(struct sock *sk, struct socket *newsock); | 76 | int af_alg_accept(struct sock *sk, struct socket *newsock, bool kern); |
77 | 77 | ||
78 | int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len); | 78 | int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len); |
79 | void af_alg_free_sg(struct af_alg_sgl *sgl); | 79 | void af_alg_free_sg(struct af_alg_sgl *sgl); |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 673acda012af..9b05886f9773 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -287,18 +287,15 @@ static inline bool invalid_phys_cpuid(phys_cpuid_t phys_id) | |||
287 | } | 287 | } |
288 | 288 | ||
289 | /* Validate the processor object's proc_id */ | 289 | /* Validate the processor object's proc_id */ |
290 | bool acpi_processor_validate_proc_id(int proc_id); | 290 | bool acpi_duplicate_processor_id(int proc_id); |
291 | 291 | ||
292 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | 292 | #ifdef CONFIG_ACPI_HOTPLUG_CPU |
293 | /* Arch dependent functions for cpu hotplug support */ | 293 | /* Arch dependent functions for cpu hotplug support */ |
294 | int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 acpi_id, | 294 | int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 acpi_id, |
295 | int *pcpu); | 295 | int *pcpu); |
296 | int acpi_unmap_cpu(int cpu); | 296 | int acpi_unmap_cpu(int cpu); |
297 | int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid); | ||
298 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ | 297 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ |
299 | 298 | ||
300 | void acpi_set_processor_mapping(void); | ||
301 | |||
302 | #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC | 299 | #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC |
303 | int acpi_get_ioapic_id(acpi_handle handle, u32 gsi_base, u64 *phys_addr); | 300 | int acpi_get_ioapic_id(acpi_handle handle, u32 gsi_base, u64 *phys_addr); |
304 | #endif | 301 | #endif |
diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 61d042bbbf60..68449293c4b6 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h | |||
@@ -163,6 +163,7 @@ struct dccp_request_sock { | |||
163 | __u64 dreq_isr; | 163 | __u64 dreq_isr; |
164 | __u64 dreq_gsr; | 164 | __u64 dreq_gsr; |
165 | __be32 dreq_service; | 165 | __be32 dreq_service; |
166 | spinlock_t dreq_lock; | ||
166 | struct list_head dreq_featneg; | 167 | struct list_head dreq_featneg; |
167 | __u32 dreq_timestamp_echo; | 168 | __u32 dreq_timestamp_echo; |
168 | __u32 dreq_timestamp_time; | 169 | __u32 dreq_timestamp_time; |
diff --git a/include/linux/device.h b/include/linux/device.h index 30c4570e928d..9ef518af5515 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -1140,7 +1140,6 @@ static inline bool device_supports_offline(struct device *dev) | |||
1140 | extern void lock_device_hotplug(void); | 1140 | extern void lock_device_hotplug(void); |
1141 | extern void unlock_device_hotplug(void); | 1141 | extern void unlock_device_hotplug(void); |
1142 | extern int lock_device_hotplug_sysfs(void); | 1142 | extern int lock_device_hotplug_sysfs(void); |
1143 | void assert_held_device_hotplug(void); | ||
1144 | extern int device_offline(struct device *dev); | 1143 | extern int device_offline(struct device *dev); |
1145 | extern int device_online(struct device *dev); | 1144 | extern int device_online(struct device *dev); |
1146 | extern void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode); | 1145 | extern void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode); |
diff --git a/include/linux/filter.h b/include/linux/filter.h index 0c167fdee5f7..fbf7b39e8103 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h | |||
@@ -409,6 +409,7 @@ struct bpf_prog { | |||
409 | u16 pages; /* Number of allocated pages */ | 409 | u16 pages; /* Number of allocated pages */ |
410 | kmemcheck_bitfield_begin(meta); | 410 | kmemcheck_bitfield_begin(meta); |
411 | u16 jited:1, /* Is our filter JIT'ed? */ | 411 | u16 jited:1, /* Is our filter JIT'ed? */ |
412 | locked:1, /* Program image locked? */ | ||
412 | gpl_compatible:1, /* Is filter GPL compatible? */ | 413 | gpl_compatible:1, /* Is filter GPL compatible? */ |
413 | cb_access:1, /* Is control block accessed? */ | 414 | cb_access:1, /* Is control block accessed? */ |
414 | dst_needed:1, /* Do we need dst entry? */ | 415 | dst_needed:1, /* Do we need dst entry? */ |
@@ -554,22 +555,29 @@ static inline bool bpf_prog_was_classic(const struct bpf_prog *prog) | |||
554 | #ifdef CONFIG_ARCH_HAS_SET_MEMORY | 555 | #ifdef CONFIG_ARCH_HAS_SET_MEMORY |
555 | static inline void bpf_prog_lock_ro(struct bpf_prog *fp) | 556 | static inline void bpf_prog_lock_ro(struct bpf_prog *fp) |
556 | { | 557 | { |
557 | set_memory_ro((unsigned long)fp, fp->pages); | 558 | fp->locked = 1; |
559 | WARN_ON_ONCE(set_memory_ro((unsigned long)fp, fp->pages)); | ||
558 | } | 560 | } |
559 | 561 | ||
560 | static inline void bpf_prog_unlock_ro(struct bpf_prog *fp) | 562 | static inline void bpf_prog_unlock_ro(struct bpf_prog *fp) |
561 | { | 563 | { |
562 | set_memory_rw((unsigned long)fp, fp->pages); | 564 | if (fp->locked) { |
565 | WARN_ON_ONCE(set_memory_rw((unsigned long)fp, fp->pages)); | ||
566 | /* In case set_memory_rw() fails, we want to be the first | ||
567 | * to crash here instead of some random place later on. | ||
568 | */ | ||
569 | fp->locked = 0; | ||
570 | } | ||
563 | } | 571 | } |
564 | 572 | ||
565 | static inline void bpf_jit_binary_lock_ro(struct bpf_binary_header *hdr) | 573 | static inline void bpf_jit_binary_lock_ro(struct bpf_binary_header *hdr) |
566 | { | 574 | { |
567 | set_memory_ro((unsigned long)hdr, hdr->pages); | 575 | WARN_ON_ONCE(set_memory_ro((unsigned long)hdr, hdr->pages)); |
568 | } | 576 | } |
569 | 577 | ||
570 | static inline void bpf_jit_binary_unlock_ro(struct bpf_binary_header *hdr) | 578 | static inline void bpf_jit_binary_unlock_ro(struct bpf_binary_header *hdr) |
571 | { | 579 | { |
572 | set_memory_rw((unsigned long)hdr, hdr->pages); | 580 | WARN_ON_ONCE(set_memory_rw((unsigned long)hdr, hdr->pages)); |
573 | } | 581 | } |
574 | #else | 582 | #else |
575 | static inline void bpf_prog_lock_ro(struct bpf_prog *fp) | 583 | static inline void bpf_prog_lock_ro(struct bpf_prog *fp) |
diff --git a/include/linux/kasan.h b/include/linux/kasan.h index 1c823bef4c15..5734480c9590 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h | |||
@@ -6,6 +6,7 @@ | |||
6 | struct kmem_cache; | 6 | struct kmem_cache; |
7 | struct page; | 7 | struct page; |
8 | struct vm_struct; | 8 | struct vm_struct; |
9 | struct task_struct; | ||
9 | 10 | ||
10 | #ifdef CONFIG_KASAN | 11 | #ifdef CONFIG_KASAN |
11 | 12 | ||
diff --git a/include/linux/list_nulls.h b/include/linux/list_nulls.h index b01fe1009084..87ff4f58a2f0 100644 --- a/include/linux/list_nulls.h +++ b/include/linux/list_nulls.h | |||
@@ -29,6 +29,11 @@ struct hlist_nulls_node { | |||
29 | ((ptr)->first = (struct hlist_nulls_node *) NULLS_MARKER(nulls)) | 29 | ((ptr)->first = (struct hlist_nulls_node *) NULLS_MARKER(nulls)) |
30 | 30 | ||
31 | #define hlist_nulls_entry(ptr, type, member) container_of(ptr,type,member) | 31 | #define hlist_nulls_entry(ptr, type, member) container_of(ptr,type,member) |
32 | |||
33 | #define hlist_nulls_entry_safe(ptr, type, member) \ | ||
34 | ({ typeof(ptr) ____ptr = (ptr); \ | ||
35 | !is_a_nulls(____ptr) ? hlist_nulls_entry(____ptr, type, member) : NULL; \ | ||
36 | }) | ||
32 | /** | 37 | /** |
33 | * ptr_is_a_nulls - Test if a ptr is a nulls | 38 | * ptr_is_a_nulls - Test if a ptr is a nulls |
34 | * @ptr: ptr to be tested | 39 | * @ptr: ptr to be tested |
diff --git a/include/linux/net.h b/include/linux/net.h index cd0c8bd0a1de..0620f5e18c96 100644 --- a/include/linux/net.h +++ b/include/linux/net.h | |||
@@ -146,7 +146,7 @@ struct proto_ops { | |||
146 | int (*socketpair)(struct socket *sock1, | 146 | int (*socketpair)(struct socket *sock1, |
147 | struct socket *sock2); | 147 | struct socket *sock2); |
148 | int (*accept) (struct socket *sock, | 148 | int (*accept) (struct socket *sock, |
149 | struct socket *newsock, int flags); | 149 | struct socket *newsock, int flags, bool kern); |
150 | int (*getname) (struct socket *sock, | 150 | int (*getname) (struct socket *sock, |
151 | struct sockaddr *addr, | 151 | struct sockaddr *addr, |
152 | int *sockaddr_len, int peer); | 152 | int *sockaddr_len, int peer); |
diff --git a/include/linux/phy.h b/include/linux/phy.h index 772476028a65..43a774873aa9 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h | |||
@@ -837,6 +837,10 @@ int genphy_read_status(struct phy_device *phydev); | |||
837 | int genphy_suspend(struct phy_device *phydev); | 837 | int genphy_suspend(struct phy_device *phydev); |
838 | int genphy_resume(struct phy_device *phydev); | 838 | int genphy_resume(struct phy_device *phydev); |
839 | int genphy_soft_reset(struct phy_device *phydev); | 839 | int genphy_soft_reset(struct phy_device *phydev); |
840 | static inline int genphy_no_soft_reset(struct phy_device *phydev) | ||
841 | { | ||
842 | return 0; | ||
843 | } | ||
840 | void phy_driver_unregister(struct phy_driver *drv); | 844 | void phy_driver_unregister(struct phy_driver *drv); |
841 | void phy_drivers_unregister(struct phy_driver *drv, int n); | 845 | void phy_drivers_unregister(struct phy_driver *drv, int n); |
842 | int phy_driver_register(struct phy_driver *new_driver, struct module *owner); | 846 | int phy_driver_register(struct phy_driver *new_driver, struct module *owner); |
diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h index 4ae95f7e8597..a23a33153180 100644 --- a/include/linux/rculist_nulls.h +++ b/include/linux/rculist_nulls.h | |||
@@ -156,5 +156,19 @@ static inline void hlist_nulls_add_tail_rcu(struct hlist_nulls_node *n, | |||
156 | ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \ | 156 | ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \ |
157 | pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos))) | 157 | pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos))) |
158 | 158 | ||
159 | /** | ||
160 | * hlist_nulls_for_each_entry_safe - | ||
161 | * iterate over list of given type safe against removal of list entry | ||
162 | * @tpos: the type * to use as a loop cursor. | ||
163 | * @pos: the &struct hlist_nulls_node to use as a loop cursor. | ||
164 | * @head: the head for your list. | ||
165 | * @member: the name of the hlist_nulls_node within the struct. | ||
166 | */ | ||
167 | #define hlist_nulls_for_each_entry_safe(tpos, pos, head, member) \ | ||
168 | for (({barrier();}), \ | ||
169 | pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \ | ||
170 | (!is_a_nulls(pos)) && \ | ||
171 | ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); \ | ||
172 | pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos)); 1; });) | ||
159 | #endif | 173 | #endif |
160 | #endif | 174 | #endif |
diff --git a/include/net/inet_common.h b/include/net/inet_common.h index b7952d55b9c0..f39ae697347f 100644 --- a/include/net/inet_common.h +++ b/include/net/inet_common.h | |||
@@ -20,7 +20,8 @@ int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, | |||
20 | int addr_len, int flags, int is_sendmsg); | 20 | int addr_len, int flags, int is_sendmsg); |
21 | int inet_dgram_connect(struct socket *sock, struct sockaddr *uaddr, | 21 | int inet_dgram_connect(struct socket *sock, struct sockaddr *uaddr, |
22 | int addr_len, int flags); | 22 | int addr_len, int flags); |
23 | int inet_accept(struct socket *sock, struct socket *newsock, int flags); | 23 | int inet_accept(struct socket *sock, struct socket *newsock, int flags, |
24 | bool kern); | ||
24 | int inet_sendmsg(struct socket *sock, struct msghdr *msg, size_t size); | 25 | int inet_sendmsg(struct socket *sock, struct msghdr *msg, size_t size); |
25 | ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, | 26 | ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, |
26 | size_t size, int flags); | 27 | size_t size, int flags); |
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 826f198374f8..c7a577976bec 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h | |||
@@ -258,7 +258,7 @@ inet_csk_rto_backoff(const struct inet_connection_sock *icsk, | |||
258 | return (unsigned long)min_t(u64, when, max_when); | 258 | return (unsigned long)min_t(u64, when, max_when); |
259 | } | 259 | } |
260 | 260 | ||
261 | struct sock *inet_csk_accept(struct sock *sk, int flags, int *err); | 261 | struct sock *inet_csk_accept(struct sock *sk, int flags, int *err, bool kern); |
262 | 262 | ||
263 | int inet_csk_get_port(struct sock *sk, unsigned short snum); | 263 | int inet_csk_get_port(struct sock *sk, unsigned short snum); |
264 | 264 | ||
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index a244db5e5ff7..07a0b128625a 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -476,7 +476,8 @@ struct sctp_pf { | |||
476 | int (*send_verify) (struct sctp_sock *, union sctp_addr *); | 476 | int (*send_verify) (struct sctp_sock *, union sctp_addr *); |
477 | int (*supported_addrs)(const struct sctp_sock *, __be16 *); | 477 | int (*supported_addrs)(const struct sctp_sock *, __be16 *); |
478 | struct sock *(*create_accept_sk) (struct sock *sk, | 478 | struct sock *(*create_accept_sk) (struct sock *sk, |
479 | struct sctp_association *asoc); | 479 | struct sctp_association *asoc, |
480 | bool kern); | ||
480 | int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr); | 481 | int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr); |
481 | void (*to_sk_saddr)(union sctp_addr *, struct sock *sk); | 482 | void (*to_sk_saddr)(union sctp_addr *, struct sock *sk); |
482 | void (*to_sk_daddr)(union sctp_addr *, struct sock *sk); | 483 | void (*to_sk_daddr)(union sctp_addr *, struct sock *sk); |
diff --git a/include/net/sock.h b/include/net/sock.h index 5e5997654db6..03252d53975d 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -236,6 +236,7 @@ struct sock_common { | |||
236 | * @sk_shutdown: mask of %SEND_SHUTDOWN and/or %RCV_SHUTDOWN | 236 | * @sk_shutdown: mask of %SEND_SHUTDOWN and/or %RCV_SHUTDOWN |
237 | * @sk_userlocks: %SO_SNDBUF and %SO_RCVBUF settings | 237 | * @sk_userlocks: %SO_SNDBUF and %SO_RCVBUF settings |
238 | * @sk_lock: synchronizer | 238 | * @sk_lock: synchronizer |
239 | * @sk_kern_sock: True if sock is using kernel lock classes | ||
239 | * @sk_rcvbuf: size of receive buffer in bytes | 240 | * @sk_rcvbuf: size of receive buffer in bytes |
240 | * @sk_wq: sock wait queue and async head | 241 | * @sk_wq: sock wait queue and async head |
241 | * @sk_rx_dst: receive input route used by early demux | 242 | * @sk_rx_dst: receive input route used by early demux |
@@ -430,7 +431,8 @@ struct sock { | |||
430 | #endif | 431 | #endif |
431 | 432 | ||
432 | kmemcheck_bitfield_begin(flags); | 433 | kmemcheck_bitfield_begin(flags); |
433 | unsigned int sk_padding : 2, | 434 | unsigned int sk_padding : 1, |
435 | sk_kern_sock : 1, | ||
434 | sk_no_check_tx : 1, | 436 | sk_no_check_tx : 1, |
435 | sk_no_check_rx : 1, | 437 | sk_no_check_rx : 1, |
436 | sk_userlocks : 4, | 438 | sk_userlocks : 4, |
@@ -1015,7 +1017,8 @@ struct proto { | |||
1015 | int addr_len); | 1017 | int addr_len); |
1016 | int (*disconnect)(struct sock *sk, int flags); | 1018 | int (*disconnect)(struct sock *sk, int flags); |
1017 | 1019 | ||
1018 | struct sock * (*accept)(struct sock *sk, int flags, int *err); | 1020 | struct sock * (*accept)(struct sock *sk, int flags, int *err, |
1021 | bool kern); | ||
1019 | 1022 | ||
1020 | int (*ioctl)(struct sock *sk, int cmd, | 1023 | int (*ioctl)(struct sock *sk, int cmd, |
1021 | unsigned long arg); | 1024 | unsigned long arg); |
@@ -1573,7 +1576,7 @@ int sock_cmsg_send(struct sock *sk, struct msghdr *msg, | |||
1573 | int sock_no_bind(struct socket *, struct sockaddr *, int); | 1576 | int sock_no_bind(struct socket *, struct sockaddr *, int); |
1574 | int sock_no_connect(struct socket *, struct sockaddr *, int, int); | 1577 | int sock_no_connect(struct socket *, struct sockaddr *, int, int); |
1575 | int sock_no_socketpair(struct socket *, struct socket *); | 1578 | int sock_no_socketpair(struct socket *, struct socket *); |
1576 | int sock_no_accept(struct socket *, struct socket *, int); | 1579 | int sock_no_accept(struct socket *, struct socket *, int, bool); |
1577 | int sock_no_getname(struct socket *, struct sockaddr *, int *, int); | 1580 | int sock_no_getname(struct socket *, struct sockaddr *, int *, int); |
1578 | unsigned int sock_no_poll(struct file *, struct socket *, | 1581 | unsigned int sock_no_poll(struct file *, struct socket *, |
1579 | struct poll_table_struct *); | 1582 | struct poll_table_struct *); |
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index b0e275de6dec..583875ea136a 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h | |||
@@ -196,6 +196,7 @@ struct iscsi_conn { | |||
196 | struct iscsi_task *task; /* xmit task in progress */ | 196 | struct iscsi_task *task; /* xmit task in progress */ |
197 | 197 | ||
198 | /* xmit */ | 198 | /* xmit */ |
199 | spinlock_t taskqueuelock; /* protects the next three lists */ | ||
199 | struct list_head mgmtqueue; /* mgmt (control) xmit queue */ | 200 | struct list_head mgmtqueue; /* mgmt (control) xmit queue */ |
200 | struct list_head cmdqueue; /* data-path cmd queue */ | 201 | struct list_head cmdqueue; /* data-path cmd queue */ |
201 | struct list_head requeue; /* tasks needing another run */ | 202 | struct list_head requeue; /* tasks needing another run */ |
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 6f22b39f1b0c..080c7ce9bae8 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h | |||
@@ -472,6 +472,10 @@ static inline int scsi_device_created(struct scsi_device *sdev) | |||
472 | sdev->sdev_state == SDEV_CREATED_BLOCK; | 472 | sdev->sdev_state == SDEV_CREATED_BLOCK; |
473 | } | 473 | } |
474 | 474 | ||
475 | int scsi_internal_device_block(struct scsi_device *sdev, bool wait); | ||
476 | int scsi_internal_device_unblock(struct scsi_device *sdev, | ||
477 | enum scsi_device_state new_state); | ||
478 | |||
475 | /* accessor functions for the SCSI parameters */ | 479 | /* accessor functions for the SCSI parameters */ |
476 | static inline int scsi_device_sync(struct scsi_device *sdev) | 480 | static inline int scsi_device_sync(struct scsi_device *sdev) |
477 | { | 481 | { |
diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index b54b98dc2d4a..1b0f447ce850 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h | |||
@@ -4,7 +4,12 @@ | |||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include <target/target_core_base.h> | 5 | #include <target/target_core_base.h> |
6 | 6 | ||
7 | #define TRANSPORT_FLAG_PASSTHROUGH 1 | 7 | #define TRANSPORT_FLAG_PASSTHROUGH 0x1 |
8 | /* | ||
9 | * ALUA commands, state checks and setup operations are handled by the | ||
10 | * backend module. | ||
11 | */ | ||
12 | #define TRANSPORT_FLAG_PASSTHROUGH_ALUA 0x2 | ||
8 | 13 | ||
9 | struct request_queue; | 14 | struct request_queue; |
10 | struct scatterlist; | 15 | struct scatterlist; |
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 37c274e61acc..4b784b6e21c0 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
@@ -299,7 +299,7 @@ struct t10_alua_tg_pt_gp { | |||
299 | struct list_head tg_pt_gp_lun_list; | 299 | struct list_head tg_pt_gp_lun_list; |
300 | struct se_lun *tg_pt_gp_alua_lun; | 300 | struct se_lun *tg_pt_gp_alua_lun; |
301 | struct se_node_acl *tg_pt_gp_alua_nacl; | 301 | struct se_node_acl *tg_pt_gp_alua_nacl; |
302 | struct delayed_work tg_pt_gp_transition_work; | 302 | struct work_struct tg_pt_gp_transition_work; |
303 | struct completion *tg_pt_gp_transition_complete; | 303 | struct completion *tg_pt_gp_transition_complete; |
304 | }; | 304 | }; |
305 | 305 | ||
diff --git a/include/uapi/drm/omap_drm.h b/include/uapi/drm/omap_drm.h index 407cb55df6ac..7fb97863c945 100644 --- a/include/uapi/drm/omap_drm.h +++ b/include/uapi/drm/omap_drm.h | |||
@@ -33,8 +33,8 @@ extern "C" { | |||
33 | #define OMAP_PARAM_CHIPSET_ID 1 /* ie. 0x3430, 0x4430, etc */ | 33 | #define OMAP_PARAM_CHIPSET_ID 1 /* ie. 0x3430, 0x4430, etc */ |
34 | 34 | ||
35 | struct drm_omap_param { | 35 | struct drm_omap_param { |
36 | uint64_t param; /* in */ | 36 | __u64 param; /* in */ |
37 | uint64_t value; /* in (set_param), out (get_param) */ | 37 | __u64 value; /* in (set_param), out (get_param) */ |
38 | }; | 38 | }; |
39 | 39 | ||
40 | #define OMAP_BO_SCANOUT 0x00000001 /* scanout capable (phys contiguous) */ | 40 | #define OMAP_BO_SCANOUT 0x00000001 /* scanout capable (phys contiguous) */ |
@@ -53,18 +53,18 @@ struct drm_omap_param { | |||
53 | #define OMAP_BO_TILED (OMAP_BO_TILED_8 | OMAP_BO_TILED_16 | OMAP_BO_TILED_32) | 53 | #define OMAP_BO_TILED (OMAP_BO_TILED_8 | OMAP_BO_TILED_16 | OMAP_BO_TILED_32) |
54 | 54 | ||
55 | union omap_gem_size { | 55 | union omap_gem_size { |
56 | uint32_t bytes; /* (for non-tiled formats) */ | 56 | __u32 bytes; /* (for non-tiled formats) */ |
57 | struct { | 57 | struct { |
58 | uint16_t width; | 58 | __u16 width; |
59 | uint16_t height; | 59 | __u16 height; |
60 | } tiled; /* (for tiled formats) */ | 60 | } tiled; /* (for tiled formats) */ |
61 | }; | 61 | }; |
62 | 62 | ||
63 | struct drm_omap_gem_new { | 63 | struct drm_omap_gem_new { |
64 | union omap_gem_size size; /* in */ | 64 | union omap_gem_size size; /* in */ |
65 | uint32_t flags; /* in */ | 65 | __u32 flags; /* in */ |
66 | uint32_t handle; /* out */ | 66 | __u32 handle; /* out */ |
67 | uint32_t __pad; | 67 | __u32 __pad; |
68 | }; | 68 | }; |
69 | 69 | ||
70 | /* mask of operations: */ | 70 | /* mask of operations: */ |
@@ -74,33 +74,33 @@ enum omap_gem_op { | |||
74 | }; | 74 | }; |
75 | 75 | ||
76 | struct drm_omap_gem_cpu_prep { | 76 | struct drm_omap_gem_cpu_prep { |
77 | uint32_t handle; /* buffer handle (in) */ | 77 | __u32 handle; /* buffer handle (in) */ |
78 | uint32_t op; /* mask of omap_gem_op (in) */ | 78 | __u32 op; /* mask of omap_gem_op (in) */ |
79 | }; | 79 | }; |
80 | 80 | ||
81 | struct drm_omap_gem_cpu_fini { | 81 | struct drm_omap_gem_cpu_fini { |
82 | uint32_t handle; /* buffer handle (in) */ | 82 | __u32 handle; /* buffer handle (in) */ |
83 | uint32_t op; /* mask of omap_gem_op (in) */ | 83 | __u32 op; /* mask of omap_gem_op (in) */ |
84 | /* TODO maybe here we pass down info about what regions are touched | 84 | /* TODO maybe here we pass down info about what regions are touched |
85 | * by sw so we can be clever about cache ops? For now a placeholder, | 85 | * by sw so we can be clever about cache ops? For now a placeholder, |
86 | * set to zero and we just do full buffer flush.. | 86 | * set to zero and we just do full buffer flush.. |
87 | */ | 87 | */ |
88 | uint32_t nregions; | 88 | __u32 nregions; |
89 | uint32_t __pad; | 89 | __u32 __pad; |
90 | }; | 90 | }; |
91 | 91 | ||
92 | struct drm_omap_gem_info { | 92 | struct drm_omap_gem_info { |
93 | uint32_t handle; /* buffer handle (in) */ | 93 | __u32 handle; /* buffer handle (in) */ |
94 | uint32_t pad; | 94 | __u32 pad; |
95 | uint64_t offset; /* mmap offset (out) */ | 95 | __u64 offset; /* mmap offset (out) */ |
96 | /* note: in case of tiled buffers, the user virtual size can be | 96 | /* note: in case of tiled buffers, the user virtual size can be |
97 | * different from the physical size (ie. how many pages are needed | 97 | * different from the physical size (ie. how many pages are needed |
98 | * to back the object) which is returned in DRM_IOCTL_GEM_OPEN.. | 98 | * to back the object) which is returned in DRM_IOCTL_GEM_OPEN.. |
99 | * This size here is the one that should be used if you want to | 99 | * This size here is the one that should be used if you want to |
100 | * mmap() the buffer: | 100 | * mmap() the buffer: |
101 | */ | 101 | */ |
102 | uint32_t size; /* virtual size for mmap'ing (out) */ | 102 | __u32 size; /* virtual size for mmap'ing (out) */ |
103 | uint32_t __pad; | 103 | __u32 __pad; |
104 | }; | 104 | }; |
105 | 105 | ||
106 | #define DRM_OMAP_GET_PARAM 0x00 | 106 | #define DRM_OMAP_GET_PARAM 0x00 |
diff --git a/include/uapi/linux/packet_diag.h b/include/uapi/linux/packet_diag.h index d08c63f3dd6f..0c5d5dd61b6a 100644 --- a/include/uapi/linux/packet_diag.h +++ b/include/uapi/linux/packet_diag.h | |||
@@ -64,7 +64,7 @@ struct packet_diag_mclist { | |||
64 | __u32 pdmc_count; | 64 | __u32 pdmc_count; |
65 | __u16 pdmc_type; | 65 | __u16 pdmc_type; |
66 | __u16 pdmc_alen; | 66 | __u16 pdmc_alen; |
67 | __u8 pdmc_addr[MAX_ADDR_LEN]; | 67 | __u8 pdmc_addr[32]; /* MAX_ADDR_LEN */ |
68 | }; | 68 | }; |
69 | 69 | ||
70 | struct packet_diag_ring { | 70 | struct packet_diag_ring { |
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index 3ea87fb19a94..afe5bab376c9 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c | |||
@@ -13,11 +13,12 @@ | |||
13 | #include <linux/bpf.h> | 13 | #include <linux/bpf.h> |
14 | #include <linux/jhash.h> | 14 | #include <linux/jhash.h> |
15 | #include <linux/filter.h> | 15 | #include <linux/filter.h> |
16 | #include <linux/rculist_nulls.h> | ||
16 | #include "percpu_freelist.h" | 17 | #include "percpu_freelist.h" |
17 | #include "bpf_lru_list.h" | 18 | #include "bpf_lru_list.h" |
18 | 19 | ||
19 | struct bucket { | 20 | struct bucket { |
20 | struct hlist_head head; | 21 | struct hlist_nulls_head head; |
21 | raw_spinlock_t lock; | 22 | raw_spinlock_t lock; |
22 | }; | 23 | }; |
23 | 24 | ||
@@ -44,9 +45,14 @@ enum extra_elem_state { | |||
44 | /* each htab element is struct htab_elem + key + value */ | 45 | /* each htab element is struct htab_elem + key + value */ |
45 | struct htab_elem { | 46 | struct htab_elem { |
46 | union { | 47 | union { |
47 | struct hlist_node hash_node; | 48 | struct hlist_nulls_node hash_node; |
48 | struct bpf_htab *htab; | 49 | struct { |
49 | struct pcpu_freelist_node fnode; | 50 | void *padding; |
51 | union { | ||
52 | struct bpf_htab *htab; | ||
53 | struct pcpu_freelist_node fnode; | ||
54 | }; | ||
55 | }; | ||
50 | }; | 56 | }; |
51 | union { | 57 | union { |
52 | struct rcu_head rcu; | 58 | struct rcu_head rcu; |
@@ -162,7 +168,8 @@ skip_percpu_elems: | |||
162 | offsetof(struct htab_elem, lru_node), | 168 | offsetof(struct htab_elem, lru_node), |
163 | htab->elem_size, htab->map.max_entries); | 169 | htab->elem_size, htab->map.max_entries); |
164 | else | 170 | else |
165 | pcpu_freelist_populate(&htab->freelist, htab->elems, | 171 | pcpu_freelist_populate(&htab->freelist, |
172 | htab->elems + offsetof(struct htab_elem, fnode), | ||
166 | htab->elem_size, htab->map.max_entries); | 173 | htab->elem_size, htab->map.max_entries); |
167 | 174 | ||
168 | return 0; | 175 | return 0; |
@@ -217,6 +224,11 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) | |||
217 | int err, i; | 224 | int err, i; |
218 | u64 cost; | 225 | u64 cost; |
219 | 226 | ||
227 | BUILD_BUG_ON(offsetof(struct htab_elem, htab) != | ||
228 | offsetof(struct htab_elem, hash_node.pprev)); | ||
229 | BUILD_BUG_ON(offsetof(struct htab_elem, fnode.next) != | ||
230 | offsetof(struct htab_elem, hash_node.pprev)); | ||
231 | |||
220 | if (lru && !capable(CAP_SYS_ADMIN)) | 232 | if (lru && !capable(CAP_SYS_ADMIN)) |
221 | /* LRU implementation is much complicated than other | 233 | /* LRU implementation is much complicated than other |
222 | * maps. Hence, limit to CAP_SYS_ADMIN for now. | 234 | * maps. Hence, limit to CAP_SYS_ADMIN for now. |
@@ -326,7 +338,7 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) | |||
326 | goto free_htab; | 338 | goto free_htab; |
327 | 339 | ||
328 | for (i = 0; i < htab->n_buckets; i++) { | 340 | for (i = 0; i < htab->n_buckets; i++) { |
329 | INIT_HLIST_HEAD(&htab->buckets[i].head); | 341 | INIT_HLIST_NULLS_HEAD(&htab->buckets[i].head, i); |
330 | raw_spin_lock_init(&htab->buckets[i].lock); | 342 | raw_spin_lock_init(&htab->buckets[i].lock); |
331 | } | 343 | } |
332 | 344 | ||
@@ -366,20 +378,44 @@ static inline struct bucket *__select_bucket(struct bpf_htab *htab, u32 hash) | |||
366 | return &htab->buckets[hash & (htab->n_buckets - 1)]; | 378 | return &htab->buckets[hash & (htab->n_buckets - 1)]; |
367 | } | 379 | } |
368 | 380 | ||
369 | static inline struct hlist_head *select_bucket(struct bpf_htab *htab, u32 hash) | 381 | static inline struct hlist_nulls_head *select_bucket(struct bpf_htab *htab, u32 hash) |
370 | { | 382 | { |
371 | return &__select_bucket(htab, hash)->head; | 383 | return &__select_bucket(htab, hash)->head; |
372 | } | 384 | } |
373 | 385 | ||
374 | static struct htab_elem *lookup_elem_raw(struct hlist_head *head, u32 hash, | 386 | /* this lookup function can only be called with bucket lock taken */ |
387 | static struct htab_elem *lookup_elem_raw(struct hlist_nulls_head *head, u32 hash, | ||
375 | void *key, u32 key_size) | 388 | void *key, u32 key_size) |
376 | { | 389 | { |
390 | struct hlist_nulls_node *n; | ||
391 | struct htab_elem *l; | ||
392 | |||
393 | hlist_nulls_for_each_entry_rcu(l, n, head, hash_node) | ||
394 | if (l->hash == hash && !memcmp(&l->key, key, key_size)) | ||
395 | return l; | ||
396 | |||
397 | return NULL; | ||
398 | } | ||
399 | |||
400 | /* can be called without bucket lock. it will repeat the loop in | ||
401 | * the unlikely event when elements moved from one bucket into another | ||
402 | * while link list is being walked | ||
403 | */ | ||
404 | static struct htab_elem *lookup_nulls_elem_raw(struct hlist_nulls_head *head, | ||
405 | u32 hash, void *key, | ||
406 | u32 key_size, u32 n_buckets) | ||
407 | { | ||
408 | struct hlist_nulls_node *n; | ||
377 | struct htab_elem *l; | 409 | struct htab_elem *l; |
378 | 410 | ||
379 | hlist_for_each_entry_rcu(l, head, hash_node) | 411 | again: |
412 | hlist_nulls_for_each_entry_rcu(l, n, head, hash_node) | ||
380 | if (l->hash == hash && !memcmp(&l->key, key, key_size)) | 413 | if (l->hash == hash && !memcmp(&l->key, key, key_size)) |
381 | return l; | 414 | return l; |
382 | 415 | ||
416 | if (unlikely(get_nulls_value(n) != (hash & (n_buckets - 1)))) | ||
417 | goto again; | ||
418 | |||
383 | return NULL; | 419 | return NULL; |
384 | } | 420 | } |
385 | 421 | ||
@@ -387,7 +423,7 @@ static struct htab_elem *lookup_elem_raw(struct hlist_head *head, u32 hash, | |||
387 | static void *__htab_map_lookup_elem(struct bpf_map *map, void *key) | 423 | static void *__htab_map_lookup_elem(struct bpf_map *map, void *key) |
388 | { | 424 | { |
389 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); | 425 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); |
390 | struct hlist_head *head; | 426 | struct hlist_nulls_head *head; |
391 | struct htab_elem *l; | 427 | struct htab_elem *l; |
392 | u32 hash, key_size; | 428 | u32 hash, key_size; |
393 | 429 | ||
@@ -400,7 +436,7 @@ static void *__htab_map_lookup_elem(struct bpf_map *map, void *key) | |||
400 | 436 | ||
401 | head = select_bucket(htab, hash); | 437 | head = select_bucket(htab, hash); |
402 | 438 | ||
403 | l = lookup_elem_raw(head, hash, key, key_size); | 439 | l = lookup_nulls_elem_raw(head, hash, key, key_size, htab->n_buckets); |
404 | 440 | ||
405 | return l; | 441 | return l; |
406 | } | 442 | } |
@@ -433,8 +469,9 @@ static void *htab_lru_map_lookup_elem(struct bpf_map *map, void *key) | |||
433 | static bool htab_lru_map_delete_node(void *arg, struct bpf_lru_node *node) | 469 | static bool htab_lru_map_delete_node(void *arg, struct bpf_lru_node *node) |
434 | { | 470 | { |
435 | struct bpf_htab *htab = (struct bpf_htab *)arg; | 471 | struct bpf_htab *htab = (struct bpf_htab *)arg; |
436 | struct htab_elem *l, *tgt_l; | 472 | struct htab_elem *l = NULL, *tgt_l; |
437 | struct hlist_head *head; | 473 | struct hlist_nulls_head *head; |
474 | struct hlist_nulls_node *n; | ||
438 | unsigned long flags; | 475 | unsigned long flags; |
439 | struct bucket *b; | 476 | struct bucket *b; |
440 | 477 | ||
@@ -444,9 +481,9 @@ static bool htab_lru_map_delete_node(void *arg, struct bpf_lru_node *node) | |||
444 | 481 | ||
445 | raw_spin_lock_irqsave(&b->lock, flags); | 482 | raw_spin_lock_irqsave(&b->lock, flags); |
446 | 483 | ||
447 | hlist_for_each_entry_rcu(l, head, hash_node) | 484 | hlist_nulls_for_each_entry_rcu(l, n, head, hash_node) |
448 | if (l == tgt_l) { | 485 | if (l == tgt_l) { |
449 | hlist_del_rcu(&l->hash_node); | 486 | hlist_nulls_del_rcu(&l->hash_node); |
450 | break; | 487 | break; |
451 | } | 488 | } |
452 | 489 | ||
@@ -459,7 +496,7 @@ static bool htab_lru_map_delete_node(void *arg, struct bpf_lru_node *node) | |||
459 | static int htab_map_get_next_key(struct bpf_map *map, void *key, void *next_key) | 496 | static int htab_map_get_next_key(struct bpf_map *map, void *key, void *next_key) |
460 | { | 497 | { |
461 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); | 498 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); |
462 | struct hlist_head *head; | 499 | struct hlist_nulls_head *head; |
463 | struct htab_elem *l, *next_l; | 500 | struct htab_elem *l, *next_l; |
464 | u32 hash, key_size; | 501 | u32 hash, key_size; |
465 | int i; | 502 | int i; |
@@ -473,7 +510,7 @@ static int htab_map_get_next_key(struct bpf_map *map, void *key, void *next_key) | |||
473 | head = select_bucket(htab, hash); | 510 | head = select_bucket(htab, hash); |
474 | 511 | ||
475 | /* lookup the key */ | 512 | /* lookup the key */ |
476 | l = lookup_elem_raw(head, hash, key, key_size); | 513 | l = lookup_nulls_elem_raw(head, hash, key, key_size, htab->n_buckets); |
477 | 514 | ||
478 | if (!l) { | 515 | if (!l) { |
479 | i = 0; | 516 | i = 0; |
@@ -481,7 +518,7 @@ static int htab_map_get_next_key(struct bpf_map *map, void *key, void *next_key) | |||
481 | } | 518 | } |
482 | 519 | ||
483 | /* key was found, get next key in the same bucket */ | 520 | /* key was found, get next key in the same bucket */ |
484 | next_l = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(&l->hash_node)), | 521 | next_l = hlist_nulls_entry_safe(rcu_dereference_raw(hlist_nulls_next_rcu(&l->hash_node)), |
485 | struct htab_elem, hash_node); | 522 | struct htab_elem, hash_node); |
486 | 523 | ||
487 | if (next_l) { | 524 | if (next_l) { |
@@ -500,7 +537,7 @@ find_first_elem: | |||
500 | head = select_bucket(htab, i); | 537 | head = select_bucket(htab, i); |
501 | 538 | ||
502 | /* pick first element in the bucket */ | 539 | /* pick first element in the bucket */ |
503 | next_l = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(head)), | 540 | next_l = hlist_nulls_entry_safe(rcu_dereference_raw(hlist_nulls_first_rcu(head)), |
504 | struct htab_elem, hash_node); | 541 | struct htab_elem, hash_node); |
505 | if (next_l) { | 542 | if (next_l) { |
506 | /* if it's not empty, just return it */ | 543 | /* if it's not empty, just return it */ |
@@ -582,9 +619,13 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, | |||
582 | int err = 0; | 619 | int err = 0; |
583 | 620 | ||
584 | if (prealloc) { | 621 | if (prealloc) { |
585 | l_new = (struct htab_elem *)pcpu_freelist_pop(&htab->freelist); | 622 | struct pcpu_freelist_node *l; |
586 | if (!l_new) | 623 | |
624 | l = pcpu_freelist_pop(&htab->freelist); | ||
625 | if (!l) | ||
587 | err = -E2BIG; | 626 | err = -E2BIG; |
627 | else | ||
628 | l_new = container_of(l, struct htab_elem, fnode); | ||
588 | } else { | 629 | } else { |
589 | if (atomic_inc_return(&htab->count) > htab->map.max_entries) { | 630 | if (atomic_inc_return(&htab->count) > htab->map.max_entries) { |
590 | atomic_dec(&htab->count); | 631 | atomic_dec(&htab->count); |
@@ -661,7 +702,7 @@ static int htab_map_update_elem(struct bpf_map *map, void *key, void *value, | |||
661 | { | 702 | { |
662 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); | 703 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); |
663 | struct htab_elem *l_new = NULL, *l_old; | 704 | struct htab_elem *l_new = NULL, *l_old; |
664 | struct hlist_head *head; | 705 | struct hlist_nulls_head *head; |
665 | unsigned long flags; | 706 | unsigned long flags; |
666 | struct bucket *b; | 707 | struct bucket *b; |
667 | u32 key_size, hash; | 708 | u32 key_size, hash; |
@@ -700,9 +741,9 @@ static int htab_map_update_elem(struct bpf_map *map, void *key, void *value, | |||
700 | /* add new element to the head of the list, so that | 741 | /* add new element to the head of the list, so that |
701 | * concurrent search will find it before old elem | 742 | * concurrent search will find it before old elem |
702 | */ | 743 | */ |
703 | hlist_add_head_rcu(&l_new->hash_node, head); | 744 | hlist_nulls_add_head_rcu(&l_new->hash_node, head); |
704 | if (l_old) { | 745 | if (l_old) { |
705 | hlist_del_rcu(&l_old->hash_node); | 746 | hlist_nulls_del_rcu(&l_old->hash_node); |
706 | free_htab_elem(htab, l_old); | 747 | free_htab_elem(htab, l_old); |
707 | } | 748 | } |
708 | ret = 0; | 749 | ret = 0; |
@@ -716,7 +757,7 @@ static int htab_lru_map_update_elem(struct bpf_map *map, void *key, void *value, | |||
716 | { | 757 | { |
717 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); | 758 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); |
718 | struct htab_elem *l_new, *l_old = NULL; | 759 | struct htab_elem *l_new, *l_old = NULL; |
719 | struct hlist_head *head; | 760 | struct hlist_nulls_head *head; |
720 | unsigned long flags; | 761 | unsigned long flags; |
721 | struct bucket *b; | 762 | struct bucket *b; |
722 | u32 key_size, hash; | 763 | u32 key_size, hash; |
@@ -757,10 +798,10 @@ static int htab_lru_map_update_elem(struct bpf_map *map, void *key, void *value, | |||
757 | /* add new element to the head of the list, so that | 798 | /* add new element to the head of the list, so that |
758 | * concurrent search will find it before old elem | 799 | * concurrent search will find it before old elem |
759 | */ | 800 | */ |
760 | hlist_add_head_rcu(&l_new->hash_node, head); | 801 | hlist_nulls_add_head_rcu(&l_new->hash_node, head); |
761 | if (l_old) { | 802 | if (l_old) { |
762 | bpf_lru_node_set_ref(&l_new->lru_node); | 803 | bpf_lru_node_set_ref(&l_new->lru_node); |
763 | hlist_del_rcu(&l_old->hash_node); | 804 | hlist_nulls_del_rcu(&l_old->hash_node); |
764 | } | 805 | } |
765 | ret = 0; | 806 | ret = 0; |
766 | 807 | ||
@@ -781,7 +822,7 @@ static int __htab_percpu_map_update_elem(struct bpf_map *map, void *key, | |||
781 | { | 822 | { |
782 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); | 823 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); |
783 | struct htab_elem *l_new = NULL, *l_old; | 824 | struct htab_elem *l_new = NULL, *l_old; |
784 | struct hlist_head *head; | 825 | struct hlist_nulls_head *head; |
785 | unsigned long flags; | 826 | unsigned long flags; |
786 | struct bucket *b; | 827 | struct bucket *b; |
787 | u32 key_size, hash; | 828 | u32 key_size, hash; |
@@ -820,7 +861,7 @@ static int __htab_percpu_map_update_elem(struct bpf_map *map, void *key, | |||
820 | ret = PTR_ERR(l_new); | 861 | ret = PTR_ERR(l_new); |
821 | goto err; | 862 | goto err; |
822 | } | 863 | } |
823 | hlist_add_head_rcu(&l_new->hash_node, head); | 864 | hlist_nulls_add_head_rcu(&l_new->hash_node, head); |
824 | } | 865 | } |
825 | ret = 0; | 866 | ret = 0; |
826 | err: | 867 | err: |
@@ -834,7 +875,7 @@ static int __htab_lru_percpu_map_update_elem(struct bpf_map *map, void *key, | |||
834 | { | 875 | { |
835 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); | 876 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); |
836 | struct htab_elem *l_new = NULL, *l_old; | 877 | struct htab_elem *l_new = NULL, *l_old; |
837 | struct hlist_head *head; | 878 | struct hlist_nulls_head *head; |
838 | unsigned long flags; | 879 | unsigned long flags; |
839 | struct bucket *b; | 880 | struct bucket *b; |
840 | u32 key_size, hash; | 881 | u32 key_size, hash; |
@@ -882,7 +923,7 @@ static int __htab_lru_percpu_map_update_elem(struct bpf_map *map, void *key, | |||
882 | } else { | 923 | } else { |
883 | pcpu_copy_value(htab, htab_elem_get_ptr(l_new, key_size), | 924 | pcpu_copy_value(htab, htab_elem_get_ptr(l_new, key_size), |
884 | value, onallcpus); | 925 | value, onallcpus); |
885 | hlist_add_head_rcu(&l_new->hash_node, head); | 926 | hlist_nulls_add_head_rcu(&l_new->hash_node, head); |
886 | l_new = NULL; | 927 | l_new = NULL; |
887 | } | 928 | } |
888 | ret = 0; | 929 | ret = 0; |
@@ -910,7 +951,7 @@ static int htab_lru_percpu_map_update_elem(struct bpf_map *map, void *key, | |||
910 | static int htab_map_delete_elem(struct bpf_map *map, void *key) | 951 | static int htab_map_delete_elem(struct bpf_map *map, void *key) |
911 | { | 952 | { |
912 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); | 953 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); |
913 | struct hlist_head *head; | 954 | struct hlist_nulls_head *head; |
914 | struct bucket *b; | 955 | struct bucket *b; |
915 | struct htab_elem *l; | 956 | struct htab_elem *l; |
916 | unsigned long flags; | 957 | unsigned long flags; |
@@ -930,7 +971,7 @@ static int htab_map_delete_elem(struct bpf_map *map, void *key) | |||
930 | l = lookup_elem_raw(head, hash, key, key_size); | 971 | l = lookup_elem_raw(head, hash, key, key_size); |
931 | 972 | ||
932 | if (l) { | 973 | if (l) { |
933 | hlist_del_rcu(&l->hash_node); | 974 | hlist_nulls_del_rcu(&l->hash_node); |
934 | free_htab_elem(htab, l); | 975 | free_htab_elem(htab, l); |
935 | ret = 0; | 976 | ret = 0; |
936 | } | 977 | } |
@@ -942,7 +983,7 @@ static int htab_map_delete_elem(struct bpf_map *map, void *key) | |||
942 | static int htab_lru_map_delete_elem(struct bpf_map *map, void *key) | 983 | static int htab_lru_map_delete_elem(struct bpf_map *map, void *key) |
943 | { | 984 | { |
944 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); | 985 | struct bpf_htab *htab = container_of(map, struct bpf_htab, map); |
945 | struct hlist_head *head; | 986 | struct hlist_nulls_head *head; |
946 | struct bucket *b; | 987 | struct bucket *b; |
947 | struct htab_elem *l; | 988 | struct htab_elem *l; |
948 | unsigned long flags; | 989 | unsigned long flags; |
@@ -962,7 +1003,7 @@ static int htab_lru_map_delete_elem(struct bpf_map *map, void *key) | |||
962 | l = lookup_elem_raw(head, hash, key, key_size); | 1003 | l = lookup_elem_raw(head, hash, key, key_size); |
963 | 1004 | ||
964 | if (l) { | 1005 | if (l) { |
965 | hlist_del_rcu(&l->hash_node); | 1006 | hlist_nulls_del_rcu(&l->hash_node); |
966 | ret = 0; | 1007 | ret = 0; |
967 | } | 1008 | } |
968 | 1009 | ||
@@ -977,12 +1018,12 @@ static void delete_all_elements(struct bpf_htab *htab) | |||
977 | int i; | 1018 | int i; |
978 | 1019 | ||
979 | for (i = 0; i < htab->n_buckets; i++) { | 1020 | for (i = 0; i < htab->n_buckets; i++) { |
980 | struct hlist_head *head = select_bucket(htab, i); | 1021 | struct hlist_nulls_head *head = select_bucket(htab, i); |
981 | struct hlist_node *n; | 1022 | struct hlist_nulls_node *n; |
982 | struct htab_elem *l; | 1023 | struct htab_elem *l; |
983 | 1024 | ||
984 | hlist_for_each_entry_safe(l, n, head, hash_node) { | 1025 | hlist_nulls_for_each_entry_safe(l, n, head, hash_node) { |
985 | hlist_del_rcu(&l->hash_node); | 1026 | hlist_nulls_del_rcu(&l->hash_node); |
986 | if (l->state != HTAB_EXTRA_ELEM_USED) | 1027 | if (l->state != HTAB_EXTRA_ELEM_USED) |
987 | htab_elem_free(htab, l); | 1028 | htab_elem_free(htab, l); |
988 | } | 1029 | } |
diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c index 8bfe0afaee10..b37bd9ab7f57 100644 --- a/kernel/bpf/lpm_trie.c +++ b/kernel/bpf/lpm_trie.c | |||
@@ -500,9 +500,15 @@ unlock: | |||
500 | raw_spin_unlock(&trie->lock); | 500 | raw_spin_unlock(&trie->lock); |
501 | } | 501 | } |
502 | 502 | ||
503 | static int trie_get_next_key(struct bpf_map *map, void *key, void *next_key) | ||
504 | { | ||
505 | return -ENOTSUPP; | ||
506 | } | ||
507 | |||
503 | static const struct bpf_map_ops trie_ops = { | 508 | static const struct bpf_map_ops trie_ops = { |
504 | .map_alloc = trie_alloc, | 509 | .map_alloc = trie_alloc, |
505 | .map_free = trie_free, | 510 | .map_free = trie_free, |
511 | .map_get_next_key = trie_get_next_key, | ||
506 | .map_lookup_elem = trie_lookup_elem, | 512 | .map_lookup_elem = trie_lookup_elem, |
507 | .map_update_elem = trie_update_elem, | 513 | .map_update_elem = trie_update_elem, |
508 | .map_delete_elem = trie_delete_elem, | 514 | .map_delete_elem = trie_delete_elem, |
diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c index 56eba9caa632..1dc22f6b49f5 100644 --- a/kernel/cgroup/cgroup-v1.c +++ b/kernel/cgroup/cgroup-v1.c | |||
@@ -1329,7 +1329,7 @@ static int cgroup_css_links_read(struct seq_file *seq, void *v) | |||
1329 | struct task_struct *task; | 1329 | struct task_struct *task; |
1330 | int count = 0; | 1330 | int count = 0; |
1331 | 1331 | ||
1332 | seq_printf(seq, "css_set %p\n", cset); | 1332 | seq_printf(seq, "css_set %pK\n", cset); |
1333 | 1333 | ||
1334 | list_for_each_entry(task, &cset->tasks, cg_list) { | 1334 | list_for_each_entry(task, &cset->tasks, cg_list) { |
1335 | if (count++ > MAX_TASKS_SHOWN_PER_CSS) | 1335 | if (count++ > MAX_TASKS_SHOWN_PER_CSS) |
diff --git a/kernel/cgroup/pids.c b/kernel/cgroup/pids.c index e756dae49300..2237201d66d5 100644 --- a/kernel/cgroup/pids.c +++ b/kernel/cgroup/pids.c | |||
@@ -229,7 +229,7 @@ static int pids_can_fork(struct task_struct *task) | |||
229 | /* Only log the first time events_limit is incremented. */ | 229 | /* Only log the first time events_limit is incremented. */ |
230 | if (atomic64_inc_return(&pids->events_limit) == 1) { | 230 | if (atomic64_inc_return(&pids->events_limit) == 1) { |
231 | pr_info("cgroup: fork rejected by pids controller in "); | 231 | pr_info("cgroup: fork rejected by pids controller in "); |
232 | pr_cont_cgroup_path(task_cgroup(current, pids_cgrp_id)); | 232 | pr_cont_cgroup_path(css->cgroup); |
233 | pr_cont("\n"); | 233 | pr_cont("\n"); |
234 | } | 234 | } |
235 | cgroup_file_notify(&pids->events_file); | 235 | cgroup_file_notify(&pids->events_file); |
diff --git a/kernel/cpu.c b/kernel/cpu.c index f7c063239fa5..37b223e4fc05 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -1335,26 +1335,21 @@ static int cpuhp_store_callbacks(enum cpuhp_state state, const char *name, | |||
1335 | struct cpuhp_step *sp; | 1335 | struct cpuhp_step *sp; |
1336 | int ret = 0; | 1336 | int ret = 0; |
1337 | 1337 | ||
1338 | mutex_lock(&cpuhp_state_mutex); | ||
1339 | |||
1340 | if (state == CPUHP_AP_ONLINE_DYN || state == CPUHP_BP_PREPARE_DYN) { | 1338 | if (state == CPUHP_AP_ONLINE_DYN || state == CPUHP_BP_PREPARE_DYN) { |
1341 | ret = cpuhp_reserve_state(state); | 1339 | ret = cpuhp_reserve_state(state); |
1342 | if (ret < 0) | 1340 | if (ret < 0) |
1343 | goto out; | 1341 | return ret; |
1344 | state = ret; | 1342 | state = ret; |
1345 | } | 1343 | } |
1346 | sp = cpuhp_get_step(state); | 1344 | sp = cpuhp_get_step(state); |
1347 | if (name && sp->name) { | 1345 | if (name && sp->name) |
1348 | ret = -EBUSY; | 1346 | return -EBUSY; |
1349 | goto out; | 1347 | |
1350 | } | ||
1351 | sp->startup.single = startup; | 1348 | sp->startup.single = startup; |
1352 | sp->teardown.single = teardown; | 1349 | sp->teardown.single = teardown; |
1353 | sp->name = name; | 1350 | sp->name = name; |
1354 | sp->multi_instance = multi_instance; | 1351 | sp->multi_instance = multi_instance; |
1355 | INIT_HLIST_HEAD(&sp->list); | 1352 | INIT_HLIST_HEAD(&sp->list); |
1356 | out: | ||
1357 | mutex_unlock(&cpuhp_state_mutex); | ||
1358 | return ret; | 1353 | return ret; |
1359 | } | 1354 | } |
1360 | 1355 | ||
@@ -1428,6 +1423,7 @@ int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node, | |||
1428 | return -EINVAL; | 1423 | return -EINVAL; |
1429 | 1424 | ||
1430 | get_online_cpus(); | 1425 | get_online_cpus(); |
1426 | mutex_lock(&cpuhp_state_mutex); | ||
1431 | 1427 | ||
1432 | if (!invoke || !sp->startup.multi) | 1428 | if (!invoke || !sp->startup.multi) |
1433 | goto add_node; | 1429 | goto add_node; |
@@ -1447,16 +1443,14 @@ int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node, | |||
1447 | if (ret) { | 1443 | if (ret) { |
1448 | if (sp->teardown.multi) | 1444 | if (sp->teardown.multi) |
1449 | cpuhp_rollback_install(cpu, state, node); | 1445 | cpuhp_rollback_install(cpu, state, node); |
1450 | goto err; | 1446 | goto unlock; |
1451 | } | 1447 | } |
1452 | } | 1448 | } |
1453 | add_node: | 1449 | add_node: |
1454 | ret = 0; | 1450 | ret = 0; |
1455 | mutex_lock(&cpuhp_state_mutex); | ||
1456 | hlist_add_head(node, &sp->list); | 1451 | hlist_add_head(node, &sp->list); |
1452 | unlock: | ||
1457 | mutex_unlock(&cpuhp_state_mutex); | 1453 | mutex_unlock(&cpuhp_state_mutex); |
1458 | |||
1459 | err: | ||
1460 | put_online_cpus(); | 1454 | put_online_cpus(); |
1461 | return ret; | 1455 | return ret; |
1462 | } | 1456 | } |
@@ -1491,6 +1485,7 @@ int __cpuhp_setup_state(enum cpuhp_state state, | |||
1491 | return -EINVAL; | 1485 | return -EINVAL; |
1492 | 1486 | ||
1493 | get_online_cpus(); | 1487 | get_online_cpus(); |
1488 | mutex_lock(&cpuhp_state_mutex); | ||
1494 | 1489 | ||
1495 | ret = cpuhp_store_callbacks(state, name, startup, teardown, | 1490 | ret = cpuhp_store_callbacks(state, name, startup, teardown, |
1496 | multi_instance); | 1491 | multi_instance); |
@@ -1524,6 +1519,7 @@ int __cpuhp_setup_state(enum cpuhp_state state, | |||
1524 | } | 1519 | } |
1525 | } | 1520 | } |
1526 | out: | 1521 | out: |
1522 | mutex_unlock(&cpuhp_state_mutex); | ||
1527 | put_online_cpus(); | 1523 | put_online_cpus(); |
1528 | /* | 1524 | /* |
1529 | * If the requested state is CPUHP_AP_ONLINE_DYN, return the | 1525 | * If the requested state is CPUHP_AP_ONLINE_DYN, return the |
@@ -1547,6 +1543,8 @@ int __cpuhp_state_remove_instance(enum cpuhp_state state, | |||
1547 | return -EINVAL; | 1543 | return -EINVAL; |
1548 | 1544 | ||
1549 | get_online_cpus(); | 1545 | get_online_cpus(); |
1546 | mutex_lock(&cpuhp_state_mutex); | ||
1547 | |||
1550 | if (!invoke || !cpuhp_get_teardown_cb(state)) | 1548 | if (!invoke || !cpuhp_get_teardown_cb(state)) |
1551 | goto remove; | 1549 | goto remove; |
1552 | /* | 1550 | /* |
@@ -1563,7 +1561,6 @@ int __cpuhp_state_remove_instance(enum cpuhp_state state, | |||
1563 | } | 1561 | } |
1564 | 1562 | ||
1565 | remove: | 1563 | remove: |
1566 | mutex_lock(&cpuhp_state_mutex); | ||
1567 | hlist_del(node); | 1564 | hlist_del(node); |
1568 | mutex_unlock(&cpuhp_state_mutex); | 1565 | mutex_unlock(&cpuhp_state_mutex); |
1569 | put_online_cpus(); | 1566 | put_online_cpus(); |
@@ -1571,6 +1568,7 @@ remove: | |||
1571 | return 0; | 1568 | return 0; |
1572 | } | 1569 | } |
1573 | EXPORT_SYMBOL_GPL(__cpuhp_state_remove_instance); | 1570 | EXPORT_SYMBOL_GPL(__cpuhp_state_remove_instance); |
1571 | |||
1574 | /** | 1572 | /** |
1575 | * __cpuhp_remove_state - Remove the callbacks for an hotplug machine state | 1573 | * __cpuhp_remove_state - Remove the callbacks for an hotplug machine state |
1576 | * @state: The state to remove | 1574 | * @state: The state to remove |
@@ -1589,6 +1587,7 @@ void __cpuhp_remove_state(enum cpuhp_state state, bool invoke) | |||
1589 | 1587 | ||
1590 | get_online_cpus(); | 1588 | get_online_cpus(); |
1591 | 1589 | ||
1590 | mutex_lock(&cpuhp_state_mutex); | ||
1592 | if (sp->multi_instance) { | 1591 | if (sp->multi_instance) { |
1593 | WARN(!hlist_empty(&sp->list), | 1592 | WARN(!hlist_empty(&sp->list), |
1594 | "Error: Removing state %d which has instances left.\n", | 1593 | "Error: Removing state %d which has instances left.\n", |
@@ -1613,6 +1612,7 @@ void __cpuhp_remove_state(enum cpuhp_state state, bool invoke) | |||
1613 | } | 1612 | } |
1614 | remove: | 1613 | remove: |
1615 | cpuhp_store_callbacks(state, NULL, NULL, NULL, false); | 1614 | cpuhp_store_callbacks(state, NULL, NULL, NULL, false); |
1615 | mutex_unlock(&cpuhp_state_mutex); | ||
1616 | put_online_cpus(); | 1616 | put_online_cpus(); |
1617 | } | 1617 | } |
1618 | EXPORT_SYMBOL(__cpuhp_remove_state); | 1618 | EXPORT_SYMBOL(__cpuhp_remove_state); |
diff --git a/kernel/events/core.c b/kernel/events/core.c index a17ed56c8ce1..ff01cba86f43 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -4256,7 +4256,7 @@ int perf_event_release_kernel(struct perf_event *event) | |||
4256 | 4256 | ||
4257 | raw_spin_lock_irq(&ctx->lock); | 4257 | raw_spin_lock_irq(&ctx->lock); |
4258 | /* | 4258 | /* |
4259 | * Mark this even as STATE_DEAD, there is no external reference to it | 4259 | * Mark this event as STATE_DEAD, there is no external reference to it |
4260 | * anymore. | 4260 | * anymore. |
4261 | * | 4261 | * |
4262 | * Anybody acquiring event->child_mutex after the below loop _must_ | 4262 | * Anybody acquiring event->child_mutex after the below loop _must_ |
@@ -10417,21 +10417,22 @@ void perf_event_free_task(struct task_struct *task) | |||
10417 | continue; | 10417 | continue; |
10418 | 10418 | ||
10419 | mutex_lock(&ctx->mutex); | 10419 | mutex_lock(&ctx->mutex); |
10420 | again: | 10420 | raw_spin_lock_irq(&ctx->lock); |
10421 | list_for_each_entry_safe(event, tmp, &ctx->pinned_groups, | 10421 | /* |
10422 | group_entry) | 10422 | * Destroy the task <-> ctx relation and mark the context dead. |
10423 | perf_free_event(event, ctx); | 10423 | * |
10424 | * This is important because even though the task hasn't been | ||
10425 | * exposed yet the context has been (through child_list). | ||
10426 | */ | ||
10427 | RCU_INIT_POINTER(task->perf_event_ctxp[ctxn], NULL); | ||
10428 | WRITE_ONCE(ctx->task, TASK_TOMBSTONE); | ||
10429 | put_task_struct(task); /* cannot be last */ | ||
10430 | raw_spin_unlock_irq(&ctx->lock); | ||
10424 | 10431 | ||
10425 | list_for_each_entry_safe(event, tmp, &ctx->flexible_groups, | 10432 | list_for_each_entry_safe(event, tmp, &ctx->event_list, event_entry) |
10426 | group_entry) | ||
10427 | perf_free_event(event, ctx); | 10433 | perf_free_event(event, ctx); |
10428 | 10434 | ||
10429 | if (!list_empty(&ctx->pinned_groups) || | ||
10430 | !list_empty(&ctx->flexible_groups)) | ||
10431 | goto again; | ||
10432 | |||
10433 | mutex_unlock(&ctx->mutex); | 10435 | mutex_unlock(&ctx->mutex); |
10434 | |||
10435 | put_ctx(ctx); | 10436 | put_ctx(ctx); |
10436 | } | 10437 | } |
10437 | } | 10438 | } |
@@ -10469,7 +10470,12 @@ const struct perf_event_attr *perf_event_attrs(struct perf_event *event) | |||
10469 | } | 10470 | } |
10470 | 10471 | ||
10471 | /* | 10472 | /* |
10472 | * inherit a event from parent task to child task: | 10473 | * Inherit a event from parent task to child task. |
10474 | * | ||
10475 | * Returns: | ||
10476 | * - valid pointer on success | ||
10477 | * - NULL for orphaned events | ||
10478 | * - IS_ERR() on error | ||
10473 | */ | 10479 | */ |
10474 | static struct perf_event * | 10480 | static struct perf_event * |
10475 | inherit_event(struct perf_event *parent_event, | 10481 | inherit_event(struct perf_event *parent_event, |
@@ -10563,6 +10569,16 @@ inherit_event(struct perf_event *parent_event, | |||
10563 | return child_event; | 10569 | return child_event; |
10564 | } | 10570 | } |
10565 | 10571 | ||
10572 | /* | ||
10573 | * Inherits an event group. | ||
10574 | * | ||
10575 | * This will quietly suppress orphaned events; !inherit_event() is not an error. | ||
10576 | * This matches with perf_event_release_kernel() removing all child events. | ||
10577 | * | ||
10578 | * Returns: | ||
10579 | * - 0 on success | ||
10580 | * - <0 on error | ||
10581 | */ | ||
10566 | static int inherit_group(struct perf_event *parent_event, | 10582 | static int inherit_group(struct perf_event *parent_event, |
10567 | struct task_struct *parent, | 10583 | struct task_struct *parent, |
10568 | struct perf_event_context *parent_ctx, | 10584 | struct perf_event_context *parent_ctx, |
@@ -10577,6 +10593,11 @@ static int inherit_group(struct perf_event *parent_event, | |||
10577 | child, NULL, child_ctx); | 10593 | child, NULL, child_ctx); |
10578 | if (IS_ERR(leader)) | 10594 | if (IS_ERR(leader)) |
10579 | return PTR_ERR(leader); | 10595 | return PTR_ERR(leader); |
10596 | /* | ||
10597 | * @leader can be NULL here because of is_orphaned_event(). In this | ||
10598 | * case inherit_event() will create individual events, similar to what | ||
10599 | * perf_group_detach() would do anyway. | ||
10600 | */ | ||
10580 | list_for_each_entry(sub, &parent_event->sibling_list, group_entry) { | 10601 | list_for_each_entry(sub, &parent_event->sibling_list, group_entry) { |
10581 | child_ctr = inherit_event(sub, parent, parent_ctx, | 10602 | child_ctr = inherit_event(sub, parent, parent_ctx, |
10582 | child, leader, child_ctx); | 10603 | child, leader, child_ctx); |
@@ -10586,6 +10607,17 @@ static int inherit_group(struct perf_event *parent_event, | |||
10586 | return 0; | 10607 | return 0; |
10587 | } | 10608 | } |
10588 | 10609 | ||
10610 | /* | ||
10611 | * Creates the child task context and tries to inherit the event-group. | ||
10612 | * | ||
10613 | * Clears @inherited_all on !attr.inherited or error. Note that we'll leave | ||
10614 | * inherited_all set when we 'fail' to inherit an orphaned event; this is | ||
10615 | * consistent with perf_event_release_kernel() removing all child events. | ||
10616 | * | ||
10617 | * Returns: | ||
10618 | * - 0 on success | ||
10619 | * - <0 on error | ||
10620 | */ | ||
10589 | static int | 10621 | static int |
10590 | inherit_task_group(struct perf_event *event, struct task_struct *parent, | 10622 | inherit_task_group(struct perf_event *event, struct task_struct *parent, |
10591 | struct perf_event_context *parent_ctx, | 10623 | struct perf_event_context *parent_ctx, |
@@ -10608,7 +10640,6 @@ inherit_task_group(struct perf_event *event, struct task_struct *parent, | |||
10608 | * First allocate and initialize a context for the | 10640 | * First allocate and initialize a context for the |
10609 | * child. | 10641 | * child. |
10610 | */ | 10642 | */ |
10611 | |||
10612 | child_ctx = alloc_perf_context(parent_ctx->pmu, child); | 10643 | child_ctx = alloc_perf_context(parent_ctx->pmu, child); |
10613 | if (!child_ctx) | 10644 | if (!child_ctx) |
10614 | return -ENOMEM; | 10645 | return -ENOMEM; |
@@ -10670,7 +10701,7 @@ static int perf_event_init_context(struct task_struct *child, int ctxn) | |||
10670 | ret = inherit_task_group(event, parent, parent_ctx, | 10701 | ret = inherit_task_group(event, parent, parent_ctx, |
10671 | child, ctxn, &inherited_all); | 10702 | child, ctxn, &inherited_all); |
10672 | if (ret) | 10703 | if (ret) |
10673 | break; | 10704 | goto out_unlock; |
10674 | } | 10705 | } |
10675 | 10706 | ||
10676 | /* | 10707 | /* |
@@ -10686,7 +10717,7 @@ static int perf_event_init_context(struct task_struct *child, int ctxn) | |||
10686 | ret = inherit_task_group(event, parent, parent_ctx, | 10717 | ret = inherit_task_group(event, parent, parent_ctx, |
10687 | child, ctxn, &inherited_all); | 10718 | child, ctxn, &inherited_all); |
10688 | if (ret) | 10719 | if (ret) |
10689 | break; | 10720 | goto out_unlock; |
10690 | } | 10721 | } |
10691 | 10722 | ||
10692 | raw_spin_lock_irqsave(&parent_ctx->lock, flags); | 10723 | raw_spin_lock_irqsave(&parent_ctx->lock, flags); |
@@ -10714,6 +10745,7 @@ static int perf_event_init_context(struct task_struct *child, int ctxn) | |||
10714 | } | 10745 | } |
10715 | 10746 | ||
10716 | raw_spin_unlock_irqrestore(&parent_ctx->lock, flags); | 10747 | raw_spin_unlock_irqrestore(&parent_ctx->lock, flags); |
10748 | out_unlock: | ||
10717 | mutex_unlock(&parent_ctx->mutex); | 10749 | mutex_unlock(&parent_ctx->mutex); |
10718 | 10750 | ||
10719 | perf_unpin_context(parent_ctx); | 10751 | perf_unpin_context(parent_ctx); |
diff --git a/kernel/futex.c b/kernel/futex.c index 229a744b1781..45858ec73941 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -2815,7 +2815,6 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, | |||
2815 | { | 2815 | { |
2816 | struct hrtimer_sleeper timeout, *to = NULL; | 2816 | struct hrtimer_sleeper timeout, *to = NULL; |
2817 | struct rt_mutex_waiter rt_waiter; | 2817 | struct rt_mutex_waiter rt_waiter; |
2818 | struct rt_mutex *pi_mutex = NULL; | ||
2819 | struct futex_hash_bucket *hb; | 2818 | struct futex_hash_bucket *hb; |
2820 | union futex_key key2 = FUTEX_KEY_INIT; | 2819 | union futex_key key2 = FUTEX_KEY_INIT; |
2821 | struct futex_q q = futex_q_init; | 2820 | struct futex_q q = futex_q_init; |
@@ -2899,6 +2898,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, | |||
2899 | if (q.pi_state && (q.pi_state->owner != current)) { | 2898 | if (q.pi_state && (q.pi_state->owner != current)) { |
2900 | spin_lock(q.lock_ptr); | 2899 | spin_lock(q.lock_ptr); |
2901 | ret = fixup_pi_state_owner(uaddr2, &q, current); | 2900 | ret = fixup_pi_state_owner(uaddr2, &q, current); |
2901 | if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) | ||
2902 | rt_mutex_unlock(&q.pi_state->pi_mutex); | ||
2902 | /* | 2903 | /* |
2903 | * Drop the reference to the pi state which | 2904 | * Drop the reference to the pi state which |
2904 | * the requeue_pi() code acquired for us. | 2905 | * the requeue_pi() code acquired for us. |
@@ -2907,6 +2908,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, | |||
2907 | spin_unlock(q.lock_ptr); | 2908 | spin_unlock(q.lock_ptr); |
2908 | } | 2909 | } |
2909 | } else { | 2910 | } else { |
2911 | struct rt_mutex *pi_mutex; | ||
2912 | |||
2910 | /* | 2913 | /* |
2911 | * We have been woken up by futex_unlock_pi(), a timeout, or a | 2914 | * We have been woken up by futex_unlock_pi(), a timeout, or a |
2912 | * signal. futex_unlock_pi() will not destroy the lock_ptr nor | 2915 | * signal. futex_unlock_pi() will not destroy the lock_ptr nor |
@@ -2930,18 +2933,19 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, | |||
2930 | if (res) | 2933 | if (res) |
2931 | ret = (res < 0) ? res : 0; | 2934 | ret = (res < 0) ? res : 0; |
2932 | 2935 | ||
2936 | /* | ||
2937 | * If fixup_pi_state_owner() faulted and was unable to handle | ||
2938 | * the fault, unlock the rt_mutex and return the fault to | ||
2939 | * userspace. | ||
2940 | */ | ||
2941 | if (ret && rt_mutex_owner(pi_mutex) == current) | ||
2942 | rt_mutex_unlock(pi_mutex); | ||
2943 | |||
2933 | /* Unqueue and drop the lock. */ | 2944 | /* Unqueue and drop the lock. */ |
2934 | unqueue_me_pi(&q); | 2945 | unqueue_me_pi(&q); |
2935 | } | 2946 | } |
2936 | 2947 | ||
2937 | /* | 2948 | if (ret == -EINTR) { |
2938 | * If fixup_pi_state_owner() faulted and was unable to handle the | ||
2939 | * fault, unlock the rt_mutex and return the fault to userspace. | ||
2940 | */ | ||
2941 | if (ret == -EFAULT) { | ||
2942 | if (pi_mutex && rt_mutex_owner(pi_mutex) == current) | ||
2943 | rt_mutex_unlock(pi_mutex); | ||
2944 | } else if (ret == -EINTR) { | ||
2945 | /* | 2949 | /* |
2946 | * We've already been requeued, but cannot restart by calling | 2950 | * We've already been requeued, but cannot restart by calling |
2947 | * futex_lock_pi() directly. We could restart this syscall, but | 2951 | * futex_lock_pi() directly. We could restart this syscall, but |
diff --git a/kernel/locking/rwsem-spinlock.c b/kernel/locking/rwsem-spinlock.c index 7bc24d477805..c65f7989f850 100644 --- a/kernel/locking/rwsem-spinlock.c +++ b/kernel/locking/rwsem-spinlock.c | |||
@@ -213,10 +213,9 @@ int __sched __down_write_common(struct rw_semaphore *sem, int state) | |||
213 | */ | 213 | */ |
214 | if (sem->count == 0) | 214 | if (sem->count == 0) |
215 | break; | 215 | break; |
216 | if (signal_pending_state(state, current)) { | 216 | if (signal_pending_state(state, current)) |
217 | ret = -EINTR; | 217 | goto out_nolock; |
218 | goto out; | 218 | |
219 | } | ||
220 | set_current_state(state); | 219 | set_current_state(state); |
221 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | 220 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); |
222 | schedule(); | 221 | schedule(); |
@@ -224,12 +223,19 @@ int __sched __down_write_common(struct rw_semaphore *sem, int state) | |||
224 | } | 223 | } |
225 | /* got the lock */ | 224 | /* got the lock */ |
226 | sem->count = -1; | 225 | sem->count = -1; |
227 | out: | ||
228 | list_del(&waiter.list); | 226 | list_del(&waiter.list); |
229 | 227 | ||
230 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | 228 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); |
231 | 229 | ||
232 | return ret; | 230 | return ret; |
231 | |||
232 | out_nolock: | ||
233 | list_del(&waiter.list); | ||
234 | if (!list_empty(&sem->wait_list)) | ||
235 | __rwsem_do_wake(sem, 1); | ||
236 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
237 | |||
238 | return -EINTR; | ||
233 | } | 239 | } |
234 | 240 | ||
235 | void __sched __down_write(struct rw_semaphore *sem) | 241 | void __sched __down_write(struct rw_semaphore *sem) |
diff --git a/kernel/memremap.c b/kernel/memremap.c index 06123234f118..07e85e5229da 100644 --- a/kernel/memremap.c +++ b/kernel/memremap.c | |||
@@ -247,11 +247,9 @@ static void devm_memremap_pages_release(struct device *dev, void *data) | |||
247 | align_start = res->start & ~(SECTION_SIZE - 1); | 247 | align_start = res->start & ~(SECTION_SIZE - 1); |
248 | align_size = ALIGN(resource_size(res), SECTION_SIZE); | 248 | align_size = ALIGN(resource_size(res), SECTION_SIZE); |
249 | 249 | ||
250 | lock_device_hotplug(); | ||
251 | mem_hotplug_begin(); | 250 | mem_hotplug_begin(); |
252 | arch_remove_memory(align_start, align_size); | 251 | arch_remove_memory(align_start, align_size); |
253 | mem_hotplug_done(); | 252 | mem_hotplug_done(); |
254 | unlock_device_hotplug(); | ||
255 | 253 | ||
256 | untrack_pfn(NULL, PHYS_PFN(align_start), align_size); | 254 | untrack_pfn(NULL, PHYS_PFN(align_start), align_size); |
257 | pgmap_radix_release(res); | 255 | pgmap_radix_release(res); |
@@ -364,11 +362,9 @@ void *devm_memremap_pages(struct device *dev, struct resource *res, | |||
364 | if (error) | 362 | if (error) |
365 | goto err_pfn_remap; | 363 | goto err_pfn_remap; |
366 | 364 | ||
367 | lock_device_hotplug(); | ||
368 | mem_hotplug_begin(); | 365 | mem_hotplug_begin(); |
369 | error = arch_add_memory(nid, align_start, align_size, true); | 366 | error = arch_add_memory(nid, align_start, align_size, true); |
370 | mem_hotplug_done(); | 367 | mem_hotplug_done(); |
371 | unlock_device_hotplug(); | ||
372 | if (error) | 368 | if (error) |
373 | goto err_add_memory; | 369 | goto err_add_memory; |
374 | 370 | ||
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index 99b2c33a9fbc..a2ce59015642 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c | |||
@@ -445,13 +445,13 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se, | |||
445 | * | 445 | * |
446 | * This function returns true if: | 446 | * This function returns true if: |
447 | * | 447 | * |
448 | * runtime / (deadline - t) > dl_runtime / dl_period , | 448 | * runtime / (deadline - t) > dl_runtime / dl_deadline , |
449 | * | 449 | * |
450 | * IOW we can't recycle current parameters. | 450 | * IOW we can't recycle current parameters. |
451 | * | 451 | * |
452 | * Notice that the bandwidth check is done against the period. For | 452 | * Notice that the bandwidth check is done against the deadline. For |
453 | * task with deadline equal to period this is the same of using | 453 | * task with deadline equal to period this is the same of using |
454 | * dl_deadline instead of dl_period in the equation above. | 454 | * dl_period instead of dl_deadline in the equation above. |
455 | */ | 455 | */ |
456 | static bool dl_entity_overflow(struct sched_dl_entity *dl_se, | 456 | static bool dl_entity_overflow(struct sched_dl_entity *dl_se, |
457 | struct sched_dl_entity *pi_se, u64 t) | 457 | struct sched_dl_entity *pi_se, u64 t) |
@@ -476,7 +476,7 @@ static bool dl_entity_overflow(struct sched_dl_entity *dl_se, | |||
476 | * of anything below microseconds resolution is actually fiction | 476 | * of anything below microseconds resolution is actually fiction |
477 | * (but still we want to give the user that illusion >;). | 477 | * (but still we want to give the user that illusion >;). |
478 | */ | 478 | */ |
479 | left = (pi_se->dl_period >> DL_SCALE) * (dl_se->runtime >> DL_SCALE); | 479 | left = (pi_se->dl_deadline >> DL_SCALE) * (dl_se->runtime >> DL_SCALE); |
480 | right = ((dl_se->deadline - t) >> DL_SCALE) * | 480 | right = ((dl_se->deadline - t) >> DL_SCALE) * |
481 | (pi_se->dl_runtime >> DL_SCALE); | 481 | (pi_se->dl_runtime >> DL_SCALE); |
482 | 482 | ||
@@ -505,10 +505,15 @@ static void update_dl_entity(struct sched_dl_entity *dl_se, | |||
505 | } | 505 | } |
506 | } | 506 | } |
507 | 507 | ||
508 | static inline u64 dl_next_period(struct sched_dl_entity *dl_se) | ||
509 | { | ||
510 | return dl_se->deadline - dl_se->dl_deadline + dl_se->dl_period; | ||
511 | } | ||
512 | |||
508 | /* | 513 | /* |
509 | * If the entity depleted all its runtime, and if we want it to sleep | 514 | * If the entity depleted all its runtime, and if we want it to sleep |
510 | * while waiting for some new execution time to become available, we | 515 | * while waiting for some new execution time to become available, we |
511 | * set the bandwidth enforcement timer to the replenishment instant | 516 | * set the bandwidth replenishment timer to the replenishment instant |
512 | * and try to activate it. | 517 | * and try to activate it. |
513 | * | 518 | * |
514 | * Notice that it is important for the caller to know if the timer | 519 | * Notice that it is important for the caller to know if the timer |
@@ -530,7 +535,7 @@ static int start_dl_timer(struct task_struct *p) | |||
530 | * that it is actually coming from rq->clock and not from | 535 | * that it is actually coming from rq->clock and not from |
531 | * hrtimer's time base reading. | 536 | * hrtimer's time base reading. |
532 | */ | 537 | */ |
533 | act = ns_to_ktime(dl_se->deadline); | 538 | act = ns_to_ktime(dl_next_period(dl_se)); |
534 | now = hrtimer_cb_get_time(timer); | 539 | now = hrtimer_cb_get_time(timer); |
535 | delta = ktime_to_ns(now) - rq_clock(rq); | 540 | delta = ktime_to_ns(now) - rq_clock(rq); |
536 | act = ktime_add_ns(act, delta); | 541 | act = ktime_add_ns(act, delta); |
@@ -638,6 +643,7 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer) | |||
638 | lockdep_unpin_lock(&rq->lock, rf.cookie); | 643 | lockdep_unpin_lock(&rq->lock, rf.cookie); |
639 | rq = dl_task_offline_migration(rq, p); | 644 | rq = dl_task_offline_migration(rq, p); |
640 | rf.cookie = lockdep_pin_lock(&rq->lock); | 645 | rf.cookie = lockdep_pin_lock(&rq->lock); |
646 | update_rq_clock(rq); | ||
641 | 647 | ||
642 | /* | 648 | /* |
643 | * Now that the task has been migrated to the new RQ and we | 649 | * Now that the task has been migrated to the new RQ and we |
@@ -689,6 +695,37 @@ void init_dl_task_timer(struct sched_dl_entity *dl_se) | |||
689 | timer->function = dl_task_timer; | 695 | timer->function = dl_task_timer; |
690 | } | 696 | } |
691 | 697 | ||
698 | /* | ||
699 | * During the activation, CBS checks if it can reuse the current task's | ||
700 | * runtime and period. If the deadline of the task is in the past, CBS | ||
701 | * cannot use the runtime, and so it replenishes the task. This rule | ||
702 | * works fine for implicit deadline tasks (deadline == period), and the | ||
703 | * CBS was designed for implicit deadline tasks. However, a task with | ||
704 | * constrained deadline (deadine < period) might be awakened after the | ||
705 | * deadline, but before the next period. In this case, replenishing the | ||
706 | * task would allow it to run for runtime / deadline. As in this case | ||
707 | * deadline < period, CBS enables a task to run for more than the | ||
708 | * runtime / period. In a very loaded system, this can cause a domino | ||
709 | * effect, making other tasks miss their deadlines. | ||
710 | * | ||
711 | * To avoid this problem, in the activation of a constrained deadline | ||
712 | * task after the deadline but before the next period, throttle the | ||
713 | * task and set the replenishing timer to the begin of the next period, | ||
714 | * unless it is boosted. | ||
715 | */ | ||
716 | static inline void dl_check_constrained_dl(struct sched_dl_entity *dl_se) | ||
717 | { | ||
718 | struct task_struct *p = dl_task_of(dl_se); | ||
719 | struct rq *rq = rq_of_dl_rq(dl_rq_of_se(dl_se)); | ||
720 | |||
721 | if (dl_time_before(dl_se->deadline, rq_clock(rq)) && | ||
722 | dl_time_before(rq_clock(rq), dl_next_period(dl_se))) { | ||
723 | if (unlikely(dl_se->dl_boosted || !start_dl_timer(p))) | ||
724 | return; | ||
725 | dl_se->dl_throttled = 1; | ||
726 | } | ||
727 | } | ||
728 | |||
692 | static | 729 | static |
693 | int dl_runtime_exceeded(struct sched_dl_entity *dl_se) | 730 | int dl_runtime_exceeded(struct sched_dl_entity *dl_se) |
694 | { | 731 | { |
@@ -922,6 +959,11 @@ static void dequeue_dl_entity(struct sched_dl_entity *dl_se) | |||
922 | __dequeue_dl_entity(dl_se); | 959 | __dequeue_dl_entity(dl_se); |
923 | } | 960 | } |
924 | 961 | ||
962 | static inline bool dl_is_constrained(struct sched_dl_entity *dl_se) | ||
963 | { | ||
964 | return dl_se->dl_deadline < dl_se->dl_period; | ||
965 | } | ||
966 | |||
925 | static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags) | 967 | static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags) |
926 | { | 968 | { |
927 | struct task_struct *pi_task = rt_mutex_get_top_task(p); | 969 | struct task_struct *pi_task = rt_mutex_get_top_task(p); |
@@ -948,6 +990,15 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags) | |||
948 | } | 990 | } |
949 | 991 | ||
950 | /* | 992 | /* |
993 | * Check if a constrained deadline task was activated | ||
994 | * after the deadline but before the next period. | ||
995 | * If that is the case, the task will be throttled and | ||
996 | * the replenishment timer will be set to the next period. | ||
997 | */ | ||
998 | if (!p->dl.dl_throttled && dl_is_constrained(&p->dl)) | ||
999 | dl_check_constrained_dl(&p->dl); | ||
1000 | |||
1001 | /* | ||
951 | * If p is throttled, we do nothing. In fact, if it exhausted | 1002 | * If p is throttled, we do nothing. In fact, if it exhausted |
952 | * its budget it needs a replenishment and, since it now is on | 1003 | * its budget it needs a replenishment and, since it now is on |
953 | * its rq, the bandwidth timer callback (which clearly has not | 1004 | * its rq, the bandwidth timer callback (which clearly has not |
diff --git a/kernel/sched/loadavg.c b/kernel/sched/loadavg.c index 7296b7308eca..f15fb2bdbc0d 100644 --- a/kernel/sched/loadavg.c +++ b/kernel/sched/loadavg.c | |||
@@ -169,7 +169,7 @@ static inline int calc_load_write_idx(void) | |||
169 | * If the folding window started, make sure we start writing in the | 169 | * If the folding window started, make sure we start writing in the |
170 | * next idle-delta. | 170 | * next idle-delta. |
171 | */ | 171 | */ |
172 | if (!time_before(jiffies, calc_load_update)) | 172 | if (!time_before(jiffies, READ_ONCE(calc_load_update))) |
173 | idx++; | 173 | idx++; |
174 | 174 | ||
175 | return idx & 1; | 175 | return idx & 1; |
@@ -202,8 +202,9 @@ void calc_load_exit_idle(void) | |||
202 | struct rq *this_rq = this_rq(); | 202 | struct rq *this_rq = this_rq(); |
203 | 203 | ||
204 | /* | 204 | /* |
205 | * If we're still before the sample window, we're done. | 205 | * If we're still before the pending sample window, we're done. |
206 | */ | 206 | */ |
207 | this_rq->calc_load_update = READ_ONCE(calc_load_update); | ||
207 | if (time_before(jiffies, this_rq->calc_load_update)) | 208 | if (time_before(jiffies, this_rq->calc_load_update)) |
208 | return; | 209 | return; |
209 | 210 | ||
@@ -212,7 +213,6 @@ void calc_load_exit_idle(void) | |||
212 | * accounted through the nohz accounting, so skip the entire deal and | 213 | * accounted through the nohz accounting, so skip the entire deal and |
213 | * sync up for the next window. | 214 | * sync up for the next window. |
214 | */ | 215 | */ |
215 | this_rq->calc_load_update = calc_load_update; | ||
216 | if (time_before(jiffies, this_rq->calc_load_update + 10)) | 216 | if (time_before(jiffies, this_rq->calc_load_update + 10)) |
217 | this_rq->calc_load_update += LOAD_FREQ; | 217 | this_rq->calc_load_update += LOAD_FREQ; |
218 | } | 218 | } |
@@ -308,13 +308,15 @@ calc_load_n(unsigned long load, unsigned long exp, | |||
308 | */ | 308 | */ |
309 | static void calc_global_nohz(void) | 309 | static void calc_global_nohz(void) |
310 | { | 310 | { |
311 | unsigned long sample_window; | ||
311 | long delta, active, n; | 312 | long delta, active, n; |
312 | 313 | ||
313 | if (!time_before(jiffies, calc_load_update + 10)) { | 314 | sample_window = READ_ONCE(calc_load_update); |
315 | if (!time_before(jiffies, sample_window + 10)) { | ||
314 | /* | 316 | /* |
315 | * Catch-up, fold however many we are behind still | 317 | * Catch-up, fold however many we are behind still |
316 | */ | 318 | */ |
317 | delta = jiffies - calc_load_update - 10; | 319 | delta = jiffies - sample_window - 10; |
318 | n = 1 + (delta / LOAD_FREQ); | 320 | n = 1 + (delta / LOAD_FREQ); |
319 | 321 | ||
320 | active = atomic_long_read(&calc_load_tasks); | 322 | active = atomic_long_read(&calc_load_tasks); |
@@ -324,7 +326,7 @@ static void calc_global_nohz(void) | |||
324 | avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n); | 326 | avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n); |
325 | avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n); | 327 | avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n); |
326 | 328 | ||
327 | calc_load_update += n * LOAD_FREQ; | 329 | WRITE_ONCE(calc_load_update, sample_window + n * LOAD_FREQ); |
328 | } | 330 | } |
329 | 331 | ||
330 | /* | 332 | /* |
@@ -352,9 +354,11 @@ static inline void calc_global_nohz(void) { } | |||
352 | */ | 354 | */ |
353 | void calc_global_load(unsigned long ticks) | 355 | void calc_global_load(unsigned long ticks) |
354 | { | 356 | { |
357 | unsigned long sample_window; | ||
355 | long active, delta; | 358 | long active, delta; |
356 | 359 | ||
357 | if (time_before(jiffies, calc_load_update + 10)) | 360 | sample_window = READ_ONCE(calc_load_update); |
361 | if (time_before(jiffies, sample_window + 10)) | ||
358 | return; | 362 | return; |
359 | 363 | ||
360 | /* | 364 | /* |
@@ -371,7 +375,7 @@ void calc_global_load(unsigned long ticks) | |||
371 | avenrun[1] = calc_load(avenrun[1], EXP_5, active); | 375 | avenrun[1] = calc_load(avenrun[1], EXP_5, active); |
372 | avenrun[2] = calc_load(avenrun[2], EXP_15, active); | 376 | avenrun[2] = calc_load(avenrun[2], EXP_15, active); |
373 | 377 | ||
374 | calc_load_update += LOAD_FREQ; | 378 | WRITE_ONCE(calc_load_update, sample_window + LOAD_FREQ); |
375 | 379 | ||
376 | /* | 380 | /* |
377 | * In case we idled for multiple LOAD_FREQ intervals, catch up in bulk. | 381 | * In case we idled for multiple LOAD_FREQ intervals, catch up in bulk. |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 072cbc9b175d..c0168b7da1ea 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -1507,6 +1507,7 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq, | |||
1507 | struct timer_list *timer = &dwork->timer; | 1507 | struct timer_list *timer = &dwork->timer; |
1508 | struct work_struct *work = &dwork->work; | 1508 | struct work_struct *work = &dwork->work; |
1509 | 1509 | ||
1510 | WARN_ON_ONCE(!wq); | ||
1510 | WARN_ON_ONCE(timer->function != delayed_work_timer_fn || | 1511 | WARN_ON_ONCE(timer->function != delayed_work_timer_fn || |
1511 | timer->data != (unsigned long)dwork); | 1512 | timer->data != (unsigned long)dwork); |
1512 | WARN_ON_ONCE(timer_pending(timer)); | 1513 | WARN_ON_ONCE(timer_pending(timer)); |
@@ -1455,7 +1455,7 @@ static int gup_p4d_range(pgd_t pgd, unsigned long addr, unsigned long end, | |||
1455 | if (!gup_huge_pd(__hugepd(p4d_val(p4d)), addr, | 1455 | if (!gup_huge_pd(__hugepd(p4d_val(p4d)), addr, |
1456 | P4D_SHIFT, next, write, pages, nr)) | 1456 | P4D_SHIFT, next, write, pages, nr)) |
1457 | return 0; | 1457 | return 0; |
1458 | } else if (!gup_p4d_range(p4d, addr, next, write, pages, nr)) | 1458 | } else if (!gup_pud_range(p4d, addr, next, write, pages, nr)) |
1459 | return 0; | 1459 | return 0; |
1460 | } while (p4dp++, addr = next, addr != end); | 1460 | } while (p4dp++, addr = next, addr != end); |
1461 | 1461 | ||
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 295479b792ec..6fa7208bcd56 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -125,9 +125,12 @@ void put_online_mems(void) | |||
125 | 125 | ||
126 | } | 126 | } |
127 | 127 | ||
128 | /* Serializes write accesses to mem_hotplug.active_writer. */ | ||
129 | static DEFINE_MUTEX(memory_add_remove_lock); | ||
130 | |||
128 | void mem_hotplug_begin(void) | 131 | void mem_hotplug_begin(void) |
129 | { | 132 | { |
130 | assert_held_device_hotplug(); | 133 | mutex_lock(&memory_add_remove_lock); |
131 | 134 | ||
132 | mem_hotplug.active_writer = current; | 135 | mem_hotplug.active_writer = current; |
133 | 136 | ||
@@ -147,6 +150,7 @@ void mem_hotplug_done(void) | |||
147 | mem_hotplug.active_writer = NULL; | 150 | mem_hotplug.active_writer = NULL; |
148 | mutex_unlock(&mem_hotplug.lock); | 151 | mutex_unlock(&mem_hotplug.lock); |
149 | memhp_lock_release(); | 152 | memhp_lock_release(); |
153 | mutex_unlock(&memory_add_remove_lock); | ||
150 | } | 154 | } |
151 | 155 | ||
152 | /* add this memory to iomem resource */ | 156 | /* add this memory to iomem resource */ |
diff --git a/mm/percpu-vm.c b/mm/percpu-vm.c index 538998a137d2..9ac639499bd1 100644 --- a/mm/percpu-vm.c +++ b/mm/percpu-vm.c | |||
@@ -21,7 +21,6 @@ static struct page *pcpu_chunk_page(struct pcpu_chunk *chunk, | |||
21 | 21 | ||
22 | /** | 22 | /** |
23 | * pcpu_get_pages - get temp pages array | 23 | * pcpu_get_pages - get temp pages array |
24 | * @chunk: chunk of interest | ||
25 | * | 24 | * |
26 | * Returns pointer to array of pointers to struct page which can be indexed | 25 | * Returns pointer to array of pointers to struct page which can be indexed |
27 | * with pcpu_page_idx(). Note that there is only one array and accesses | 26 | * with pcpu_page_idx(). Note that there is only one array and accesses |
@@ -30,7 +29,7 @@ static struct page *pcpu_chunk_page(struct pcpu_chunk *chunk, | |||
30 | * RETURNS: | 29 | * RETURNS: |
31 | * Pointer to temp pages array on success. | 30 | * Pointer to temp pages array on success. |
32 | */ | 31 | */ |
33 | static struct page **pcpu_get_pages(struct pcpu_chunk *chunk_alloc) | 32 | static struct page **pcpu_get_pages(void) |
34 | { | 33 | { |
35 | static struct page **pages; | 34 | static struct page **pages; |
36 | size_t pages_size = pcpu_nr_units * pcpu_unit_pages * sizeof(pages[0]); | 35 | size_t pages_size = pcpu_nr_units * pcpu_unit_pages * sizeof(pages[0]); |
@@ -275,7 +274,7 @@ static int pcpu_populate_chunk(struct pcpu_chunk *chunk, | |||
275 | { | 274 | { |
276 | struct page **pages; | 275 | struct page **pages; |
277 | 276 | ||
278 | pages = pcpu_get_pages(chunk); | 277 | pages = pcpu_get_pages(); |
279 | if (!pages) | 278 | if (!pages) |
280 | return -ENOMEM; | 279 | return -ENOMEM; |
281 | 280 | ||
@@ -313,7 +312,7 @@ static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, | |||
313 | * successful population attempt so the temp pages array must | 312 | * successful population attempt so the temp pages array must |
314 | * be available now. | 313 | * be available now. |
315 | */ | 314 | */ |
316 | pages = pcpu_get_pages(chunk); | 315 | pages = pcpu_get_pages(); |
317 | BUG_ON(!pages); | 316 | BUG_ON(!pages); |
318 | 317 | ||
319 | /* unmap and free */ | 318 | /* unmap and free */ |
diff --git a/mm/percpu.c b/mm/percpu.c index 5696039b5c07..60a6488e9e6d 100644 --- a/mm/percpu.c +++ b/mm/percpu.c | |||
@@ -1011,8 +1011,11 @@ area_found: | |||
1011 | mutex_unlock(&pcpu_alloc_mutex); | 1011 | mutex_unlock(&pcpu_alloc_mutex); |
1012 | } | 1012 | } |
1013 | 1013 | ||
1014 | if (chunk != pcpu_reserved_chunk) | 1014 | if (chunk != pcpu_reserved_chunk) { |
1015 | spin_lock_irqsave(&pcpu_lock, flags); | ||
1015 | pcpu_nr_empty_pop_pages -= occ_pages; | 1016 | pcpu_nr_empty_pop_pages -= occ_pages; |
1017 | spin_unlock_irqrestore(&pcpu_lock, flags); | ||
1018 | } | ||
1016 | 1019 | ||
1017 | if (pcpu_nr_empty_pop_pages < PCPU_EMPTY_POP_PAGES_LOW) | 1020 | if (pcpu_nr_empty_pop_pages < PCPU_EMPTY_POP_PAGES_LOW) |
1018 | pcpu_schedule_balance_work(); | 1021 | pcpu_schedule_balance_work(); |
diff --git a/mm/swap_slots.c b/mm/swap_slots.c index 9b5bc86f96ad..7ebb23836f68 100644 --- a/mm/swap_slots.c +++ b/mm/swap_slots.c | |||
@@ -267,7 +267,7 @@ int free_swap_slot(swp_entry_t entry) | |||
267 | { | 267 | { |
268 | struct swap_slots_cache *cache; | 268 | struct swap_slots_cache *cache; |
269 | 269 | ||
270 | BUG_ON(!swap_slot_cache_initialized); | 270 | WARN_ON_ONCE(!swap_slot_cache_initialized); |
271 | 271 | ||
272 | cache = &get_cpu_var(swp_slots); | 272 | cache = &get_cpu_var(swp_slots); |
273 | if (use_swap_slot_cache && cache->slots_ret) { | 273 | if (use_swap_slot_cache && cache->slots_ret) { |
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 0dd80222b20b..0b057628a7ba 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c | |||
@@ -1683,7 +1683,7 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, | |||
1683 | 1683 | ||
1684 | if (fatal_signal_pending(current)) { | 1684 | if (fatal_signal_pending(current)) { |
1685 | area->nr_pages = i; | 1685 | area->nr_pages = i; |
1686 | goto fail; | 1686 | goto fail_no_warn; |
1687 | } | 1687 | } |
1688 | 1688 | ||
1689 | if (node == NUMA_NO_NODE) | 1689 | if (node == NUMA_NO_NODE) |
@@ -1709,6 +1709,7 @@ fail: | |||
1709 | warn_alloc(gfp_mask, NULL, | 1709 | warn_alloc(gfp_mask, NULL, |
1710 | "vmalloc: allocation failure, allocated %ld of %ld bytes", | 1710 | "vmalloc: allocation failure, allocated %ld of %ld bytes", |
1711 | (area->nr_pages*PAGE_SIZE), area->size); | 1711 | (area->nr_pages*PAGE_SIZE), area->size); |
1712 | fail_no_warn: | ||
1712 | vfree(area->addr); | 1713 | vfree(area->addr); |
1713 | return NULL; | 1714 | return NULL; |
1714 | } | 1715 | } |
diff --git a/mm/z3fold.c b/mm/z3fold.c index 8970a2fd3b1a..f9492bccfd79 100644 --- a/mm/z3fold.c +++ b/mm/z3fold.c | |||
@@ -667,6 +667,7 @@ next: | |||
667 | z3fold_page_unlock(zhdr); | 667 | z3fold_page_unlock(zhdr); |
668 | spin_lock(&pool->lock); | 668 | spin_lock(&pool->lock); |
669 | if (kref_put(&zhdr->refcount, release_z3fold_page)) { | 669 | if (kref_put(&zhdr->refcount, release_z3fold_page)) { |
670 | spin_unlock(&pool->lock); | ||
670 | atomic64_dec(&pool->pages_nr); | 671 | atomic64_dec(&pool->pages_nr); |
671 | return 0; | 672 | return 0; |
672 | } | 673 | } |
diff --git a/net/atm/svc.c b/net/atm/svc.c index db9794ec61d8..5589de7086af 100644 --- a/net/atm/svc.c +++ b/net/atm/svc.c | |||
@@ -318,7 +318,8 @@ out: | |||
318 | return error; | 318 | return error; |
319 | } | 319 | } |
320 | 320 | ||
321 | static int svc_accept(struct socket *sock, struct socket *newsock, int flags) | 321 | static int svc_accept(struct socket *sock, struct socket *newsock, int flags, |
322 | bool kern) | ||
322 | { | 323 | { |
323 | struct sock *sk = sock->sk; | 324 | struct sock *sk = sock->sk; |
324 | struct sk_buff *skb; | 325 | struct sk_buff *skb; |
@@ -329,7 +330,7 @@ static int svc_accept(struct socket *sock, struct socket *newsock, int flags) | |||
329 | 330 | ||
330 | lock_sock(sk); | 331 | lock_sock(sk); |
331 | 332 | ||
332 | error = svc_create(sock_net(sk), newsock, 0, 0); | 333 | error = svc_create(sock_net(sk), newsock, 0, kern); |
333 | if (error) | 334 | if (error) |
334 | goto out; | 335 | goto out; |
335 | 336 | ||
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index a8e42cedf1db..b7c486752b3a 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
@@ -1320,7 +1320,8 @@ out_release: | |||
1320 | return err; | 1320 | return err; |
1321 | } | 1321 | } |
1322 | 1322 | ||
1323 | static int ax25_accept(struct socket *sock, struct socket *newsock, int flags) | 1323 | static int ax25_accept(struct socket *sock, struct socket *newsock, int flags, |
1324 | bool kern) | ||
1324 | { | 1325 | { |
1325 | struct sk_buff *skb; | 1326 | struct sk_buff *skb; |
1326 | struct sock *newsk; | 1327 | struct sock *newsk; |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index f307b145ea54..507b80d59dec 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -301,7 +301,7 @@ done: | |||
301 | } | 301 | } |
302 | 302 | ||
303 | static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, | 303 | static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, |
304 | int flags) | 304 | int flags, bool kern) |
305 | { | 305 | { |
306 | DEFINE_WAIT_FUNC(wait, woken_wake_function); | 306 | DEFINE_WAIT_FUNC(wait, woken_wake_function); |
307 | struct sock *sk = sock->sk, *nsk; | 307 | struct sock *sk = sock->sk, *nsk; |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index aa1a814ceddc..ac3c650cb234 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -471,7 +471,8 @@ done: | |||
471 | return err; | 471 | return err; |
472 | } | 472 | } |
473 | 473 | ||
474 | static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags) | 474 | static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags, |
475 | bool kern) | ||
475 | { | 476 | { |
476 | DEFINE_WAIT_FUNC(wait, woken_wake_function); | 477 | DEFINE_WAIT_FUNC(wait, woken_wake_function); |
477 | struct sock *sk = sock->sk, *nsk; | 478 | struct sock *sk = sock->sk, *nsk; |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index e4e9a2da1e7e..728e0c8dc8e7 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -627,7 +627,7 @@ done: | |||
627 | } | 627 | } |
628 | 628 | ||
629 | static int sco_sock_accept(struct socket *sock, struct socket *newsock, | 629 | static int sco_sock_accept(struct socket *sock, struct socket *newsock, |
630 | int flags) | 630 | int flags, bool kern) |
631 | { | 631 | { |
632 | DEFINE_WAIT_FUNC(wait, woken_wake_function); | 632 | DEFINE_WAIT_FUNC(wait, woken_wake_function); |
633 | struct sock *sk = sock->sk, *ch; | 633 | struct sock *sk = sock->sk, *ch; |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 236f34244dbe..013f2290bfa5 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -30,6 +30,7 @@ EXPORT_SYMBOL(br_should_route_hook); | |||
30 | static int | 30 | static int |
31 | br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb) | 31 | br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb) |
32 | { | 32 | { |
33 | br_drop_fake_rtable(skb); | ||
33 | return netif_receive_skb(skb); | 34 | return netif_receive_skb(skb); |
34 | } | 35 | } |
35 | 36 | ||
diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c index 95087e6e8258..fa87fbd62bb7 100644 --- a/net/bridge/br_netfilter_hooks.c +++ b/net/bridge/br_netfilter_hooks.c | |||
@@ -521,21 +521,6 @@ static unsigned int br_nf_pre_routing(void *priv, | |||
521 | } | 521 | } |
522 | 522 | ||
523 | 523 | ||
524 | /* PF_BRIDGE/LOCAL_IN ************************************************/ | ||
525 | /* The packet is locally destined, which requires a real | ||
526 | * dst_entry, so detach the fake one. On the way up, the | ||
527 | * packet would pass through PRE_ROUTING again (which already | ||
528 | * took place when the packet entered the bridge), but we | ||
529 | * register an IPv4 PRE_ROUTING 'sabotage' hook that will | ||
530 | * prevent this from happening. */ | ||
531 | static unsigned int br_nf_local_in(void *priv, | ||
532 | struct sk_buff *skb, | ||
533 | const struct nf_hook_state *state) | ||
534 | { | ||
535 | br_drop_fake_rtable(skb); | ||
536 | return NF_ACCEPT; | ||
537 | } | ||
538 | |||
539 | /* PF_BRIDGE/FORWARD *************************************************/ | 524 | /* PF_BRIDGE/FORWARD *************************************************/ |
540 | static int br_nf_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb) | 525 | static int br_nf_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb) |
541 | { | 526 | { |
@@ -908,12 +893,6 @@ static struct nf_hook_ops br_nf_ops[] __read_mostly = { | |||
908 | .priority = NF_BR_PRI_BRNF, | 893 | .priority = NF_BR_PRI_BRNF, |
909 | }, | 894 | }, |
910 | { | 895 | { |
911 | .hook = br_nf_local_in, | ||
912 | .pf = NFPROTO_BRIDGE, | ||
913 | .hooknum = NF_BR_LOCAL_IN, | ||
914 | .priority = NF_BR_PRI_BRNF, | ||
915 | }, | ||
916 | { | ||
917 | .hook = br_nf_forward_ip, | 896 | .hook = br_nf_forward_ip, |
918 | .pf = NFPROTO_BRIDGE, | 897 | .pf = NFPROTO_BRIDGE, |
919 | .hooknum = NF_BR_FORWARD, | 898 | .hooknum = NF_BR_FORWARD, |
diff --git a/net/core/dev.c b/net/core/dev.c index 8637b2b71f3d..7869ae3837ca 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1304,6 +1304,7 @@ void netdev_notify_peers(struct net_device *dev) | |||
1304 | { | 1304 | { |
1305 | rtnl_lock(); | 1305 | rtnl_lock(); |
1306 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, dev); | 1306 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, dev); |
1307 | call_netdevice_notifiers(NETDEV_RESEND_IGMP, dev); | ||
1307 | rtnl_unlock(); | 1308 | rtnl_unlock(); |
1308 | } | 1309 | } |
1309 | EXPORT_SYMBOL(netdev_notify_peers); | 1310 | EXPORT_SYMBOL(netdev_notify_peers); |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 3945821e9c1f..65ea0ff4017c 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -953,7 +953,7 @@ net_rx_queue_update_kobjects(struct net_device *dev, int old_num, int new_num) | |||
953 | while (--i >= new_num) { | 953 | while (--i >= new_num) { |
954 | struct kobject *kobj = &dev->_rx[i].kobj; | 954 | struct kobject *kobj = &dev->_rx[i].kobj; |
955 | 955 | ||
956 | if (!list_empty(&dev_net(dev)->exit_list)) | 956 | if (!atomic_read(&dev_net(dev)->count)) |
957 | kobj->uevent_suppress = 1; | 957 | kobj->uevent_suppress = 1; |
958 | if (dev->sysfs_rx_queue_group) | 958 | if (dev->sysfs_rx_queue_group) |
959 | sysfs_remove_group(kobj, dev->sysfs_rx_queue_group); | 959 | sysfs_remove_group(kobj, dev->sysfs_rx_queue_group); |
@@ -1371,7 +1371,7 @@ netdev_queue_update_kobjects(struct net_device *dev, int old_num, int new_num) | |||
1371 | while (--i >= new_num) { | 1371 | while (--i >= new_num) { |
1372 | struct netdev_queue *queue = dev->_tx + i; | 1372 | struct netdev_queue *queue = dev->_tx + i; |
1373 | 1373 | ||
1374 | if (!list_empty(&dev_net(dev)->exit_list)) | 1374 | if (!atomic_read(&dev_net(dev)->count)) |
1375 | queue->kobj.uevent_suppress = 1; | 1375 | queue->kobj.uevent_suppress = 1; |
1376 | #ifdef CONFIG_BQL | 1376 | #ifdef CONFIG_BQL |
1377 | sysfs_remove_group(&queue->kobj, &dql_group); | 1377 | sysfs_remove_group(&queue->kobj, &dql_group); |
@@ -1558,7 +1558,7 @@ void netdev_unregister_kobject(struct net_device *ndev) | |||
1558 | { | 1558 | { |
1559 | struct device *dev = &(ndev->dev); | 1559 | struct device *dev = &(ndev->dev); |
1560 | 1560 | ||
1561 | if (!list_empty(&dev_net(ndev)->exit_list)) | 1561 | if (!atomic_read(&dev_net(ndev)->count)) |
1562 | dev_set_uevent_suppress(dev, 1); | 1562 | dev_set_uevent_suppress(dev, 1); |
1563 | 1563 | ||
1564 | kobject_get(&dev->kobj); | 1564 | kobject_get(&dev->kobj); |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index f3557958e9bf..cd4ba8c6b609 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -3828,13 +3828,14 @@ void skb_complete_tx_timestamp(struct sk_buff *skb, | |||
3828 | if (!skb_may_tx_timestamp(sk, false)) | 3828 | if (!skb_may_tx_timestamp(sk, false)) |
3829 | return; | 3829 | return; |
3830 | 3830 | ||
3831 | /* take a reference to prevent skb_orphan() from freeing the socket */ | 3831 | /* Take a reference to prevent skb_orphan() from freeing the socket, |
3832 | sock_hold(sk); | 3832 | * but only if the socket refcount is not zero. |
3833 | 3833 | */ | |
3834 | *skb_hwtstamps(skb) = *hwtstamps; | 3834 | if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) { |
3835 | __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND); | 3835 | *skb_hwtstamps(skb) = *hwtstamps; |
3836 | 3836 | __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND); | |
3837 | sock_put(sk); | 3837 | sock_put(sk); |
3838 | } | ||
3838 | } | 3839 | } |
3839 | EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp); | 3840 | EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp); |
3840 | 3841 | ||
@@ -3893,7 +3894,7 @@ void skb_complete_wifi_ack(struct sk_buff *skb, bool acked) | |||
3893 | { | 3894 | { |
3894 | struct sock *sk = skb->sk; | 3895 | struct sock *sk = skb->sk; |
3895 | struct sock_exterr_skb *serr; | 3896 | struct sock_exterr_skb *serr; |
3896 | int err; | 3897 | int err = 1; |
3897 | 3898 | ||
3898 | skb->wifi_acked_valid = 1; | 3899 | skb->wifi_acked_valid = 1; |
3899 | skb->wifi_acked = acked; | 3900 | skb->wifi_acked = acked; |
@@ -3903,14 +3904,15 @@ void skb_complete_wifi_ack(struct sk_buff *skb, bool acked) | |||
3903 | serr->ee.ee_errno = ENOMSG; | 3904 | serr->ee.ee_errno = ENOMSG; |
3904 | serr->ee.ee_origin = SO_EE_ORIGIN_TXSTATUS; | 3905 | serr->ee.ee_origin = SO_EE_ORIGIN_TXSTATUS; |
3905 | 3906 | ||
3906 | /* take a reference to prevent skb_orphan() from freeing the socket */ | 3907 | /* Take a reference to prevent skb_orphan() from freeing the socket, |
3907 | sock_hold(sk); | 3908 | * but only if the socket refcount is not zero. |
3908 | 3909 | */ | |
3909 | err = sock_queue_err_skb(sk, skb); | 3910 | if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) { |
3911 | err = sock_queue_err_skb(sk, skb); | ||
3912 | sock_put(sk); | ||
3913 | } | ||
3910 | if (err) | 3914 | if (err) |
3911 | kfree_skb(skb); | 3915 | kfree_skb(skb); |
3912 | |||
3913 | sock_put(sk); | ||
3914 | } | 3916 | } |
3915 | EXPORT_SYMBOL_GPL(skb_complete_wifi_ack); | 3917 | EXPORT_SYMBOL_GPL(skb_complete_wifi_ack); |
3916 | 3918 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index f6fd79f33097..a96d5f7a5734 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -197,66 +197,55 @@ EXPORT_SYMBOL(sk_net_capable); | |||
197 | 197 | ||
198 | /* | 198 | /* |
199 | * Each address family might have different locking rules, so we have | 199 | * Each address family might have different locking rules, so we have |
200 | * one slock key per address family: | 200 | * one slock key per address family and separate keys for internal and |
201 | * userspace sockets. | ||
201 | */ | 202 | */ |
202 | static struct lock_class_key af_family_keys[AF_MAX]; | 203 | static struct lock_class_key af_family_keys[AF_MAX]; |
204 | static struct lock_class_key af_family_kern_keys[AF_MAX]; | ||
203 | static struct lock_class_key af_family_slock_keys[AF_MAX]; | 205 | static struct lock_class_key af_family_slock_keys[AF_MAX]; |
206 | static struct lock_class_key af_family_kern_slock_keys[AF_MAX]; | ||
204 | 207 | ||
205 | /* | 208 | /* |
206 | * Make lock validator output more readable. (we pre-construct these | 209 | * Make lock validator output more readable. (we pre-construct these |
207 | * strings build-time, so that runtime initialization of socket | 210 | * strings build-time, so that runtime initialization of socket |
208 | * locks is fast): | 211 | * locks is fast): |
209 | */ | 212 | */ |
213 | |||
214 | #define _sock_locks(x) \ | ||
215 | x "AF_UNSPEC", x "AF_UNIX" , x "AF_INET" , \ | ||
216 | x "AF_AX25" , x "AF_IPX" , x "AF_APPLETALK", \ | ||
217 | x "AF_NETROM", x "AF_BRIDGE" , x "AF_ATMPVC" , \ | ||
218 | x "AF_X25" , x "AF_INET6" , x "AF_ROSE" , \ | ||
219 | x "AF_DECnet", x "AF_NETBEUI" , x "AF_SECURITY" , \ | ||
220 | x "AF_KEY" , x "AF_NETLINK" , x "AF_PACKET" , \ | ||
221 | x "AF_ASH" , x "AF_ECONET" , x "AF_ATMSVC" , \ | ||
222 | x "AF_RDS" , x "AF_SNA" , x "AF_IRDA" , \ | ||
223 | x "AF_PPPOX" , x "AF_WANPIPE" , x "AF_LLC" , \ | ||
224 | x "27" , x "28" , x "AF_CAN" , \ | ||
225 | x "AF_TIPC" , x "AF_BLUETOOTH", x "IUCV" , \ | ||
226 | x "AF_RXRPC" , x "AF_ISDN" , x "AF_PHONET" , \ | ||
227 | x "AF_IEEE802154", x "AF_CAIF" , x "AF_ALG" , \ | ||
228 | x "AF_NFC" , x "AF_VSOCK" , x "AF_KCM" , \ | ||
229 | x "AF_QIPCRTR", x "AF_SMC" , x "AF_MAX" | ||
230 | |||
210 | static const char *const af_family_key_strings[AF_MAX+1] = { | 231 | static const char *const af_family_key_strings[AF_MAX+1] = { |
211 | "sk_lock-AF_UNSPEC", "sk_lock-AF_UNIX" , "sk_lock-AF_INET" , | 232 | _sock_locks("sk_lock-") |
212 | "sk_lock-AF_AX25" , "sk_lock-AF_IPX" , "sk_lock-AF_APPLETALK", | ||
213 | "sk_lock-AF_NETROM", "sk_lock-AF_BRIDGE" , "sk_lock-AF_ATMPVC" , | ||
214 | "sk_lock-AF_X25" , "sk_lock-AF_INET6" , "sk_lock-AF_ROSE" , | ||
215 | "sk_lock-AF_DECnet", "sk_lock-AF_NETBEUI" , "sk_lock-AF_SECURITY" , | ||
216 | "sk_lock-AF_KEY" , "sk_lock-AF_NETLINK" , "sk_lock-AF_PACKET" , | ||
217 | "sk_lock-AF_ASH" , "sk_lock-AF_ECONET" , "sk_lock-AF_ATMSVC" , | ||
218 | "sk_lock-AF_RDS" , "sk_lock-AF_SNA" , "sk_lock-AF_IRDA" , | ||
219 | "sk_lock-AF_PPPOX" , "sk_lock-AF_WANPIPE" , "sk_lock-AF_LLC" , | ||
220 | "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , | ||
221 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , | ||
222 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , | ||
223 | "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , | ||
224 | "sk_lock-AF_NFC" , "sk_lock-AF_VSOCK" , "sk_lock-AF_KCM" , | ||
225 | "sk_lock-AF_QIPCRTR", "sk_lock-AF_SMC" , "sk_lock-AF_MAX" | ||
226 | }; | 233 | }; |
227 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { | 234 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { |
228 | "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , | 235 | _sock_locks("slock-") |
229 | "slock-AF_AX25" , "slock-AF_IPX" , "slock-AF_APPLETALK", | ||
230 | "slock-AF_NETROM", "slock-AF_BRIDGE" , "slock-AF_ATMPVC" , | ||
231 | "slock-AF_X25" , "slock-AF_INET6" , "slock-AF_ROSE" , | ||
232 | "slock-AF_DECnet", "slock-AF_NETBEUI" , "slock-AF_SECURITY" , | ||
233 | "slock-AF_KEY" , "slock-AF_NETLINK" , "slock-AF_PACKET" , | ||
234 | "slock-AF_ASH" , "slock-AF_ECONET" , "slock-AF_ATMSVC" , | ||
235 | "slock-AF_RDS" , "slock-AF_SNA" , "slock-AF_IRDA" , | ||
236 | "slock-AF_PPPOX" , "slock-AF_WANPIPE" , "slock-AF_LLC" , | ||
237 | "slock-27" , "slock-28" , "slock-AF_CAN" , | ||
238 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , | ||
239 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , | ||
240 | "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , | ||
241 | "slock-AF_NFC" , "slock-AF_VSOCK" ,"slock-AF_KCM" , | ||
242 | "slock-AF_QIPCRTR", "slock-AF_SMC" , "slock-AF_MAX" | ||
243 | }; | 236 | }; |
244 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { | 237 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { |
245 | "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , | 238 | _sock_locks("clock-") |
246 | "clock-AF_AX25" , "clock-AF_IPX" , "clock-AF_APPLETALK", | 239 | }; |
247 | "clock-AF_NETROM", "clock-AF_BRIDGE" , "clock-AF_ATMPVC" , | 240 | |
248 | "clock-AF_X25" , "clock-AF_INET6" , "clock-AF_ROSE" , | 241 | static const char *const af_family_kern_key_strings[AF_MAX+1] = { |
249 | "clock-AF_DECnet", "clock-AF_NETBEUI" , "clock-AF_SECURITY" , | 242 | _sock_locks("k-sk_lock-") |
250 | "clock-AF_KEY" , "clock-AF_NETLINK" , "clock-AF_PACKET" , | 243 | }; |
251 | "clock-AF_ASH" , "clock-AF_ECONET" , "clock-AF_ATMSVC" , | 244 | static const char *const af_family_kern_slock_key_strings[AF_MAX+1] = { |
252 | "clock-AF_RDS" , "clock-AF_SNA" , "clock-AF_IRDA" , | 245 | _sock_locks("k-slock-") |
253 | "clock-AF_PPPOX" , "clock-AF_WANPIPE" , "clock-AF_LLC" , | 246 | }; |
254 | "clock-27" , "clock-28" , "clock-AF_CAN" , | 247 | static const char *const af_family_kern_clock_key_strings[AF_MAX+1] = { |
255 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , | 248 | _sock_locks("k-clock-") |
256 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , | ||
257 | "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , | ||
258 | "clock-AF_NFC" , "clock-AF_VSOCK" , "clock-AF_KCM" , | ||
259 | "clock-AF_QIPCRTR", "clock-AF_SMC" , "clock-AF_MAX" | ||
260 | }; | 249 | }; |
261 | 250 | ||
262 | /* | 251 | /* |
@@ -264,6 +253,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = { | |||
264 | * so split the lock classes by using a per-AF key: | 253 | * so split the lock classes by using a per-AF key: |
265 | */ | 254 | */ |
266 | static struct lock_class_key af_callback_keys[AF_MAX]; | 255 | static struct lock_class_key af_callback_keys[AF_MAX]; |
256 | static struct lock_class_key af_kern_callback_keys[AF_MAX]; | ||
267 | 257 | ||
268 | /* Take into consideration the size of the struct sk_buff overhead in the | 258 | /* Take into consideration the size of the struct sk_buff overhead in the |
269 | * determination of these values, since that is non-constant across | 259 | * determination of these values, since that is non-constant across |
@@ -1293,7 +1283,16 @@ lenout: | |||
1293 | */ | 1283 | */ |
1294 | static inline void sock_lock_init(struct sock *sk) | 1284 | static inline void sock_lock_init(struct sock *sk) |
1295 | { | 1285 | { |
1296 | sock_lock_init_class_and_name(sk, | 1286 | if (sk->sk_kern_sock) |
1287 | sock_lock_init_class_and_name( | ||
1288 | sk, | ||
1289 | af_family_kern_slock_key_strings[sk->sk_family], | ||
1290 | af_family_kern_slock_keys + sk->sk_family, | ||
1291 | af_family_kern_key_strings[sk->sk_family], | ||
1292 | af_family_kern_keys + sk->sk_family); | ||
1293 | else | ||
1294 | sock_lock_init_class_and_name( | ||
1295 | sk, | ||
1297 | af_family_slock_key_strings[sk->sk_family], | 1296 | af_family_slock_key_strings[sk->sk_family], |
1298 | af_family_slock_keys + sk->sk_family, | 1297 | af_family_slock_keys + sk->sk_family, |
1299 | af_family_key_strings[sk->sk_family], | 1298 | af_family_key_strings[sk->sk_family], |
@@ -1399,6 +1398,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, | |||
1399 | * why we need sk_prot_creator -acme | 1398 | * why we need sk_prot_creator -acme |
1400 | */ | 1399 | */ |
1401 | sk->sk_prot = sk->sk_prot_creator = prot; | 1400 | sk->sk_prot = sk->sk_prot_creator = prot; |
1401 | sk->sk_kern_sock = kern; | ||
1402 | sock_lock_init(sk); | 1402 | sock_lock_init(sk); |
1403 | sk->sk_net_refcnt = kern ? 0 : 1; | 1403 | sk->sk_net_refcnt = kern ? 0 : 1; |
1404 | if (likely(sk->sk_net_refcnt)) | 1404 | if (likely(sk->sk_net_refcnt)) |
@@ -2277,7 +2277,8 @@ int sock_no_socketpair(struct socket *sock1, struct socket *sock2) | |||
2277 | } | 2277 | } |
2278 | EXPORT_SYMBOL(sock_no_socketpair); | 2278 | EXPORT_SYMBOL(sock_no_socketpair); |
2279 | 2279 | ||
2280 | int sock_no_accept(struct socket *sock, struct socket *newsock, int flags) | 2280 | int sock_no_accept(struct socket *sock, struct socket *newsock, int flags, |
2281 | bool kern) | ||
2281 | { | 2282 | { |
2282 | return -EOPNOTSUPP; | 2283 | return -EOPNOTSUPP; |
2283 | } | 2284 | } |
@@ -2481,7 +2482,14 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
2481 | } | 2482 | } |
2482 | 2483 | ||
2483 | rwlock_init(&sk->sk_callback_lock); | 2484 | rwlock_init(&sk->sk_callback_lock); |
2484 | lockdep_set_class_and_name(&sk->sk_callback_lock, | 2485 | if (sk->sk_kern_sock) |
2486 | lockdep_set_class_and_name( | ||
2487 | &sk->sk_callback_lock, | ||
2488 | af_kern_callback_keys + sk->sk_family, | ||
2489 | af_family_kern_clock_key_strings[sk->sk_family]); | ||
2490 | else | ||
2491 | lockdep_set_class_and_name( | ||
2492 | &sk->sk_callback_lock, | ||
2485 | af_callback_keys + sk->sk_family, | 2493 | af_callback_keys + sk->sk_family, |
2486 | af_family_clock_key_strings[sk->sk_family]); | 2494 | af_family_clock_key_strings[sk->sk_family]); |
2487 | 2495 | ||
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index f053198e730c..5e3a7302f774 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c | |||
@@ -749,6 +749,7 @@ static void ccid2_hc_tx_exit(struct sock *sk) | |||
749 | for (i = 0; i < hc->tx_seqbufc; i++) | 749 | for (i = 0; i < hc->tx_seqbufc; i++) |
750 | kfree(hc->tx_seqbuf[i]); | 750 | kfree(hc->tx_seqbuf[i]); |
751 | hc->tx_seqbufc = 0; | 751 | hc->tx_seqbufc = 0; |
752 | dccp_ackvec_parsed_cleanup(&hc->tx_av_chunks); | ||
752 | } | 753 | } |
753 | 754 | ||
754 | static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) | 755 | static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) |
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 409d0cfd3447..b99168b0fabf 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -289,7 +289,8 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) | |||
289 | 289 | ||
290 | switch (type) { | 290 | switch (type) { |
291 | case ICMP_REDIRECT: | 291 | case ICMP_REDIRECT: |
292 | dccp_do_redirect(skb, sk); | 292 | if (!sock_owned_by_user(sk)) |
293 | dccp_do_redirect(skb, sk); | ||
293 | goto out; | 294 | goto out; |
294 | case ICMP_SOURCE_QUENCH: | 295 | case ICMP_SOURCE_QUENCH: |
295 | /* Just silently ignore these. */ | 296 | /* Just silently ignore these. */ |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 233b57367758..d9b6a4e403e7 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -122,10 +122,12 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
122 | np = inet6_sk(sk); | 122 | np = inet6_sk(sk); |
123 | 123 | ||
124 | if (type == NDISC_REDIRECT) { | 124 | if (type == NDISC_REDIRECT) { |
125 | struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); | 125 | if (!sock_owned_by_user(sk)) { |
126 | struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); | ||
126 | 127 | ||
127 | if (dst) | 128 | if (dst) |
128 | dst->ops->redirect(dst, sk, skb); | 129 | dst->ops->redirect(dst, sk, skb); |
130 | } | ||
129 | goto out; | 131 | goto out; |
130 | } | 132 | } |
131 | 133 | ||
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index e267e6f4c9a5..abd07a443219 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c | |||
@@ -142,6 +142,13 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, | |||
142 | struct dccp_request_sock *dreq = dccp_rsk(req); | 142 | struct dccp_request_sock *dreq = dccp_rsk(req); |
143 | bool own_req; | 143 | bool own_req; |
144 | 144 | ||
145 | /* TCP/DCCP listeners became lockless. | ||
146 | * DCCP stores complex state in its request_sock, so we need | ||
147 | * a protection for them, now this code runs without being protected | ||
148 | * by the parent (listener) lock. | ||
149 | */ | ||
150 | spin_lock_bh(&dreq->dreq_lock); | ||
151 | |||
145 | /* Check for retransmitted REQUEST */ | 152 | /* Check for retransmitted REQUEST */ |
146 | if (dccp_hdr(skb)->dccph_type == DCCP_PKT_REQUEST) { | 153 | if (dccp_hdr(skb)->dccph_type == DCCP_PKT_REQUEST) { |
147 | 154 | ||
@@ -156,7 +163,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, | |||
156 | inet_rtx_syn_ack(sk, req); | 163 | inet_rtx_syn_ack(sk, req); |
157 | } | 164 | } |
158 | /* Network Duplicate, discard packet */ | 165 | /* Network Duplicate, discard packet */ |
159 | return NULL; | 166 | goto out; |
160 | } | 167 | } |
161 | 168 | ||
162 | DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; | 169 | DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; |
@@ -182,20 +189,20 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, | |||
182 | 189 | ||
183 | child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL, | 190 | child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL, |
184 | req, &own_req); | 191 | req, &own_req); |
185 | if (!child) | 192 | if (child) { |
186 | goto listen_overflow; | 193 | child = inet_csk_complete_hashdance(sk, child, req, own_req); |
187 | 194 | goto out; | |
188 | return inet_csk_complete_hashdance(sk, child, req, own_req); | 195 | } |
189 | 196 | ||
190 | listen_overflow: | ||
191 | dccp_pr_debug("listen_overflow!\n"); | ||
192 | DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_TOO_BUSY; | 197 | DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_TOO_BUSY; |
193 | drop: | 198 | drop: |
194 | if (dccp_hdr(skb)->dccph_type != DCCP_PKT_RESET) | 199 | if (dccp_hdr(skb)->dccph_type != DCCP_PKT_RESET) |
195 | req->rsk_ops->send_reset(sk, skb); | 200 | req->rsk_ops->send_reset(sk, skb); |
196 | 201 | ||
197 | inet_csk_reqsk_queue_drop(sk, req); | 202 | inet_csk_reqsk_queue_drop(sk, req); |
198 | return NULL; | 203 | out: |
204 | spin_unlock_bh(&dreq->dreq_lock); | ||
205 | return child; | ||
199 | } | 206 | } |
200 | 207 | ||
201 | EXPORT_SYMBOL_GPL(dccp_check_req); | 208 | EXPORT_SYMBOL_GPL(dccp_check_req); |
@@ -246,6 +253,7 @@ int dccp_reqsk_init(struct request_sock *req, | |||
246 | { | 253 | { |
247 | struct dccp_request_sock *dreq = dccp_rsk(req); | 254 | struct dccp_request_sock *dreq = dccp_rsk(req); |
248 | 255 | ||
256 | spin_lock_init(&dreq->dreq_lock); | ||
249 | inet_rsk(req)->ir_rmt_port = dccp_hdr(skb)->dccph_sport; | 257 | inet_rsk(req)->ir_rmt_port = dccp_hdr(skb)->dccph_sport; |
250 | inet_rsk(req)->ir_num = ntohs(dccp_hdr(skb)->dccph_dport); | 258 | inet_rsk(req)->ir_num = ntohs(dccp_hdr(skb)->dccph_dport); |
251 | inet_rsk(req)->acked = 0; | 259 | inet_rsk(req)->acked = 0; |
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index e6e79eda9763..7de5b40a5d0d 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
@@ -1070,7 +1070,8 @@ static struct sk_buff *dn_wait_for_connect(struct sock *sk, long *timeo) | |||
1070 | return skb == NULL ? ERR_PTR(err) : skb; | 1070 | return skb == NULL ? ERR_PTR(err) : skb; |
1071 | } | 1071 | } |
1072 | 1072 | ||
1073 | static int dn_accept(struct socket *sock, struct socket *newsock, int flags) | 1073 | static int dn_accept(struct socket *sock, struct socket *newsock, int flags, |
1074 | bool kern) | ||
1074 | { | 1075 | { |
1075 | struct sock *sk = sock->sk, *newsk; | 1076 | struct sock *sk = sock->sk, *newsk; |
1076 | struct sk_buff *skb = NULL; | 1077 | struct sk_buff *skb = NULL; |
@@ -1099,7 +1100,7 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags) | |||
1099 | 1100 | ||
1100 | cb = DN_SKB_CB(skb); | 1101 | cb = DN_SKB_CB(skb); |
1101 | sk->sk_ack_backlog--; | 1102 | sk->sk_ack_backlog--; |
1102 | newsk = dn_alloc_sock(sock_net(sk), newsock, sk->sk_allocation, 0); | 1103 | newsk = dn_alloc_sock(sock_net(sk), newsock, sk->sk_allocation, kern); |
1103 | if (newsk == NULL) { | 1104 | if (newsk == NULL) { |
1104 | release_sock(sk); | 1105 | release_sock(sk); |
1105 | kfree_skb(skb); | 1106 | kfree_skb(skb); |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 602d40f43687..6b1fc6e4278e 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -689,11 +689,12 @@ EXPORT_SYMBOL(inet_stream_connect); | |||
689 | * Accept a pending connection. The TCP layer now gives BSD semantics. | 689 | * Accept a pending connection. The TCP layer now gives BSD semantics. |
690 | */ | 690 | */ |
691 | 691 | ||
692 | int inet_accept(struct socket *sock, struct socket *newsock, int flags) | 692 | int inet_accept(struct socket *sock, struct socket *newsock, int flags, |
693 | bool kern) | ||
693 | { | 694 | { |
694 | struct sock *sk1 = sock->sk; | 695 | struct sock *sk1 = sock->sk; |
695 | int err = -EINVAL; | 696 | int err = -EINVAL; |
696 | struct sock *sk2 = sk1->sk_prot->accept(sk1, flags, &err); | 697 | struct sock *sk2 = sk1->sk_prot->accept(sk1, flags, &err, kern); |
697 | 698 | ||
698 | if (!sk2) | 699 | if (!sk2) |
699 | goto do_err; | 700 | goto do_err; |
@@ -1487,8 +1488,10 @@ int inet_gro_complete(struct sk_buff *skb, int nhoff) | |||
1487 | int proto = iph->protocol; | 1488 | int proto = iph->protocol; |
1488 | int err = -ENOSYS; | 1489 | int err = -ENOSYS; |
1489 | 1490 | ||
1490 | if (skb->encapsulation) | 1491 | if (skb->encapsulation) { |
1492 | skb_set_inner_protocol(skb, cpu_to_be16(ETH_P_IP)); | ||
1491 | skb_set_inner_network_header(skb, nhoff); | 1493 | skb_set_inner_network_header(skb, nhoff); |
1494 | } | ||
1492 | 1495 | ||
1493 | csum_replace2(&iph->check, iph->tot_len, newlen); | 1496 | csum_replace2(&iph->check, iph->tot_len, newlen); |
1494 | iph->tot_len = newlen; | 1497 | iph->tot_len = newlen; |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index b4d5980ade3b..5e313c1ac94f 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -424,7 +424,7 @@ static int inet_csk_wait_for_connect(struct sock *sk, long timeo) | |||
424 | /* | 424 | /* |
425 | * This will accept the next outstanding connection. | 425 | * This will accept the next outstanding connection. |
426 | */ | 426 | */ |
427 | struct sock *inet_csk_accept(struct sock *sk, int flags, int *err) | 427 | struct sock *inet_csk_accept(struct sock *sk, int flags, int *err, bool kern) |
428 | { | 428 | { |
429 | struct inet_connection_sock *icsk = inet_csk(sk); | 429 | struct inet_connection_sock *icsk = inet_csk(sk); |
430 | struct request_sock_queue *queue = &icsk->icsk_accept_queue; | 430 | struct request_sock_queue *queue = &icsk->icsk_accept_queue; |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 737ce826d7ec..7a3fd25e8913 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -966,7 +966,7 @@ static int __ip_append_data(struct sock *sk, | |||
966 | cork->length += length; | 966 | cork->length += length; |
967 | if ((((length + fragheaderlen) > mtu) || (skb && skb_is_gso(skb))) && | 967 | if ((((length + fragheaderlen) > mtu) || (skb && skb_is_gso(skb))) && |
968 | (sk->sk_protocol == IPPROTO_UDP) && | 968 | (sk->sk_protocol == IPPROTO_UDP) && |
969 | (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len && | 969 | (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) && |
970 | (sk->sk_type == SOCK_DGRAM) && !sk->sk_no_check_tx) { | 970 | (sk->sk_type == SOCK_DGRAM) && !sk->sk_no_check_tx) { |
971 | err = ip_ufo_append_data(sk, queue, getfrag, from, length, | 971 | err = ip_ufo_append_data(sk, queue, getfrag, from, length, |
972 | hh_len, fragheaderlen, transhdrlen, | 972 | hh_len, fragheaderlen, transhdrlen, |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 9a89b8deafae..575e19dcc017 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -279,10 +279,13 @@ EXPORT_SYMBOL(tcp_v4_connect); | |||
279 | */ | 279 | */ |
280 | void tcp_v4_mtu_reduced(struct sock *sk) | 280 | void tcp_v4_mtu_reduced(struct sock *sk) |
281 | { | 281 | { |
282 | struct dst_entry *dst; | ||
283 | struct inet_sock *inet = inet_sk(sk); | 282 | struct inet_sock *inet = inet_sk(sk); |
284 | u32 mtu = tcp_sk(sk)->mtu_info; | 283 | struct dst_entry *dst; |
284 | u32 mtu; | ||
285 | 285 | ||
286 | if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) | ||
287 | return; | ||
288 | mtu = tcp_sk(sk)->mtu_info; | ||
286 | dst = inet_csk_update_pmtu(sk, mtu); | 289 | dst = inet_csk_update_pmtu(sk, mtu); |
287 | if (!dst) | 290 | if (!dst) |
288 | return; | 291 | return; |
@@ -428,7 +431,8 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
428 | 431 | ||
429 | switch (type) { | 432 | switch (type) { |
430 | case ICMP_REDIRECT: | 433 | case ICMP_REDIRECT: |
431 | do_redirect(icmp_skb, sk); | 434 | if (!sock_owned_by_user(sk)) |
435 | do_redirect(icmp_skb, sk); | ||
432 | goto out; | 436 | goto out; |
433 | case ICMP_SOURCE_QUENCH: | 437 | case ICMP_SOURCE_QUENCH: |
434 | /* Just silently ignore these. */ | 438 | /* Just silently ignore these. */ |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 40d893556e67..b2ab411c6d37 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -249,7 +249,8 @@ void tcp_delack_timer_handler(struct sock *sk) | |||
249 | 249 | ||
250 | sk_mem_reclaim_partial(sk); | 250 | sk_mem_reclaim_partial(sk); |
251 | 251 | ||
252 | if (sk->sk_state == TCP_CLOSE || !(icsk->icsk_ack.pending & ICSK_ACK_TIMER)) | 252 | if (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || |
253 | !(icsk->icsk_ack.pending & ICSK_ACK_TIMER)) | ||
253 | goto out; | 254 | goto out; |
254 | 255 | ||
255 | if (time_after(icsk->icsk_ack.timeout, jiffies)) { | 256 | if (time_after(icsk->icsk_ack.timeout, jiffies)) { |
@@ -552,7 +553,8 @@ void tcp_write_timer_handler(struct sock *sk) | |||
552 | struct inet_connection_sock *icsk = inet_csk(sk); | 553 | struct inet_connection_sock *icsk = inet_csk(sk); |
553 | int event; | 554 | int event; |
554 | 555 | ||
555 | if (sk->sk_state == TCP_CLOSE || !icsk->icsk_pending) | 556 | if (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || |
557 | !icsk->icsk_pending) | ||
556 | goto out; | 558 | goto out; |
557 | 559 | ||
558 | if (time_after(icsk->icsk_timeout, jiffies)) { | 560 | if (time_after(icsk->icsk_timeout, jiffies)) { |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 04db40620ea6..a9a9553ee63d 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -920,12 +920,12 @@ static int __init inet6_init(void) | |||
920 | err = register_pernet_subsys(&inet6_net_ops); | 920 | err = register_pernet_subsys(&inet6_net_ops); |
921 | if (err) | 921 | if (err) |
922 | goto register_pernet_fail; | 922 | goto register_pernet_fail; |
923 | err = icmpv6_init(); | ||
924 | if (err) | ||
925 | goto icmp_fail; | ||
926 | err = ip6_mr_init(); | 923 | err = ip6_mr_init(); |
927 | if (err) | 924 | if (err) |
928 | goto ipmr_fail; | 925 | goto ipmr_fail; |
926 | err = icmpv6_init(); | ||
927 | if (err) | ||
928 | goto icmp_fail; | ||
929 | err = ndisc_init(); | 929 | err = ndisc_init(); |
930 | if (err) | 930 | if (err) |
931 | goto ndisc_fail; | 931 | goto ndisc_fail; |
@@ -1061,10 +1061,10 @@ igmp_fail: | |||
1061 | ndisc_cleanup(); | 1061 | ndisc_cleanup(); |
1062 | ndisc_fail: | 1062 | ndisc_fail: |
1063 | ip6_mr_cleanup(); | 1063 | ip6_mr_cleanup(); |
1064 | ipmr_fail: | ||
1065 | icmpv6_cleanup(); | ||
1066 | icmp_fail: | 1064 | icmp_fail: |
1067 | unregister_pernet_subsys(&inet6_net_ops); | 1065 | unregister_pernet_subsys(&inet6_net_ops); |
1066 | ipmr_fail: | ||
1067 | icmpv6_cleanup(); | ||
1068 | register_pernet_fail: | 1068 | register_pernet_fail: |
1069 | sock_unregister(PF_INET6); | 1069 | sock_unregister(PF_INET6); |
1070 | rtnl_unregister_all(PF_INET6); | 1070 | rtnl_unregister_all(PF_INET6); |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index e4266746e4a2..d4bf2c68a545 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -923,6 +923,8 @@ add: | |||
923 | ins = &rt->dst.rt6_next; | 923 | ins = &rt->dst.rt6_next; |
924 | iter = *ins; | 924 | iter = *ins; |
925 | while (iter) { | 925 | while (iter) { |
926 | if (iter->rt6i_metric > rt->rt6i_metric) | ||
927 | break; | ||
926 | if (rt6_qualify_for_ecmp(iter)) { | 928 | if (rt6_qualify_for_ecmp(iter)) { |
927 | *ins = iter->dst.rt6_next; | 929 | *ins = iter->dst.rt6_next; |
928 | fib6_purge_rt(iter, fn, info->nl_net); | 930 | fib6_purge_rt(iter, fn, info->nl_net); |
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index 0838e6d01d2e..93e58a5e1837 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c | |||
@@ -294,8 +294,10 @@ static int ipv6_gro_complete(struct sk_buff *skb, int nhoff) | |||
294 | struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + nhoff); | 294 | struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + nhoff); |
295 | int err = -ENOSYS; | 295 | int err = -ENOSYS; |
296 | 296 | ||
297 | if (skb->encapsulation) | 297 | if (skb->encapsulation) { |
298 | skb_set_inner_protocol(skb, cpu_to_be16(ETH_P_IPV6)); | ||
298 | skb_set_inner_network_header(skb, nhoff); | 299 | skb_set_inner_network_header(skb, nhoff); |
300 | } | ||
299 | 301 | ||
300 | iph->payload_len = htons(skb->len - nhoff - sizeof(*iph)); | 302 | iph->payload_len = htons(skb->len - nhoff - sizeof(*iph)); |
301 | 303 | ||
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 528b3c1f3fde..58f6288e9ba5 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -768,13 +768,14 @@ slow_path: | |||
768 | * Fragment the datagram. | 768 | * Fragment the datagram. |
769 | */ | 769 | */ |
770 | 770 | ||
771 | *prevhdr = NEXTHDR_FRAGMENT; | ||
772 | troom = rt->dst.dev->needed_tailroom; | 771 | troom = rt->dst.dev->needed_tailroom; |
773 | 772 | ||
774 | /* | 773 | /* |
775 | * Keep copying data until we run out. | 774 | * Keep copying data until we run out. |
776 | */ | 775 | */ |
777 | while (left > 0) { | 776 | while (left > 0) { |
777 | u8 *fragnexthdr_offset; | ||
778 | |||
778 | len = left; | 779 | len = left; |
779 | /* IF: it doesn't fit, use 'mtu' - the data space left */ | 780 | /* IF: it doesn't fit, use 'mtu' - the data space left */ |
780 | if (len > mtu) | 781 | if (len > mtu) |
@@ -819,6 +820,10 @@ slow_path: | |||
819 | */ | 820 | */ |
820 | skb_copy_from_linear_data(skb, skb_network_header(frag), hlen); | 821 | skb_copy_from_linear_data(skb, skb_network_header(frag), hlen); |
821 | 822 | ||
823 | fragnexthdr_offset = skb_network_header(frag); | ||
824 | fragnexthdr_offset += prevhdr - skb_network_header(skb); | ||
825 | *fragnexthdr_offset = NEXTHDR_FRAGMENT; | ||
826 | |||
822 | /* | 827 | /* |
823 | * Build fragment header. | 828 | * Build fragment header. |
824 | */ | 829 | */ |
@@ -1385,7 +1390,7 @@ emsgsize: | |||
1385 | if ((((length + fragheaderlen) > mtu) || | 1390 | if ((((length + fragheaderlen) > mtu) || |
1386 | (skb && skb_is_gso(skb))) && | 1391 | (skb && skb_is_gso(skb))) && |
1387 | (sk->sk_protocol == IPPROTO_UDP) && | 1392 | (sk->sk_protocol == IPPROTO_UDP) && |
1388 | (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len && | 1393 | (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) && |
1389 | (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) { | 1394 | (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) { |
1390 | err = ip6_ufo_append_data(sk, queue, getfrag, from, length, | 1395 | err = ip6_ufo_append_data(sk, queue, getfrag, from, length, |
1391 | hh_len, fragheaderlen, exthdrlen, | 1396 | hh_len, fragheaderlen, exthdrlen, |
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 644ba59fbd9d..3d8a3b63b4fd 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
@@ -485,11 +485,15 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) | |||
485 | if (!skb->ignore_df && skb->len > mtu) { | 485 | if (!skb->ignore_df && skb->len > mtu) { |
486 | skb_dst(skb)->ops->update_pmtu(dst, NULL, skb, mtu); | 486 | skb_dst(skb)->ops->update_pmtu(dst, NULL, skb, mtu); |
487 | 487 | ||
488 | if (skb->protocol == htons(ETH_P_IPV6)) | 488 | if (skb->protocol == htons(ETH_P_IPV6)) { |
489 | if (mtu < IPV6_MIN_MTU) | ||
490 | mtu = IPV6_MIN_MTU; | ||
491 | |||
489 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 492 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
490 | else | 493 | } else { |
491 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, | 494 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, |
492 | htonl(mtu)); | 495 | htonl(mtu)); |
496 | } | ||
493 | 497 | ||
494 | return -EMSGSIZE; | 498 | return -EMSGSIZE; |
495 | } | 499 | } |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 229bfcc451ef..35c58b669ebd 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -3299,7 +3299,6 @@ static size_t rt6_nlmsg_size(struct rt6_info *rt) | |||
3299 | nexthop_len = nla_total_size(0) /* RTA_MULTIPATH */ | 3299 | nexthop_len = nla_total_size(0) /* RTA_MULTIPATH */ |
3300 | + NLA_ALIGN(sizeof(struct rtnexthop)) | 3300 | + NLA_ALIGN(sizeof(struct rtnexthop)) |
3301 | + nla_total_size(16) /* RTA_GATEWAY */ | 3301 | + nla_total_size(16) /* RTA_GATEWAY */ |
3302 | + nla_total_size(4) /* RTA_OIF */ | ||
3303 | + lwtunnel_get_encap_size(rt->dst.lwtstate); | 3302 | + lwtunnel_get_encap_size(rt->dst.lwtstate); |
3304 | 3303 | ||
3305 | nexthop_len *= rt->rt6i_nsiblings; | 3304 | nexthop_len *= rt->rt6i_nsiblings; |
@@ -3323,7 +3322,7 @@ static size_t rt6_nlmsg_size(struct rt6_info *rt) | |||
3323 | } | 3322 | } |
3324 | 3323 | ||
3325 | static int rt6_nexthop_info(struct sk_buff *skb, struct rt6_info *rt, | 3324 | static int rt6_nexthop_info(struct sk_buff *skb, struct rt6_info *rt, |
3326 | unsigned int *flags) | 3325 | unsigned int *flags, bool skip_oif) |
3327 | { | 3326 | { |
3328 | if (!netif_running(rt->dst.dev) || !netif_carrier_ok(rt->dst.dev)) { | 3327 | if (!netif_running(rt->dst.dev) || !netif_carrier_ok(rt->dst.dev)) { |
3329 | *flags |= RTNH_F_LINKDOWN; | 3328 | *flags |= RTNH_F_LINKDOWN; |
@@ -3336,7 +3335,8 @@ static int rt6_nexthop_info(struct sk_buff *skb, struct rt6_info *rt, | |||
3336 | goto nla_put_failure; | 3335 | goto nla_put_failure; |
3337 | } | 3336 | } |
3338 | 3337 | ||
3339 | if (rt->dst.dev && | 3338 | /* not needed for multipath encoding b/c it has a rtnexthop struct */ |
3339 | if (!skip_oif && rt->dst.dev && | ||
3340 | nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex)) | 3340 | nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex)) |
3341 | goto nla_put_failure; | 3341 | goto nla_put_failure; |
3342 | 3342 | ||
@@ -3350,6 +3350,7 @@ nla_put_failure: | |||
3350 | return -EMSGSIZE; | 3350 | return -EMSGSIZE; |
3351 | } | 3351 | } |
3352 | 3352 | ||
3353 | /* add multipath next hop */ | ||
3353 | static int rt6_add_nexthop(struct sk_buff *skb, struct rt6_info *rt) | 3354 | static int rt6_add_nexthop(struct sk_buff *skb, struct rt6_info *rt) |
3354 | { | 3355 | { |
3355 | struct rtnexthop *rtnh; | 3356 | struct rtnexthop *rtnh; |
@@ -3362,7 +3363,7 @@ static int rt6_add_nexthop(struct sk_buff *skb, struct rt6_info *rt) | |||
3362 | rtnh->rtnh_hops = 0; | 3363 | rtnh->rtnh_hops = 0; |
3363 | rtnh->rtnh_ifindex = rt->dst.dev ? rt->dst.dev->ifindex : 0; | 3364 | rtnh->rtnh_ifindex = rt->dst.dev ? rt->dst.dev->ifindex : 0; |
3364 | 3365 | ||
3365 | if (rt6_nexthop_info(skb, rt, &flags) < 0) | 3366 | if (rt6_nexthop_info(skb, rt, &flags, true) < 0) |
3366 | goto nla_put_failure; | 3367 | goto nla_put_failure; |
3367 | 3368 | ||
3368 | rtnh->rtnh_flags = flags; | 3369 | rtnh->rtnh_flags = flags; |
@@ -3515,7 +3516,7 @@ static int rt6_fill_node(struct net *net, | |||
3515 | 3516 | ||
3516 | nla_nest_end(skb, mp); | 3517 | nla_nest_end(skb, mp); |
3517 | } else { | 3518 | } else { |
3518 | if (rt6_nexthop_info(skb, rt, &rtm->rtm_flags) < 0) | 3519 | if (rt6_nexthop_info(skb, rt, &rtm->rtm_flags, false) < 0) |
3519 | goto nla_put_failure; | 3520 | goto nla_put_failure; |
3520 | } | 3521 | } |
3521 | 3522 | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 60a5295a7de6..49fa2e8c3fa9 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -391,10 +391,12 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
391 | np = inet6_sk(sk); | 391 | np = inet6_sk(sk); |
392 | 392 | ||
393 | if (type == NDISC_REDIRECT) { | 393 | if (type == NDISC_REDIRECT) { |
394 | struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); | 394 | if (!sock_owned_by_user(sk)) { |
395 | struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); | ||
395 | 396 | ||
396 | if (dst) | 397 | if (dst) |
397 | dst->ops->redirect(dst, sk, skb); | 398 | dst->ops->redirect(dst, sk, skb); |
399 | } | ||
398 | goto out; | 400 | goto out; |
399 | } | 401 | } |
400 | 402 | ||
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 81adc29a448d..8d77ad5cadaf 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -828,7 +828,8 @@ out: | |||
828 | * Wait for incoming connection | 828 | * Wait for incoming connection |
829 | * | 829 | * |
830 | */ | 830 | */ |
831 | static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | 831 | static int irda_accept(struct socket *sock, struct socket *newsock, int flags, |
832 | bool kern) | ||
832 | { | 833 | { |
833 | struct sock *sk = sock->sk; | 834 | struct sock *sk = sock->sk; |
834 | struct irda_sock *new, *self = irda_sk(sk); | 835 | struct irda_sock *new, *self = irda_sk(sk); |
@@ -836,7 +837,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) | |||
836 | struct sk_buff *skb = NULL; | 837 | struct sk_buff *skb = NULL; |
837 | int err; | 838 | int err; |
838 | 839 | ||
839 | err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0); | 840 | err = irda_create(sock_net(sk), newsock, sk->sk_protocol, kern); |
840 | if (err) | 841 | if (err) |
841 | return err; | 842 | return err; |
842 | 843 | ||
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 89bbde1081ce..84de7b6326dc 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
@@ -938,7 +938,7 @@ done: | |||
938 | 938 | ||
939 | /* Accept a pending connection */ | 939 | /* Accept a pending connection */ |
940 | static int iucv_sock_accept(struct socket *sock, struct socket *newsock, | 940 | static int iucv_sock_accept(struct socket *sock, struct socket *newsock, |
941 | int flags) | 941 | int flags, bool kern) |
942 | { | 942 | { |
943 | DECLARE_WAITQUEUE(wait, current); | 943 | DECLARE_WAITQUEUE(wait, current); |
944 | struct sock *sk = sock->sk, *nsk; | 944 | struct sock *sk = sock->sk, *nsk; |
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 06186d608a27..cb4fff785cbf 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
@@ -641,11 +641,13 @@ static void llc_cmsg_rcv(struct msghdr *msg, struct sk_buff *skb) | |||
641 | * @sock: Socket which connections arrive on. | 641 | * @sock: Socket which connections arrive on. |
642 | * @newsock: Socket to move incoming connection to. | 642 | * @newsock: Socket to move incoming connection to. |
643 | * @flags: User specified operational flags. | 643 | * @flags: User specified operational flags. |
644 | * @kern: If the socket is kernel internal | ||
644 | * | 645 | * |
645 | * Accept a new incoming connection. | 646 | * Accept a new incoming connection. |
646 | * Returns 0 upon success, negative otherwise. | 647 | * Returns 0 upon success, negative otherwise. |
647 | */ | 648 | */ |
648 | static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags) | 649 | static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags, |
650 | bool kern) | ||
649 | { | 651 | { |
650 | struct sock *sk = sock->sk, *newsk; | 652 | struct sock *sk = sock->sk, *newsk; |
651 | struct llc_sock *llc, *newllc; | 653 | struct llc_sock *llc, *newllc; |
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 3818686182b2..33211f9a2656 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c | |||
@@ -1288,7 +1288,8 @@ static void mpls_ifdown(struct net_device *dev, int event) | |||
1288 | /* fall through */ | 1288 | /* fall through */ |
1289 | case NETDEV_CHANGE: | 1289 | case NETDEV_CHANGE: |
1290 | nh->nh_flags |= RTNH_F_LINKDOWN; | 1290 | nh->nh_flags |= RTNH_F_LINKDOWN; |
1291 | ACCESS_ONCE(rt->rt_nhn_alive) = rt->rt_nhn_alive - 1; | 1291 | if (event != NETDEV_UNREGISTER) |
1292 | ACCESS_ONCE(rt->rt_nhn_alive) = rt->rt_nhn_alive - 1; | ||
1292 | break; | 1293 | break; |
1293 | } | 1294 | } |
1294 | if (event == NETDEV_UNREGISTER) | 1295 | if (event == NETDEV_UNREGISTER) |
@@ -2028,6 +2029,7 @@ static void mpls_net_exit(struct net *net) | |||
2028 | for (index = 0; index < platform_labels; index++) { | 2029 | for (index = 0; index < platform_labels; index++) { |
2029 | struct mpls_route *rt = rtnl_dereference(platform_label[index]); | 2030 | struct mpls_route *rt = rtnl_dereference(platform_label[index]); |
2030 | RCU_INIT_POINTER(platform_label[index], NULL); | 2031 | RCU_INIT_POINTER(platform_label[index], NULL); |
2032 | mpls_notify_route(net, index, rt, NULL, NULL); | ||
2031 | mpls_rt_free(rt); | 2033 | mpls_rt_free(rt); |
2032 | } | 2034 | } |
2033 | rtnl_unlock(); | 2035 | rtnl_unlock(); |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 4bbf4526b885..ebf16f7f9089 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -765,7 +765,8 @@ out_release: | |||
765 | return err; | 765 | return err; |
766 | } | 766 | } |
767 | 767 | ||
768 | static int nr_accept(struct socket *sock, struct socket *newsock, int flags) | 768 | static int nr_accept(struct socket *sock, struct socket *newsock, int flags, |
769 | bool kern) | ||
769 | { | 770 | { |
770 | struct sk_buff *skb; | 771 | struct sk_buff *skb; |
771 | struct sock *newsk; | 772 | struct sock *newsk; |
diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c index 879885b31cce..2ffb18e73df6 100644 --- a/net/nfc/llcp_sock.c +++ b/net/nfc/llcp_sock.c | |||
@@ -441,7 +441,7 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent, | |||
441 | } | 441 | } |
442 | 442 | ||
443 | static int llcp_sock_accept(struct socket *sock, struct socket *newsock, | 443 | static int llcp_sock_accept(struct socket *sock, struct socket *newsock, |
444 | int flags) | 444 | int flags, bool kern) |
445 | { | 445 | { |
446 | DECLARE_WAITQUEUE(wait, current); | 446 | DECLARE_WAITQUEUE(wait, current); |
447 | struct sock *sk = sock->sk, *new_sk; | 447 | struct sock *sk = sock->sk, *new_sk; |
diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 222bedcd9575..e81537991ddf 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c | |||
@@ -772,7 +772,8 @@ static void pep_sock_close(struct sock *sk, long timeout) | |||
772 | sock_put(sk); | 772 | sock_put(sk); |
773 | } | 773 | } |
774 | 774 | ||
775 | static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp) | 775 | static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp, |
776 | bool kern) | ||
776 | { | 777 | { |
777 | struct pep_sock *pn = pep_sk(sk), *newpn; | 778 | struct pep_sock *pn = pep_sk(sk), *newpn; |
778 | struct sock *newsk = NULL; | 779 | struct sock *newsk = NULL; |
@@ -846,7 +847,8 @@ static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp) | |||
846 | } | 847 | } |
847 | 848 | ||
848 | /* Create a new to-be-accepted sock */ | 849 | /* Create a new to-be-accepted sock */ |
849 | newsk = sk_alloc(sock_net(sk), PF_PHONET, GFP_KERNEL, sk->sk_prot, 0); | 850 | newsk = sk_alloc(sock_net(sk), PF_PHONET, GFP_KERNEL, sk->sk_prot, |
851 | kern); | ||
850 | if (!newsk) { | 852 | if (!newsk) { |
851 | pep_reject_conn(sk, skb, PN_PIPE_ERR_OVERLOAD, GFP_KERNEL); | 853 | pep_reject_conn(sk, skb, PN_PIPE_ERR_OVERLOAD, GFP_KERNEL); |
852 | err = -ENOBUFS; | 854 | err = -ENOBUFS; |
diff --git a/net/phonet/socket.c b/net/phonet/socket.c index a6c8da3ee893..64634e3ec2fc 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c | |||
@@ -305,7 +305,7 @@ out: | |||
305 | } | 305 | } |
306 | 306 | ||
307 | static int pn_socket_accept(struct socket *sock, struct socket *newsock, | 307 | static int pn_socket_accept(struct socket *sock, struct socket *newsock, |
308 | int flags) | 308 | int flags, bool kern) |
309 | { | 309 | { |
310 | struct sock *sk = sock->sk; | 310 | struct sock *sk = sock->sk; |
311 | struct sock *newsk; | 311 | struct sock *newsk; |
@@ -314,7 +314,7 @@ static int pn_socket_accept(struct socket *sock, struct socket *newsock, | |||
314 | if (unlikely(sk->sk_state != TCP_LISTEN)) | 314 | if (unlikely(sk->sk_state != TCP_LISTEN)) |
315 | return -EINVAL; | 315 | return -EINVAL; |
316 | 316 | ||
317 | newsk = sk->sk_prot->accept(sk, flags, &err); | 317 | newsk = sk->sk_prot->accept(sk, flags, &err, kern); |
318 | if (!newsk) | 318 | if (!newsk) |
319 | return err; | 319 | return err; |
320 | 320 | ||
diff --git a/net/rds/connection.c b/net/rds/connection.c index 0e04dcceb1d4..1fa75ab7b733 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c | |||
@@ -429,6 +429,7 @@ void rds_conn_destroy(struct rds_connection *conn) | |||
429 | */ | 429 | */ |
430 | rds_cong_remove_conn(conn); | 430 | rds_cong_remove_conn(conn); |
431 | 431 | ||
432 | put_net(conn->c_net); | ||
432 | kmem_cache_free(rds_conn_slab, conn); | 433 | kmem_cache_free(rds_conn_slab, conn); |
433 | 434 | ||
434 | spin_lock_irqsave(&rds_conn_lock, flags); | 435 | spin_lock_irqsave(&rds_conn_lock, flags); |
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index ce3775abc6e7..1c38d2c7caa8 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c | |||
@@ -442,7 +442,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
442 | ic->i_send_cq = NULL; | 442 | ic->i_send_cq = NULL; |
443 | ibdev_put_vector(rds_ibdev, ic->i_scq_vector); | 443 | ibdev_put_vector(rds_ibdev, ic->i_scq_vector); |
444 | rdsdebug("ib_create_cq send failed: %d\n", ret); | 444 | rdsdebug("ib_create_cq send failed: %d\n", ret); |
445 | goto out; | 445 | goto rds_ibdev_out; |
446 | } | 446 | } |
447 | 447 | ||
448 | ic->i_rcq_vector = ibdev_get_unused_vector(rds_ibdev); | 448 | ic->i_rcq_vector = ibdev_get_unused_vector(rds_ibdev); |
@@ -456,19 +456,19 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
456 | ic->i_recv_cq = NULL; | 456 | ic->i_recv_cq = NULL; |
457 | ibdev_put_vector(rds_ibdev, ic->i_rcq_vector); | 457 | ibdev_put_vector(rds_ibdev, ic->i_rcq_vector); |
458 | rdsdebug("ib_create_cq recv failed: %d\n", ret); | 458 | rdsdebug("ib_create_cq recv failed: %d\n", ret); |
459 | goto out; | 459 | goto send_cq_out; |
460 | } | 460 | } |
461 | 461 | ||
462 | ret = ib_req_notify_cq(ic->i_send_cq, IB_CQ_NEXT_COMP); | 462 | ret = ib_req_notify_cq(ic->i_send_cq, IB_CQ_NEXT_COMP); |
463 | if (ret) { | 463 | if (ret) { |
464 | rdsdebug("ib_req_notify_cq send failed: %d\n", ret); | 464 | rdsdebug("ib_req_notify_cq send failed: %d\n", ret); |
465 | goto out; | 465 | goto recv_cq_out; |
466 | } | 466 | } |
467 | 467 | ||
468 | ret = ib_req_notify_cq(ic->i_recv_cq, IB_CQ_SOLICITED); | 468 | ret = ib_req_notify_cq(ic->i_recv_cq, IB_CQ_SOLICITED); |
469 | if (ret) { | 469 | if (ret) { |
470 | rdsdebug("ib_req_notify_cq recv failed: %d\n", ret); | 470 | rdsdebug("ib_req_notify_cq recv failed: %d\n", ret); |
471 | goto out; | 471 | goto recv_cq_out; |
472 | } | 472 | } |
473 | 473 | ||
474 | /* XXX negotiate max send/recv with remote? */ | 474 | /* XXX negotiate max send/recv with remote? */ |
@@ -494,7 +494,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
494 | ret = rdma_create_qp(ic->i_cm_id, ic->i_pd, &attr); | 494 | ret = rdma_create_qp(ic->i_cm_id, ic->i_pd, &attr); |
495 | if (ret) { | 495 | if (ret) { |
496 | rdsdebug("rdma_create_qp failed: %d\n", ret); | 496 | rdsdebug("rdma_create_qp failed: %d\n", ret); |
497 | goto out; | 497 | goto recv_cq_out; |
498 | } | 498 | } |
499 | 499 | ||
500 | ic->i_send_hdrs = ib_dma_alloc_coherent(dev, | 500 | ic->i_send_hdrs = ib_dma_alloc_coherent(dev, |
@@ -504,7 +504,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
504 | if (!ic->i_send_hdrs) { | 504 | if (!ic->i_send_hdrs) { |
505 | ret = -ENOMEM; | 505 | ret = -ENOMEM; |
506 | rdsdebug("ib_dma_alloc_coherent send failed\n"); | 506 | rdsdebug("ib_dma_alloc_coherent send failed\n"); |
507 | goto out; | 507 | goto qp_out; |
508 | } | 508 | } |
509 | 509 | ||
510 | ic->i_recv_hdrs = ib_dma_alloc_coherent(dev, | 510 | ic->i_recv_hdrs = ib_dma_alloc_coherent(dev, |
@@ -514,7 +514,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
514 | if (!ic->i_recv_hdrs) { | 514 | if (!ic->i_recv_hdrs) { |
515 | ret = -ENOMEM; | 515 | ret = -ENOMEM; |
516 | rdsdebug("ib_dma_alloc_coherent recv failed\n"); | 516 | rdsdebug("ib_dma_alloc_coherent recv failed\n"); |
517 | goto out; | 517 | goto send_hdrs_dma_out; |
518 | } | 518 | } |
519 | 519 | ||
520 | ic->i_ack = ib_dma_alloc_coherent(dev, sizeof(struct rds_header), | 520 | ic->i_ack = ib_dma_alloc_coherent(dev, sizeof(struct rds_header), |
@@ -522,7 +522,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
522 | if (!ic->i_ack) { | 522 | if (!ic->i_ack) { |
523 | ret = -ENOMEM; | 523 | ret = -ENOMEM; |
524 | rdsdebug("ib_dma_alloc_coherent ack failed\n"); | 524 | rdsdebug("ib_dma_alloc_coherent ack failed\n"); |
525 | goto out; | 525 | goto recv_hdrs_dma_out; |
526 | } | 526 | } |
527 | 527 | ||
528 | ic->i_sends = vzalloc_node(ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work), | 528 | ic->i_sends = vzalloc_node(ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work), |
@@ -530,7 +530,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
530 | if (!ic->i_sends) { | 530 | if (!ic->i_sends) { |
531 | ret = -ENOMEM; | 531 | ret = -ENOMEM; |
532 | rdsdebug("send allocation failed\n"); | 532 | rdsdebug("send allocation failed\n"); |
533 | goto out; | 533 | goto ack_dma_out; |
534 | } | 534 | } |
535 | 535 | ||
536 | ic->i_recvs = vzalloc_node(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work), | 536 | ic->i_recvs = vzalloc_node(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work), |
@@ -538,7 +538,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
538 | if (!ic->i_recvs) { | 538 | if (!ic->i_recvs) { |
539 | ret = -ENOMEM; | 539 | ret = -ENOMEM; |
540 | rdsdebug("recv allocation failed\n"); | 540 | rdsdebug("recv allocation failed\n"); |
541 | goto out; | 541 | goto sends_out; |
542 | } | 542 | } |
543 | 543 | ||
544 | rds_ib_recv_init_ack(ic); | 544 | rds_ib_recv_init_ack(ic); |
@@ -546,8 +546,33 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
546 | rdsdebug("conn %p pd %p cq %p %p\n", conn, ic->i_pd, | 546 | rdsdebug("conn %p pd %p cq %p %p\n", conn, ic->i_pd, |
547 | ic->i_send_cq, ic->i_recv_cq); | 547 | ic->i_send_cq, ic->i_recv_cq); |
548 | 548 | ||
549 | out: | 549 | return ret; |
550 | |||
551 | sends_out: | ||
552 | vfree(ic->i_sends); | ||
553 | ack_dma_out: | ||
554 | ib_dma_free_coherent(dev, sizeof(struct rds_header), | ||
555 | ic->i_ack, ic->i_ack_dma); | ||
556 | recv_hdrs_dma_out: | ||
557 | ib_dma_free_coherent(dev, ic->i_recv_ring.w_nr * | ||
558 | sizeof(struct rds_header), | ||
559 | ic->i_recv_hdrs, ic->i_recv_hdrs_dma); | ||
560 | send_hdrs_dma_out: | ||
561 | ib_dma_free_coherent(dev, ic->i_send_ring.w_nr * | ||
562 | sizeof(struct rds_header), | ||
563 | ic->i_send_hdrs, ic->i_send_hdrs_dma); | ||
564 | qp_out: | ||
565 | rdma_destroy_qp(ic->i_cm_id); | ||
566 | recv_cq_out: | ||
567 | if (!ib_destroy_cq(ic->i_recv_cq)) | ||
568 | ic->i_recv_cq = NULL; | ||
569 | send_cq_out: | ||
570 | if (!ib_destroy_cq(ic->i_send_cq)) | ||
571 | ic->i_send_cq = NULL; | ||
572 | rds_ibdev_out: | ||
573 | rds_ib_remove_conn(rds_ibdev, conn); | ||
550 | rds_ib_dev_put(rds_ibdev); | 574 | rds_ib_dev_put(rds_ibdev); |
575 | |||
551 | return ret; | 576 | return ret; |
552 | } | 577 | } |
553 | 578 | ||
diff --git a/net/rds/rds.h b/net/rds/rds.h index 39518ef7af4d..82d38ccf5e8b 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h | |||
@@ -147,7 +147,7 @@ struct rds_connection { | |||
147 | 147 | ||
148 | /* Protocol version */ | 148 | /* Protocol version */ |
149 | unsigned int c_version; | 149 | unsigned int c_version; |
150 | possible_net_t c_net; | 150 | struct net *c_net; |
151 | 151 | ||
152 | struct list_head c_map_item; | 152 | struct list_head c_map_item; |
153 | unsigned long c_map_queued; | 153 | unsigned long c_map_queued; |
@@ -162,13 +162,13 @@ struct rds_connection { | |||
162 | static inline | 162 | static inline |
163 | struct net *rds_conn_net(struct rds_connection *conn) | 163 | struct net *rds_conn_net(struct rds_connection *conn) |
164 | { | 164 | { |
165 | return read_pnet(&conn->c_net); | 165 | return conn->c_net; |
166 | } | 166 | } |
167 | 167 | ||
168 | static inline | 168 | static inline |
169 | void rds_conn_net_set(struct rds_connection *conn, struct net *net) | 169 | void rds_conn_net_set(struct rds_connection *conn, struct net *net) |
170 | { | 170 | { |
171 | write_pnet(&conn->c_net, net); | 171 | conn->c_net = get_net(net); |
172 | } | 172 | } |
173 | 173 | ||
174 | #define RDS_FLAG_CONG_BITMAP 0x01 | 174 | #define RDS_FLAG_CONG_BITMAP 0x01 |
diff --git a/net/rds/tcp.c b/net/rds/tcp.c index a973d3b4dff0..225690076773 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c | |||
@@ -484,9 +484,10 @@ static void __net_exit rds_tcp_exit_net(struct net *net) | |||
484 | * we do need to clean up the listen socket here. | 484 | * we do need to clean up the listen socket here. |
485 | */ | 485 | */ |
486 | if (rtn->rds_tcp_listen_sock) { | 486 | if (rtn->rds_tcp_listen_sock) { |
487 | rds_tcp_listen_stop(rtn->rds_tcp_listen_sock); | 487 | struct socket *lsock = rtn->rds_tcp_listen_sock; |
488 | |||
488 | rtn->rds_tcp_listen_sock = NULL; | 489 | rtn->rds_tcp_listen_sock = NULL; |
489 | flush_work(&rtn->rds_tcp_accept_w); | 490 | rds_tcp_listen_stop(lsock, &rtn->rds_tcp_accept_w); |
490 | } | 491 | } |
491 | } | 492 | } |
492 | 493 | ||
@@ -523,13 +524,13 @@ static void rds_tcp_kill_sock(struct net *net) | |||
523 | struct rds_tcp_connection *tc, *_tc; | 524 | struct rds_tcp_connection *tc, *_tc; |
524 | LIST_HEAD(tmp_list); | 525 | LIST_HEAD(tmp_list); |
525 | struct rds_tcp_net *rtn = net_generic(net, rds_tcp_netid); | 526 | struct rds_tcp_net *rtn = net_generic(net, rds_tcp_netid); |
527 | struct socket *lsock = rtn->rds_tcp_listen_sock; | ||
526 | 528 | ||
527 | rds_tcp_listen_stop(rtn->rds_tcp_listen_sock); | ||
528 | rtn->rds_tcp_listen_sock = NULL; | 529 | rtn->rds_tcp_listen_sock = NULL; |
529 | flush_work(&rtn->rds_tcp_accept_w); | 530 | rds_tcp_listen_stop(lsock, &rtn->rds_tcp_accept_w); |
530 | spin_lock_irq(&rds_tcp_conn_lock); | 531 | spin_lock_irq(&rds_tcp_conn_lock); |
531 | list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) { | 532 | list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) { |
532 | struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net); | 533 | struct net *c_net = tc->t_cpath->cp_conn->c_net; |
533 | 534 | ||
534 | if (net != c_net || !tc->t_sock) | 535 | if (net != c_net || !tc->t_sock) |
535 | continue; | 536 | continue; |
@@ -546,8 +547,12 @@ static void rds_tcp_kill_sock(struct net *net) | |||
546 | void *rds_tcp_listen_sock_def_readable(struct net *net) | 547 | void *rds_tcp_listen_sock_def_readable(struct net *net) |
547 | { | 548 | { |
548 | struct rds_tcp_net *rtn = net_generic(net, rds_tcp_netid); | 549 | struct rds_tcp_net *rtn = net_generic(net, rds_tcp_netid); |
550 | struct socket *lsock = rtn->rds_tcp_listen_sock; | ||
551 | |||
552 | if (!lsock) | ||
553 | return NULL; | ||
549 | 554 | ||
550 | return rtn->rds_tcp_listen_sock->sk->sk_user_data; | 555 | return lsock->sk->sk_user_data; |
551 | } | 556 | } |
552 | 557 | ||
553 | static int rds_tcp_dev_event(struct notifier_block *this, | 558 | static int rds_tcp_dev_event(struct notifier_block *this, |
@@ -584,7 +589,7 @@ static void rds_tcp_sysctl_reset(struct net *net) | |||
584 | 589 | ||
585 | spin_lock_irq(&rds_tcp_conn_lock); | 590 | spin_lock_irq(&rds_tcp_conn_lock); |
586 | list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) { | 591 | list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) { |
587 | struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net); | 592 | struct net *c_net = tc->t_cpath->cp_conn->c_net; |
588 | 593 | ||
589 | if (net != c_net || !tc->t_sock) | 594 | if (net != c_net || !tc->t_sock) |
590 | continue; | 595 | continue; |
@@ -638,19 +643,19 @@ static int rds_tcp_init(void) | |||
638 | goto out; | 643 | goto out; |
639 | } | 644 | } |
640 | 645 | ||
641 | ret = register_netdevice_notifier(&rds_tcp_dev_notifier); | 646 | ret = rds_tcp_recv_init(); |
642 | if (ret) { | 647 | if (ret) |
643 | pr_warn("could not register rds_tcp_dev_notifier\n"); | ||
644 | goto out_slab; | 648 | goto out_slab; |
645 | } | ||
646 | 649 | ||
647 | ret = register_pernet_subsys(&rds_tcp_net_ops); | 650 | ret = register_pernet_subsys(&rds_tcp_net_ops); |
648 | if (ret) | 651 | if (ret) |
649 | goto out_notifier; | 652 | goto out_recv; |
650 | 653 | ||
651 | ret = rds_tcp_recv_init(); | 654 | ret = register_netdevice_notifier(&rds_tcp_dev_notifier); |
652 | if (ret) | 655 | if (ret) { |
656 | pr_warn("could not register rds_tcp_dev_notifier\n"); | ||
653 | goto out_pernet; | 657 | goto out_pernet; |
658 | } | ||
654 | 659 | ||
655 | rds_trans_register(&rds_tcp_transport); | 660 | rds_trans_register(&rds_tcp_transport); |
656 | 661 | ||
@@ -660,9 +665,8 @@ static int rds_tcp_init(void) | |||
660 | 665 | ||
661 | out_pernet: | 666 | out_pernet: |
662 | unregister_pernet_subsys(&rds_tcp_net_ops); | 667 | unregister_pernet_subsys(&rds_tcp_net_ops); |
663 | out_notifier: | 668 | out_recv: |
664 | if (unregister_netdevice_notifier(&rds_tcp_dev_notifier)) | 669 | rds_tcp_recv_exit(); |
665 | pr_warn("could not unregister rds_tcp_dev_notifier\n"); | ||
666 | out_slab: | 670 | out_slab: |
667 | kmem_cache_destroy(rds_tcp_conn_slab); | 671 | kmem_cache_destroy(rds_tcp_conn_slab); |
668 | out: | 672 | out: |
diff --git a/net/rds/tcp.h b/net/rds/tcp.h index 9a1cc8906576..56ea6620fcf9 100644 --- a/net/rds/tcp.h +++ b/net/rds/tcp.h | |||
@@ -66,7 +66,7 @@ void rds_tcp_state_change(struct sock *sk); | |||
66 | 66 | ||
67 | /* tcp_listen.c */ | 67 | /* tcp_listen.c */ |
68 | struct socket *rds_tcp_listen_init(struct net *); | 68 | struct socket *rds_tcp_listen_init(struct net *); |
69 | void rds_tcp_listen_stop(struct socket *); | 69 | void rds_tcp_listen_stop(struct socket *sock, struct work_struct *acceptor); |
70 | void rds_tcp_listen_data_ready(struct sock *sk); | 70 | void rds_tcp_listen_data_ready(struct sock *sk); |
71 | int rds_tcp_accept_one(struct socket *sock); | 71 | int rds_tcp_accept_one(struct socket *sock); |
72 | int rds_tcp_keepalive(struct socket *sock); | 72 | int rds_tcp_keepalive(struct socket *sock); |
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index 67d0929c7d3d..507678853e6c 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c | |||
@@ -133,7 +133,7 @@ int rds_tcp_accept_one(struct socket *sock) | |||
133 | 133 | ||
134 | new_sock->type = sock->type; | 134 | new_sock->type = sock->type; |
135 | new_sock->ops = sock->ops; | 135 | new_sock->ops = sock->ops; |
136 | ret = sock->ops->accept(sock, new_sock, O_NONBLOCK); | 136 | ret = sock->ops->accept(sock, new_sock, O_NONBLOCK, true); |
137 | if (ret < 0) | 137 | if (ret < 0) |
138 | goto out; | 138 | goto out; |
139 | 139 | ||
@@ -223,6 +223,9 @@ void rds_tcp_listen_data_ready(struct sock *sk) | |||
223 | * before it has been accepted and the accepter has set up their | 223 | * before it has been accepted and the accepter has set up their |
224 | * data_ready.. we only want to queue listen work for our listening | 224 | * data_ready.. we only want to queue listen work for our listening |
225 | * socket | 225 | * socket |
226 | * | ||
227 | * (*ready)() may be null if we are racing with netns delete, and | ||
228 | * the listen socket is being torn down. | ||
226 | */ | 229 | */ |
227 | if (sk->sk_state == TCP_LISTEN) | 230 | if (sk->sk_state == TCP_LISTEN) |
228 | rds_tcp_accept_work(sk); | 231 | rds_tcp_accept_work(sk); |
@@ -231,7 +234,8 @@ void rds_tcp_listen_data_ready(struct sock *sk) | |||
231 | 234 | ||
232 | out: | 235 | out: |
233 | read_unlock_bh(&sk->sk_callback_lock); | 236 | read_unlock_bh(&sk->sk_callback_lock); |
234 | ready(sk); | 237 | if (ready) |
238 | ready(sk); | ||
235 | } | 239 | } |
236 | 240 | ||
237 | struct socket *rds_tcp_listen_init(struct net *net) | 241 | struct socket *rds_tcp_listen_init(struct net *net) |
@@ -271,7 +275,7 @@ out: | |||
271 | return NULL; | 275 | return NULL; |
272 | } | 276 | } |
273 | 277 | ||
274 | void rds_tcp_listen_stop(struct socket *sock) | 278 | void rds_tcp_listen_stop(struct socket *sock, struct work_struct *acceptor) |
275 | { | 279 | { |
276 | struct sock *sk; | 280 | struct sock *sk; |
277 | 281 | ||
@@ -292,5 +296,6 @@ void rds_tcp_listen_stop(struct socket *sock) | |||
292 | 296 | ||
293 | /* wait for accepts to stop and close the socket */ | 297 | /* wait for accepts to stop and close the socket */ |
294 | flush_workqueue(rds_wq); | 298 | flush_workqueue(rds_wq); |
299 | flush_work(acceptor); | ||
295 | sock_release(sock); | 300 | sock_release(sock); |
296 | } | 301 | } |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index b8a1df2c9785..4a9729257023 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -871,7 +871,8 @@ out_release: | |||
871 | return err; | 871 | return err; |
872 | } | 872 | } |
873 | 873 | ||
874 | static int rose_accept(struct socket *sock, struct socket *newsock, int flags) | 874 | static int rose_accept(struct socket *sock, struct socket *newsock, int flags, |
875 | bool kern) | ||
875 | { | 876 | { |
876 | struct sk_buff *skb; | 877 | struct sk_buff *skb; |
877 | struct sock *newsk; | 878 | struct sock *newsk; |
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c index 9f4cfa25af7c..18b2ad8be8e2 100644 --- a/net/rxrpc/input.c +++ b/net/rxrpc/input.c | |||
@@ -420,6 +420,7 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb, | |||
420 | u16 skew) | 420 | u16 skew) |
421 | { | 421 | { |
422 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); | 422 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
423 | enum rxrpc_call_state state; | ||
423 | unsigned int offset = sizeof(struct rxrpc_wire_header); | 424 | unsigned int offset = sizeof(struct rxrpc_wire_header); |
424 | unsigned int ix; | 425 | unsigned int ix; |
425 | rxrpc_serial_t serial = sp->hdr.serial, ack_serial = 0; | 426 | rxrpc_serial_t serial = sp->hdr.serial, ack_serial = 0; |
@@ -434,14 +435,15 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb, | |||
434 | _proto("Rx DATA %%%u { #%u f=%02x }", | 435 | _proto("Rx DATA %%%u { #%u f=%02x }", |
435 | sp->hdr.serial, seq, sp->hdr.flags); | 436 | sp->hdr.serial, seq, sp->hdr.flags); |
436 | 437 | ||
437 | if (call->state >= RXRPC_CALL_COMPLETE) | 438 | state = READ_ONCE(call->state); |
439 | if (state >= RXRPC_CALL_COMPLETE) | ||
438 | return; | 440 | return; |
439 | 441 | ||
440 | /* Received data implicitly ACKs all of the request packets we sent | 442 | /* Received data implicitly ACKs all of the request packets we sent |
441 | * when we're acting as a client. | 443 | * when we're acting as a client. |
442 | */ | 444 | */ |
443 | if ((call->state == RXRPC_CALL_CLIENT_SEND_REQUEST || | 445 | if ((state == RXRPC_CALL_CLIENT_SEND_REQUEST || |
444 | call->state == RXRPC_CALL_CLIENT_AWAIT_REPLY) && | 446 | state == RXRPC_CALL_CLIENT_AWAIT_REPLY) && |
445 | !rxrpc_receiving_reply(call)) | 447 | !rxrpc_receiving_reply(call)) |
446 | return; | 448 | return; |
447 | 449 | ||
@@ -650,6 +652,7 @@ static void rxrpc_input_ackinfo(struct rxrpc_call *call, struct sk_buff *skb, | |||
650 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); | 652 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
651 | struct rxrpc_peer *peer; | 653 | struct rxrpc_peer *peer; |
652 | unsigned int mtu; | 654 | unsigned int mtu; |
655 | bool wake = false; | ||
653 | u32 rwind = ntohl(ackinfo->rwind); | 656 | u32 rwind = ntohl(ackinfo->rwind); |
654 | 657 | ||
655 | _proto("Rx ACK %%%u Info { rx=%u max=%u rwin=%u jm=%u }", | 658 | _proto("Rx ACK %%%u Info { rx=%u max=%u rwin=%u jm=%u }", |
@@ -657,9 +660,14 @@ static void rxrpc_input_ackinfo(struct rxrpc_call *call, struct sk_buff *skb, | |||
657 | ntohl(ackinfo->rxMTU), ntohl(ackinfo->maxMTU), | 660 | ntohl(ackinfo->rxMTU), ntohl(ackinfo->maxMTU), |
658 | rwind, ntohl(ackinfo->jumbo_max)); | 661 | rwind, ntohl(ackinfo->jumbo_max)); |
659 | 662 | ||
660 | if (rwind > RXRPC_RXTX_BUFF_SIZE - 1) | 663 | if (call->tx_winsize != rwind) { |
661 | rwind = RXRPC_RXTX_BUFF_SIZE - 1; | 664 | if (rwind > RXRPC_RXTX_BUFF_SIZE - 1) |
662 | call->tx_winsize = rwind; | 665 | rwind = RXRPC_RXTX_BUFF_SIZE - 1; |
666 | if (rwind > call->tx_winsize) | ||
667 | wake = true; | ||
668 | call->tx_winsize = rwind; | ||
669 | } | ||
670 | |||
663 | if (call->cong_ssthresh > rwind) | 671 | if (call->cong_ssthresh > rwind) |
664 | call->cong_ssthresh = rwind; | 672 | call->cong_ssthresh = rwind; |
665 | 673 | ||
@@ -673,6 +681,9 @@ static void rxrpc_input_ackinfo(struct rxrpc_call *call, struct sk_buff *skb, | |||
673 | spin_unlock_bh(&peer->lock); | 681 | spin_unlock_bh(&peer->lock); |
674 | _net("Net MTU %u (maxdata %u)", peer->mtu, peer->maxdata); | 682 | _net("Net MTU %u (maxdata %u)", peer->mtu, peer->maxdata); |
675 | } | 683 | } |
684 | |||
685 | if (wake) | ||
686 | wake_up(&call->waitq); | ||
676 | } | 687 | } |
677 | 688 | ||
678 | /* | 689 | /* |
@@ -799,7 +810,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb, | |||
799 | return rxrpc_proto_abort("AK0", call, 0); | 810 | return rxrpc_proto_abort("AK0", call, 0); |
800 | 811 | ||
801 | /* Ignore ACKs unless we are or have just been transmitting. */ | 812 | /* Ignore ACKs unless we are or have just been transmitting. */ |
802 | switch (call->state) { | 813 | switch (READ_ONCE(call->state)) { |
803 | case RXRPC_CALL_CLIENT_SEND_REQUEST: | 814 | case RXRPC_CALL_CLIENT_SEND_REQUEST: |
804 | case RXRPC_CALL_CLIENT_AWAIT_REPLY: | 815 | case RXRPC_CALL_CLIENT_AWAIT_REPLY: |
805 | case RXRPC_CALL_SERVER_SEND_REPLY: | 816 | case RXRPC_CALL_SERVER_SEND_REPLY: |
@@ -940,7 +951,7 @@ static void rxrpc_input_call_packet(struct rxrpc_call *call, | |||
940 | static void rxrpc_input_implicit_end_call(struct rxrpc_connection *conn, | 951 | static void rxrpc_input_implicit_end_call(struct rxrpc_connection *conn, |
941 | struct rxrpc_call *call) | 952 | struct rxrpc_call *call) |
942 | { | 953 | { |
943 | switch (call->state) { | 954 | switch (READ_ONCE(call->state)) { |
944 | case RXRPC_CALL_SERVER_AWAIT_ACK: | 955 | case RXRPC_CALL_SERVER_AWAIT_ACK: |
945 | rxrpc_call_completed(call); | 956 | rxrpc_call_completed(call); |
946 | break; | 957 | break; |
diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c index 6491ca46a03f..3e2f1a8e9c5b 100644 --- a/net/rxrpc/recvmsg.c +++ b/net/rxrpc/recvmsg.c | |||
@@ -527,7 +527,7 @@ try_again: | |||
527 | msg->msg_namelen = len; | 527 | msg->msg_namelen = len; |
528 | } | 528 | } |
529 | 529 | ||
530 | switch (call->state) { | 530 | switch (READ_ONCE(call->state)) { |
531 | case RXRPC_CALL_SERVER_ACCEPTING: | 531 | case RXRPC_CALL_SERVER_ACCEPTING: |
532 | ret = rxrpc_recvmsg_new_call(rx, call, msg, flags); | 532 | ret = rxrpc_recvmsg_new_call(rx, call, msg, flags); |
533 | break; | 533 | break; |
@@ -640,7 +640,7 @@ int rxrpc_kernel_recv_data(struct socket *sock, struct rxrpc_call *call, | |||
640 | 640 | ||
641 | mutex_lock(&call->user_mutex); | 641 | mutex_lock(&call->user_mutex); |
642 | 642 | ||
643 | switch (call->state) { | 643 | switch (READ_ONCE(call->state)) { |
644 | case RXRPC_CALL_CLIENT_RECV_REPLY: | 644 | case RXRPC_CALL_CLIENT_RECV_REPLY: |
645 | case RXRPC_CALL_SERVER_RECV_REQUEST: | 645 | case RXRPC_CALL_SERVER_RECV_REQUEST: |
646 | case RXRPC_CALL_SERVER_ACK_REQUEST: | 646 | case RXRPC_CALL_SERVER_ACK_REQUEST: |
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index bc2d3dcff9de..97ab214ca411 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c | |||
@@ -488,6 +488,7 @@ rxrpc_new_client_call_for_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, | |||
488 | int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) | 488 | int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) |
489 | __releases(&rx->sk.sk_lock.slock) | 489 | __releases(&rx->sk.sk_lock.slock) |
490 | { | 490 | { |
491 | enum rxrpc_call_state state; | ||
491 | enum rxrpc_command cmd; | 492 | enum rxrpc_command cmd; |
492 | struct rxrpc_call *call; | 493 | struct rxrpc_call *call; |
493 | unsigned long user_call_ID = 0; | 494 | unsigned long user_call_ID = 0; |
@@ -526,13 +527,17 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) | |||
526 | return PTR_ERR(call); | 527 | return PTR_ERR(call); |
527 | /* ... and we have the call lock. */ | 528 | /* ... and we have the call lock. */ |
528 | } else { | 529 | } else { |
529 | ret = -EBUSY; | 530 | switch (READ_ONCE(call->state)) { |
530 | if (call->state == RXRPC_CALL_UNINITIALISED || | 531 | case RXRPC_CALL_UNINITIALISED: |
531 | call->state == RXRPC_CALL_CLIENT_AWAIT_CONN || | 532 | case RXRPC_CALL_CLIENT_AWAIT_CONN: |
532 | call->state == RXRPC_CALL_SERVER_PREALLOC || | 533 | case RXRPC_CALL_SERVER_PREALLOC: |
533 | call->state == RXRPC_CALL_SERVER_SECURING || | 534 | case RXRPC_CALL_SERVER_SECURING: |
534 | call->state == RXRPC_CALL_SERVER_ACCEPTING) | 535 | case RXRPC_CALL_SERVER_ACCEPTING: |
536 | ret = -EBUSY; | ||
535 | goto error_release_sock; | 537 | goto error_release_sock; |
538 | default: | ||
539 | break; | ||
540 | } | ||
536 | 541 | ||
537 | ret = mutex_lock_interruptible(&call->user_mutex); | 542 | ret = mutex_lock_interruptible(&call->user_mutex); |
538 | release_sock(&rx->sk); | 543 | release_sock(&rx->sk); |
@@ -542,10 +547,11 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) | |||
542 | } | 547 | } |
543 | } | 548 | } |
544 | 549 | ||
550 | state = READ_ONCE(call->state); | ||
545 | _debug("CALL %d USR %lx ST %d on CONN %p", | 551 | _debug("CALL %d USR %lx ST %d on CONN %p", |
546 | call->debug_id, call->user_call_ID, call->state, call->conn); | 552 | call->debug_id, call->user_call_ID, state, call->conn); |
547 | 553 | ||
548 | if (call->state >= RXRPC_CALL_COMPLETE) { | 554 | if (state >= RXRPC_CALL_COMPLETE) { |
549 | /* it's too late for this call */ | 555 | /* it's too late for this call */ |
550 | ret = -ESHUTDOWN; | 556 | ret = -ESHUTDOWN; |
551 | } else if (cmd == RXRPC_CMD_SEND_ABORT) { | 557 | } else if (cmd == RXRPC_CMD_SEND_ABORT) { |
@@ -555,12 +561,12 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) | |||
555 | } else if (cmd != RXRPC_CMD_SEND_DATA) { | 561 | } else if (cmd != RXRPC_CMD_SEND_DATA) { |
556 | ret = -EINVAL; | 562 | ret = -EINVAL; |
557 | } else if (rxrpc_is_client_call(call) && | 563 | } else if (rxrpc_is_client_call(call) && |
558 | call->state != RXRPC_CALL_CLIENT_SEND_REQUEST) { | 564 | state != RXRPC_CALL_CLIENT_SEND_REQUEST) { |
559 | /* request phase complete for this client call */ | 565 | /* request phase complete for this client call */ |
560 | ret = -EPROTO; | 566 | ret = -EPROTO; |
561 | } else if (rxrpc_is_service_call(call) && | 567 | } else if (rxrpc_is_service_call(call) && |
562 | call->state != RXRPC_CALL_SERVER_ACK_REQUEST && | 568 | state != RXRPC_CALL_SERVER_ACK_REQUEST && |
563 | call->state != RXRPC_CALL_SERVER_SEND_REPLY) { | 569 | state != RXRPC_CALL_SERVER_SEND_REPLY) { |
564 | /* Reply phase not begun or not complete for service call. */ | 570 | /* Reply phase not begun or not complete for service call. */ |
565 | ret = -EPROTO; | 571 | ret = -EPROTO; |
566 | } else { | 572 | } else { |
@@ -605,14 +611,21 @@ int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call, | |||
605 | _debug("CALL %d USR %lx ST %d on CONN %p", | 611 | _debug("CALL %d USR %lx ST %d on CONN %p", |
606 | call->debug_id, call->user_call_ID, call->state, call->conn); | 612 | call->debug_id, call->user_call_ID, call->state, call->conn); |
607 | 613 | ||
608 | if (call->state >= RXRPC_CALL_COMPLETE) { | 614 | switch (READ_ONCE(call->state)) { |
609 | ret = -ESHUTDOWN; /* it's too late for this call */ | 615 | case RXRPC_CALL_CLIENT_SEND_REQUEST: |
610 | } else if (call->state != RXRPC_CALL_CLIENT_SEND_REQUEST && | 616 | case RXRPC_CALL_SERVER_ACK_REQUEST: |
611 | call->state != RXRPC_CALL_SERVER_ACK_REQUEST && | 617 | case RXRPC_CALL_SERVER_SEND_REPLY: |
612 | call->state != RXRPC_CALL_SERVER_SEND_REPLY) { | ||
613 | ret = -EPROTO; /* request phase complete for this client call */ | ||
614 | } else { | ||
615 | ret = rxrpc_send_data(rxrpc_sk(sock->sk), call, msg, len); | 618 | ret = rxrpc_send_data(rxrpc_sk(sock->sk), call, msg, len); |
619 | break; | ||
620 | case RXRPC_CALL_COMPLETE: | ||
621 | read_lock_bh(&call->state_lock); | ||
622 | ret = -call->error; | ||
623 | read_unlock_bh(&call->state_lock); | ||
624 | break; | ||
625 | default: | ||
626 | /* Request phase complete for this client call */ | ||
627 | ret = -EPROTO; | ||
628 | break; | ||
616 | } | 629 | } |
617 | 630 | ||
618 | mutex_unlock(&call->user_mutex); | 631 | mutex_unlock(&call->user_mutex); |
diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c index ab8062909962..f9bb43c25697 100644 --- a/net/sched/act_connmark.c +++ b/net/sched/act_connmark.c | |||
@@ -113,6 +113,9 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla, | |||
113 | if (ret < 0) | 113 | if (ret < 0) |
114 | return ret; | 114 | return ret; |
115 | 115 | ||
116 | if (!tb[TCA_CONNMARK_PARMS]) | ||
117 | return -EINVAL; | ||
118 | |||
116 | parm = nla_data(tb[TCA_CONNMARK_PARMS]); | 119 | parm = nla_data(tb[TCA_CONNMARK_PARMS]); |
117 | 120 | ||
118 | if (!tcf_hash_check(tn, parm->index, a, bind)) { | 121 | if (!tcf_hash_check(tn, parm->index, a, bind)) { |
diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c index 3b7074e23024..c736627f8f4a 100644 --- a/net/sched/act_skbmod.c +++ b/net/sched/act_skbmod.c | |||
@@ -228,7 +228,6 @@ static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a, | |||
228 | 228 | ||
229 | return skb->len; | 229 | return skb->len; |
230 | nla_put_failure: | 230 | nla_put_failure: |
231 | rcu_read_unlock(); | ||
232 | nlmsg_trim(skb, b); | 231 | nlmsg_trim(skb, b); |
233 | return -1; | 232 | return -1; |
234 | } | 233 | } |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 063baac5b9fe..961ee59f696a 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -640,14 +640,15 @@ static sctp_scope_t sctp_v6_scope(union sctp_addr *addr) | |||
640 | 640 | ||
641 | /* Create and initialize a new sk for the socket to be returned by accept(). */ | 641 | /* Create and initialize a new sk for the socket to be returned by accept(). */ |
642 | static struct sock *sctp_v6_create_accept_sk(struct sock *sk, | 642 | static struct sock *sctp_v6_create_accept_sk(struct sock *sk, |
643 | struct sctp_association *asoc) | 643 | struct sctp_association *asoc, |
644 | bool kern) | ||
644 | { | 645 | { |
645 | struct sock *newsk; | 646 | struct sock *newsk; |
646 | struct ipv6_pinfo *newnp, *np = inet6_sk(sk); | 647 | struct ipv6_pinfo *newnp, *np = inet6_sk(sk); |
647 | struct sctp6_sock *newsctp6sk; | 648 | struct sctp6_sock *newsctp6sk; |
648 | struct ipv6_txoptions *opt; | 649 | struct ipv6_txoptions *opt; |
649 | 650 | ||
650 | newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot, 0); | 651 | newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot, kern); |
651 | if (!newsk) | 652 | if (!newsk) |
652 | goto out; | 653 | goto out; |
653 | 654 | ||
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 1b6d4574d2b0..989a900383b5 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -575,10 +575,11 @@ static int sctp_v4_is_ce(const struct sk_buff *skb) | |||
575 | 575 | ||
576 | /* Create and initialize a new sk for the socket returned by accept(). */ | 576 | /* Create and initialize a new sk for the socket returned by accept(). */ |
577 | static struct sock *sctp_v4_create_accept_sk(struct sock *sk, | 577 | static struct sock *sctp_v4_create_accept_sk(struct sock *sk, |
578 | struct sctp_association *asoc) | 578 | struct sctp_association *asoc, |
579 | bool kern) | ||
579 | { | 580 | { |
580 | struct sock *newsk = sk_alloc(sock_net(sk), PF_INET, GFP_KERNEL, | 581 | struct sock *newsk = sk_alloc(sock_net(sk), PF_INET, GFP_KERNEL, |
581 | sk->sk_prot, 0); | 582 | sk->sk_prot, kern); |
582 | struct inet_sock *newinet; | 583 | struct inet_sock *newinet; |
583 | 584 | ||
584 | if (!newsk) | 585 | if (!newsk) |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 6f0a9be50f50..0f378ea2ae38 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -4116,7 +4116,7 @@ static int sctp_disconnect(struct sock *sk, int flags) | |||
4116 | * descriptor will be returned from accept() to represent the newly | 4116 | * descriptor will be returned from accept() to represent the newly |
4117 | * formed association. | 4117 | * formed association. |
4118 | */ | 4118 | */ |
4119 | static struct sock *sctp_accept(struct sock *sk, int flags, int *err) | 4119 | static struct sock *sctp_accept(struct sock *sk, int flags, int *err, bool kern) |
4120 | { | 4120 | { |
4121 | struct sctp_sock *sp; | 4121 | struct sctp_sock *sp; |
4122 | struct sctp_endpoint *ep; | 4122 | struct sctp_endpoint *ep; |
@@ -4151,7 +4151,7 @@ static struct sock *sctp_accept(struct sock *sk, int flags, int *err) | |||
4151 | */ | 4151 | */ |
4152 | asoc = list_entry(ep->asocs.next, struct sctp_association, asocs); | 4152 | asoc = list_entry(ep->asocs.next, struct sctp_association, asocs); |
4153 | 4153 | ||
4154 | newsk = sp->pf->create_accept_sk(sk, asoc); | 4154 | newsk = sp->pf->create_accept_sk(sk, asoc, kern); |
4155 | if (!newsk) { | 4155 | if (!newsk) { |
4156 | error = -ENOMEM; | 4156 | error = -ENOMEM; |
4157 | goto out; | 4157 | goto out; |
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 85837ab90e89..093803786eac 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c | |||
@@ -944,7 +944,7 @@ out: | |||
944 | } | 944 | } |
945 | 945 | ||
946 | static int smc_accept(struct socket *sock, struct socket *new_sock, | 946 | static int smc_accept(struct socket *sock, struct socket *new_sock, |
947 | int flags) | 947 | int flags, bool kern) |
948 | { | 948 | { |
949 | struct sock *sk = sock->sk, *nsk; | 949 | struct sock *sk = sock->sk, *nsk; |
950 | DECLARE_WAITQUEUE(wait, current); | 950 | DECLARE_WAITQUEUE(wait, current); |
diff --git a/net/socket.c b/net/socket.c index 2c1e8677ff2d..e034fe4164be 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -1506,7 +1506,7 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, | |||
1506 | if (err) | 1506 | if (err) |
1507 | goto out_fd; | 1507 | goto out_fd; |
1508 | 1508 | ||
1509 | err = sock->ops->accept(sock, newsock, sock->file->f_flags); | 1509 | err = sock->ops->accept(sock, newsock, sock->file->f_flags, false); |
1510 | if (err < 0) | 1510 | if (err < 0) |
1511 | goto out_fd; | 1511 | goto out_fd; |
1512 | 1512 | ||
@@ -1731,6 +1731,7 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, | |||
1731 | /* We assume all kernel code knows the size of sockaddr_storage */ | 1731 | /* We assume all kernel code knows the size of sockaddr_storage */ |
1732 | msg.msg_namelen = 0; | 1732 | msg.msg_namelen = 0; |
1733 | msg.msg_iocb = NULL; | 1733 | msg.msg_iocb = NULL; |
1734 | msg.msg_flags = 0; | ||
1734 | if (sock->file->f_flags & O_NONBLOCK) | 1735 | if (sock->file->f_flags & O_NONBLOCK) |
1735 | flags |= MSG_DONTWAIT; | 1736 | flags |= MSG_DONTWAIT; |
1736 | err = sock_recvmsg(sock, &msg, flags); | 1737 | err = sock_recvmsg(sock, &msg, flags); |
@@ -3238,7 +3239,7 @@ int kernel_accept(struct socket *sock, struct socket **newsock, int flags) | |||
3238 | if (err < 0) | 3239 | if (err < 0) |
3239 | goto done; | 3240 | goto done; |
3240 | 3241 | ||
3241 | err = sock->ops->accept(sock, *newsock, flags); | 3242 | err = sock->ops->accept(sock, *newsock, flags, true); |
3242 | if (err < 0) { | 3243 | if (err < 0) { |
3243 | sock_release(*newsock); | 3244 | sock_release(*newsock); |
3244 | *newsock = NULL; | 3245 | *newsock = NULL; |
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 81cd31acf690..3b332b395045 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c | |||
@@ -503,7 +503,8 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia, | |||
503 | struct ib_cq *sendcq, *recvcq; | 503 | struct ib_cq *sendcq, *recvcq; |
504 | int rc; | 504 | int rc; |
505 | 505 | ||
506 | max_sge = min(ia->ri_device->attrs.max_sge, RPCRDMA_MAX_SEND_SGES); | 506 | max_sge = min_t(unsigned int, ia->ri_device->attrs.max_sge, |
507 | RPCRDMA_MAX_SEND_SGES); | ||
507 | if (max_sge < RPCRDMA_MIN_SEND_SGES) { | 508 | if (max_sge < RPCRDMA_MIN_SEND_SGES) { |
508 | pr_warn("rpcrdma: HCA provides only %d send SGEs\n", max_sge); | 509 | pr_warn("rpcrdma: HCA provides only %d send SGEs\n", max_sge); |
509 | return -ENOMEM; | 510 | return -ENOMEM; |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 43e4045e72bc..7130e73bd42c 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -115,7 +115,8 @@ static void tipc_data_ready(struct sock *sk); | |||
115 | static void tipc_write_space(struct sock *sk); | 115 | static void tipc_write_space(struct sock *sk); |
116 | static void tipc_sock_destruct(struct sock *sk); | 116 | static void tipc_sock_destruct(struct sock *sk); |
117 | static int tipc_release(struct socket *sock); | 117 | static int tipc_release(struct socket *sock); |
118 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); | 118 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags, |
119 | bool kern); | ||
119 | static void tipc_sk_timeout(unsigned long data); | 120 | static void tipc_sk_timeout(unsigned long data); |
120 | static int tipc_sk_publish(struct tipc_sock *tsk, uint scope, | 121 | static int tipc_sk_publish(struct tipc_sock *tsk, uint scope, |
121 | struct tipc_name_seq const *seq); | 122 | struct tipc_name_seq const *seq); |
@@ -2029,7 +2030,8 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo) | |||
2029 | * | 2030 | * |
2030 | * Returns 0 on success, errno otherwise | 2031 | * Returns 0 on success, errno otherwise |
2031 | */ | 2032 | */ |
2032 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) | 2033 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags, |
2034 | bool kern) | ||
2033 | { | 2035 | { |
2034 | struct sock *new_sk, *sk = sock->sk; | 2036 | struct sock *new_sk, *sk = sock->sk; |
2035 | struct sk_buff *buf; | 2037 | struct sk_buff *buf; |
@@ -2051,7 +2053,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) | |||
2051 | 2053 | ||
2052 | buf = skb_peek(&sk->sk_receive_queue); | 2054 | buf = skb_peek(&sk->sk_receive_queue); |
2053 | 2055 | ||
2054 | res = tipc_sk_create(sock_net(sock->sk), new_sock, 0, 0); | 2056 | res = tipc_sk_create(sock_net(sock->sk), new_sock, 0, kern); |
2055 | if (res) | 2057 | if (res) |
2056 | goto exit; | 2058 | goto exit; |
2057 | security_sk_clone(sock->sk, new_sock->sk); | 2059 | security_sk_clone(sock->sk, new_sock->sk); |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index ee37b390260a..928691c43408 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -636,7 +636,7 @@ static int unix_bind(struct socket *, struct sockaddr *, int); | |||
636 | static int unix_stream_connect(struct socket *, struct sockaddr *, | 636 | static int unix_stream_connect(struct socket *, struct sockaddr *, |
637 | int addr_len, int flags); | 637 | int addr_len, int flags); |
638 | static int unix_socketpair(struct socket *, struct socket *); | 638 | static int unix_socketpair(struct socket *, struct socket *); |
639 | static int unix_accept(struct socket *, struct socket *, int); | 639 | static int unix_accept(struct socket *, struct socket *, int, bool); |
640 | static int unix_getname(struct socket *, struct sockaddr *, int *, int); | 640 | static int unix_getname(struct socket *, struct sockaddr *, int *, int); |
641 | static unsigned int unix_poll(struct file *, struct socket *, poll_table *); | 641 | static unsigned int unix_poll(struct file *, struct socket *, poll_table *); |
642 | static unsigned int unix_dgram_poll(struct file *, struct socket *, | 642 | static unsigned int unix_dgram_poll(struct file *, struct socket *, |
@@ -1402,7 +1402,8 @@ static void unix_sock_inherit_flags(const struct socket *old, | |||
1402 | set_bit(SOCK_PASSSEC, &new->flags); | 1402 | set_bit(SOCK_PASSSEC, &new->flags); |
1403 | } | 1403 | } |
1404 | 1404 | ||
1405 | static int unix_accept(struct socket *sock, struct socket *newsock, int flags) | 1405 | static int unix_accept(struct socket *sock, struct socket *newsock, int flags, |
1406 | bool kern) | ||
1406 | { | 1407 | { |
1407 | struct sock *sk = sock->sk; | 1408 | struct sock *sk = sock->sk; |
1408 | struct sock *tsk; | 1409 | struct sock *tsk; |
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 9192ead66751..9f770f33c100 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c | |||
@@ -1250,7 +1250,8 @@ out: | |||
1250 | return err; | 1250 | return err; |
1251 | } | 1251 | } |
1252 | 1252 | ||
1253 | static int vsock_accept(struct socket *sock, struct socket *newsock, int flags) | 1253 | static int vsock_accept(struct socket *sock, struct socket *newsock, int flags, |
1254 | bool kern) | ||
1254 | { | 1255 | { |
1255 | struct sock *listener; | 1256 | struct sock *listener; |
1256 | int err; | 1257 | int err; |
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index fd28a49dbe8f..8b911c29860e 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
@@ -852,7 +852,8 @@ static int x25_wait_for_data(struct sock *sk, long timeout) | |||
852 | return rc; | 852 | return rc; |
853 | } | 853 | } |
854 | 854 | ||
855 | static int x25_accept(struct socket *sock, struct socket *newsock, int flags) | 855 | static int x25_accept(struct socket *sock, struct socket *newsock, int flags, |
856 | bool kern) | ||
856 | { | 857 | { |
857 | struct sock *sk = sock->sk; | 858 | struct sock *sk = sock->sk; |
858 | struct sock *newsk; | 859 | struct sock *newsk; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 0806dccdf507..236cbbc0ab9c 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1243,7 +1243,7 @@ static inline int policy_to_flow_dir(int dir) | |||
1243 | } | 1243 | } |
1244 | 1244 | ||
1245 | static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, | 1245 | static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, |
1246 | const struct flowi *fl) | 1246 | const struct flowi *fl, u16 family) |
1247 | { | 1247 | { |
1248 | struct xfrm_policy *pol; | 1248 | struct xfrm_policy *pol; |
1249 | 1249 | ||
@@ -1251,8 +1251,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, | |||
1251 | again: | 1251 | again: |
1252 | pol = rcu_dereference(sk->sk_policy[dir]); | 1252 | pol = rcu_dereference(sk->sk_policy[dir]); |
1253 | if (pol != NULL) { | 1253 | if (pol != NULL) { |
1254 | bool match = xfrm_selector_match(&pol->selector, fl, | 1254 | bool match = xfrm_selector_match(&pol->selector, fl, family); |
1255 | sk->sk_family); | ||
1256 | int err = 0; | 1255 | int err = 0; |
1257 | 1256 | ||
1258 | if (match) { | 1257 | if (match) { |
@@ -2239,7 +2238,7 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, | |||
2239 | sk = sk_const_to_full_sk(sk); | 2238 | sk = sk_const_to_full_sk(sk); |
2240 | if (sk && sk->sk_policy[XFRM_POLICY_OUT]) { | 2239 | if (sk && sk->sk_policy[XFRM_POLICY_OUT]) { |
2241 | num_pols = 1; | 2240 | num_pols = 1; |
2242 | pols[0] = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); | 2241 | pols[0] = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl, family); |
2243 | err = xfrm_expand_policies(fl, family, pols, | 2242 | err = xfrm_expand_policies(fl, family, pols, |
2244 | &num_pols, &num_xfrms); | 2243 | &num_pols, &num_xfrms); |
2245 | if (err < 0) | 2244 | if (err < 0) |
@@ -2518,7 +2517,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
2518 | pol = NULL; | 2517 | pol = NULL; |
2519 | sk = sk_to_full_sk(sk); | 2518 | sk = sk_to_full_sk(sk); |
2520 | if (sk && sk->sk_policy[dir]) { | 2519 | if (sk && sk->sk_policy[dir]) { |
2521 | pol = xfrm_sk_policy_lookup(sk, dir, &fl); | 2520 | pol = xfrm_sk_policy_lookup(sk, dir, &fl, family); |
2522 | if (IS_ERR(pol)) { | 2521 | if (IS_ERR(pol)) { |
2523 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR); | 2522 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR); |
2524 | return 0; | 2523 | return 0; |
@@ -3069,6 +3068,11 @@ static int __net_init xfrm_net_init(struct net *net) | |||
3069 | { | 3068 | { |
3070 | int rv; | 3069 | int rv; |
3071 | 3070 | ||
3071 | /* Initialize the per-net locks here */ | ||
3072 | spin_lock_init(&net->xfrm.xfrm_state_lock); | ||
3073 | spin_lock_init(&net->xfrm.xfrm_policy_lock); | ||
3074 | mutex_init(&net->xfrm.xfrm_cfg_mutex); | ||
3075 | |||
3072 | rv = xfrm_statistics_init(net); | 3076 | rv = xfrm_statistics_init(net); |
3073 | if (rv < 0) | 3077 | if (rv < 0) |
3074 | goto out_statistics; | 3078 | goto out_statistics; |
@@ -3085,11 +3089,6 @@ static int __net_init xfrm_net_init(struct net *net) | |||
3085 | if (rv < 0) | 3089 | if (rv < 0) |
3086 | goto out; | 3090 | goto out; |
3087 | 3091 | ||
3088 | /* Initialize the per-net locks here */ | ||
3089 | spin_lock_init(&net->xfrm.xfrm_state_lock); | ||
3090 | spin_lock_init(&net->xfrm.xfrm_policy_lock); | ||
3091 | mutex_init(&net->xfrm.xfrm_cfg_mutex); | ||
3092 | |||
3093 | return 0; | 3092 | return 0; |
3094 | 3093 | ||
3095 | out: | 3094 | out: |
diff --git a/tools/include/uapi/linux/bpf_perf_event.h b/tools/include/uapi/linux/bpf_perf_event.h new file mode 100644 index 000000000000..067427259820 --- /dev/null +++ b/tools/include/uapi/linux/bpf_perf_event.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* Copyright (c) 2016 Facebook | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or | ||
4 | * modify it under the terms of version 2 of the GNU General Public | ||
5 | * License as published by the Free Software Foundation. | ||
6 | */ | ||
7 | #ifndef _UAPI__LINUX_BPF_PERF_EVENT_H__ | ||
8 | #define _UAPI__LINUX_BPF_PERF_EVENT_H__ | ||
9 | |||
10 | #include <linux/types.h> | ||
11 | #include <linux/ptrace.h> | ||
12 | |||
13 | struct bpf_perf_event_data { | ||
14 | struct pt_regs regs; | ||
15 | __u64 sample_period; | ||
16 | }; | ||
17 | |||
18 | #endif /* _UAPI__LINUX_BPF_PERF_EVENT_H__ */ | ||
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 70e389bc4af7..9b4d8ba22fed 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -202,7 +202,7 @@ void symbols__fixup_end(struct rb_root *symbols) | |||
202 | 202 | ||
203 | /* Last entry */ | 203 | /* Last entry */ |
204 | if (curr->end == curr->start) | 204 | if (curr->end == curr->start) |
205 | curr->end = roundup(curr->start, 4096); | 205 | curr->end = roundup(curr->start, 4096) + 4096; |
206 | } | 206 | } |
207 | 207 | ||
208 | void __map_groups__fixup_end(struct map_groups *mg, enum map_type type) | 208 | void __map_groups__fixup_end(struct map_groups *mg, enum map_type type) |
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 4b498265dae6..67531f47781b 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile | |||
@@ -1,12 +1,14 @@ | |||
1 | LIBDIR := ../../../lib | 1 | LIBDIR := ../../../lib |
2 | BPFOBJ := $(LIBDIR)/bpf/bpf.o | 2 | BPFOBJ := $(LIBDIR)/bpf/bpf.o |
3 | 3 | ||
4 | CFLAGS += -Wall -O2 -lcap -I../../../include/uapi -I$(LIBDIR) | 4 | CFLAGS += -Wall -O2 -lcap -I../../../include/uapi -I$(LIBDIR) $(BPFOBJ) |
5 | 5 | ||
6 | TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map | 6 | TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map |
7 | 7 | ||
8 | TEST_PROGS := test_kmod.sh | 8 | TEST_PROGS := test_kmod.sh |
9 | 9 | ||
10 | all: $(TEST_GEN_PROGS) | ||
11 | |||
10 | .PHONY: all clean force | 12 | .PHONY: all clean force |
11 | 13 | ||
12 | # force a rebuild of BPFOBJ when its dependencies are updated | 14 | # force a rebuild of BPFOBJ when its dependencies are updated |
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index e1f5b9eea1e8..d1555e4240c0 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c | |||
@@ -8,6 +8,8 @@ | |||
8 | * License as published by the Free Software Foundation. | 8 | * License as published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <asm/types.h> | ||
12 | #include <linux/types.h> | ||
11 | #include <stdint.h> | 13 | #include <stdint.h> |
12 | #include <stdio.h> | 14 | #include <stdio.h> |
13 | #include <stdlib.h> | 15 | #include <stdlib.h> |
@@ -4583,10 +4585,12 @@ static bool is_admin(void) | |||
4583 | cap_flag_value_t sysadmin = CAP_CLEAR; | 4585 | cap_flag_value_t sysadmin = CAP_CLEAR; |
4584 | const cap_value_t cap_val = CAP_SYS_ADMIN; | 4586 | const cap_value_t cap_val = CAP_SYS_ADMIN; |
4585 | 4587 | ||
4588 | #ifdef CAP_IS_SUPPORTED | ||
4586 | if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) { | 4589 | if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) { |
4587 | perror("cap_get_flag"); | 4590 | perror("cap_get_flag"); |
4588 | return false; | 4591 | return false; |
4589 | } | 4592 | } |
4593 | #endif | ||
4590 | caps = cap_get_proc(); | 4594 | caps = cap_get_proc(); |
4591 | if (!caps) { | 4595 | if (!caps) { |
4592 | perror("cap_get_proc"); | 4596 | perror("cap_get_proc"); |
diff --git a/tools/testing/selftests/powerpc/include/vsx_asm.h b/tools/testing/selftests/powerpc/include/vsx_asm.h index d828bfb6ef2d..54064ced9e95 100644 --- a/tools/testing/selftests/powerpc/include/vsx_asm.h +++ b/tools/testing/selftests/powerpc/include/vsx_asm.h | |||
@@ -16,56 +16,56 @@ | |||
16 | */ | 16 | */ |
17 | FUNC_START(load_vsx) | 17 | FUNC_START(load_vsx) |
18 | li r5,0 | 18 | li r5,0 |
19 | lxvx vs20,r5,r3 | 19 | lxvd2x vs20,r5,r3 |
20 | addi r5,r5,16 | 20 | addi r5,r5,16 |
21 | lxvx vs21,r5,r3 | 21 | lxvd2x vs21,r5,r3 |
22 | addi r5,r5,16 | 22 | addi r5,r5,16 |
23 | lxvx vs22,r5,r3 | 23 | lxvd2x vs22,r5,r3 |
24 | addi r5,r5,16 | 24 | addi r5,r5,16 |
25 | lxvx vs23,r5,r3 | 25 | lxvd2x vs23,r5,r3 |
26 | addi r5,r5,16 | 26 | addi r5,r5,16 |
27 | lxvx vs24,r5,r3 | 27 | lxvd2x vs24,r5,r3 |
28 | addi r5,r5,16 | 28 | addi r5,r5,16 |
29 | lxvx vs25,r5,r3 | 29 | lxvd2x vs25,r5,r3 |
30 | addi r5,r5,16 | 30 | addi r5,r5,16 |
31 | lxvx vs26,r5,r3 | 31 | lxvd2x vs26,r5,r3 |
32 | addi r5,r5,16 | 32 | addi r5,r5,16 |
33 | lxvx vs27,r5,r3 | 33 | lxvd2x vs27,r5,r3 |
34 | addi r5,r5,16 | 34 | addi r5,r5,16 |
35 | lxvx vs28,r5,r3 | 35 | lxvd2x vs28,r5,r3 |
36 | addi r5,r5,16 | 36 | addi r5,r5,16 |
37 | lxvx vs29,r5,r3 | 37 | lxvd2x vs29,r5,r3 |
38 | addi r5,r5,16 | 38 | addi r5,r5,16 |
39 | lxvx vs30,r5,r3 | 39 | lxvd2x vs30,r5,r3 |
40 | addi r5,r5,16 | 40 | addi r5,r5,16 |
41 | lxvx vs31,r5,r3 | 41 | lxvd2x vs31,r5,r3 |
42 | blr | 42 | blr |
43 | FUNC_END(load_vsx) | 43 | FUNC_END(load_vsx) |
44 | 44 | ||
45 | FUNC_START(store_vsx) | 45 | FUNC_START(store_vsx) |
46 | li r5,0 | 46 | li r5,0 |
47 | stxvx vs20,r5,r3 | 47 | stxvd2x vs20,r5,r3 |
48 | addi r5,r5,16 | 48 | addi r5,r5,16 |
49 | stxvx vs21,r5,r3 | 49 | stxvd2x vs21,r5,r3 |
50 | addi r5,r5,16 | 50 | addi r5,r5,16 |
51 | stxvx vs22,r5,r3 | 51 | stxvd2x vs22,r5,r3 |
52 | addi r5,r5,16 | 52 | addi r5,r5,16 |
53 | stxvx vs23,r5,r3 | 53 | stxvd2x vs23,r5,r3 |
54 | addi r5,r5,16 | 54 | addi r5,r5,16 |
55 | stxvx vs24,r5,r3 | 55 | stxvd2x vs24,r5,r3 |
56 | addi r5,r5,16 | 56 | addi r5,r5,16 |
57 | stxvx vs25,r5,r3 | 57 | stxvd2x vs25,r5,r3 |
58 | addi r5,r5,16 | 58 | addi r5,r5,16 |
59 | stxvx vs26,r5,r3 | 59 | stxvd2x vs26,r5,r3 |
60 | addi r5,r5,16 | 60 | addi r5,r5,16 |
61 | stxvx vs27,r5,r3 | 61 | stxvd2x vs27,r5,r3 |
62 | addi r5,r5,16 | 62 | addi r5,r5,16 |
63 | stxvx vs28,r5,r3 | 63 | stxvd2x vs28,r5,r3 |
64 | addi r5,r5,16 | 64 | addi r5,r5,16 |
65 | stxvx vs29,r5,r3 | 65 | stxvd2x vs29,r5,r3 |
66 | addi r5,r5,16 | 66 | addi r5,r5,16 |
67 | stxvx vs30,r5,r3 | 67 | stxvd2x vs30,r5,r3 |
68 | addi r5,r5,16 | 68 | addi r5,r5,16 |
69 | stxvx vs31,r5,r3 | 69 | stxvd2x vs31,r5,r3 |
70 | blr | 70 | blr |
71 | FUNC_END(store_vsx) | 71 | FUNC_END(store_vsx) |