diff options
239 files changed, 4513 insertions, 1789 deletions
@@ -688,10 +688,13 @@ S: Oxfordshire, UK. | |||
688 | 688 | ||
689 | N: Kees Cook | 689 | N: Kees Cook |
690 | E: kees@outflux.net | 690 | E: kees@outflux.net |
691 | W: http://outflux.net/ | 691 | E: kees@ubuntu.com |
692 | P: 1024D/17063E6D 9FA3 C49C 23C9 D1BC 2E30 1975 1FFF 4BA9 1706 3E6D | 692 | E: keescook@chromium.org |
693 | D: Minor updates to SCSI types, added /proc/pid/maps protection | 693 | W: http://outflux.net/blog/ |
694 | P: 4096R/DC6DC026 A5C3 F68F 229D D60F 723E 6E13 8972 F4DF DC6D C026 | ||
695 | D: Various security things, bug fixes, and documentation. | ||
694 | S: (ask for current address) | 696 | S: (ask for current address) |
697 | S: Portland, Oregon | ||
695 | S: USA | 698 | S: USA |
696 | 699 | ||
697 | N: Robin Cornelius | 700 | N: Robin Cornelius |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index a0c5c5f4fce6..22152ed148a5 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -315,12 +315,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
315 | CPU-intensive style benchmark, and it can vary highly in | 315 | CPU-intensive style benchmark, and it can vary highly in |
316 | a microbenchmark depending on workload and compiler. | 316 | a microbenchmark depending on workload and compiler. |
317 | 317 | ||
318 | 1: only for 32-bit processes | 318 | 32: only for 32-bit processes |
319 | 2: only for 64-bit processes | 319 | 64: only for 64-bit processes |
320 | on: enable for both 32- and 64-bit processes | 320 | on: enable for both 32- and 64-bit processes |
321 | off: disable for both 32- and 64-bit processes | 321 | off: disable for both 32- and 64-bit processes |
322 | 322 | ||
323 | amd_iommu= [HW,X86-84] | 323 | amd_iommu= [HW,X86-64] |
324 | Pass parameters to the AMD IOMMU driver in the system. | 324 | Pass parameters to the AMD IOMMU driver in the system. |
325 | Possible values are: | 325 | Possible values are: |
326 | fullflush - enable flushing of IO/TLB entries when | 326 | fullflush - enable flushing of IO/TLB entries when |
@@ -329,6 +329,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
329 | is a lot of faster | 329 | is a lot of faster |
330 | off - do not initialize any AMD IOMMU found in | 330 | off - do not initialize any AMD IOMMU found in |
331 | the system | 331 | the system |
332 | force_isolation - Force device isolation for all | ||
333 | devices. The IOMMU driver is not | ||
334 | allowed anymore to lift isolation | ||
335 | requirements as needed. This option | ||
336 | does not override iommu=pt | ||
332 | 337 | ||
333 | amijoy.map= [HW,JOY] Amiga joystick support | 338 | amijoy.map= [HW,JOY] Amiga joystick support |
334 | Map of devices attached to JOY0DAT and JOY1DAT | 339 | Map of devices attached to JOY0DAT and JOY1DAT |
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index f049a1ca186f..589f2da5d545 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
@@ -282,11 +282,11 @@ tcp_max_ssthresh - INTEGER | |||
282 | Default: 0 (off) | 282 | Default: 0 (off) |
283 | 283 | ||
284 | tcp_max_syn_backlog - INTEGER | 284 | tcp_max_syn_backlog - INTEGER |
285 | Maximal number of remembered connection requests, which are | 285 | Maximal number of remembered connection requests, which have not |
286 | still did not receive an acknowledgment from connecting client. | 286 | received an acknowledgment from connecting client. |
287 | Default value is 1024 for systems with more than 128Mb of memory, | 287 | The minimal value is 128 for low memory machines, and it will |
288 | and 128 for low memory machines. If server suffers of overload, | 288 | increase in proportion to the memory of machine. |
289 | try to increase this number. | 289 | If server suffers from overload, try increasing this number. |
290 | 290 | ||
291 | tcp_max_tw_buckets - INTEGER | 291 | tcp_max_tw_buckets - INTEGER |
292 | Maximal number of timewait sockets held by system simultaneously. | 292 | Maximal number of timewait sockets held by system simultaneously. |
diff --git a/Documentation/sound/alsa/soc/machine.txt b/Documentation/sound/alsa/soc/machine.txt index 3e2ec9cbf397..d50c14df3411 100644 --- a/Documentation/sound/alsa/soc/machine.txt +++ b/Documentation/sound/alsa/soc/machine.txt | |||
@@ -50,8 +50,7 @@ Machine DAI Configuration | |||
50 | The machine DAI configuration glues all the codec and CPU DAIs together. It can | 50 | The machine DAI configuration glues all the codec and CPU DAIs together. It can |
51 | also be used to set up the DAI system clock and for any machine related DAI | 51 | also be used to set up the DAI system clock and for any machine related DAI |
52 | initialisation e.g. the machine audio map can be connected to the codec audio | 52 | initialisation e.g. the machine audio map can be connected to the codec audio |
53 | map, unconnected codec pins can be set as such. Please see corgi.c, spitz.c | 53 | map, unconnected codec pins can be set as such. |
54 | for examples. | ||
55 | 54 | ||
56 | struct snd_soc_dai_link is used to set up each DAI in your machine. e.g. | 55 | struct snd_soc_dai_link is used to set up each DAI in your machine. e.g. |
57 | 56 | ||
@@ -83,8 +82,7 @@ Machine Power Map | |||
83 | The machine driver can optionally extend the codec power map and to become an | 82 | The machine driver can optionally extend the codec power map and to become an |
84 | audio power map of the audio subsystem. This allows for automatic power up/down | 83 | audio power map of the audio subsystem. This allows for automatic power up/down |
85 | of speaker/HP amplifiers, etc. Codec pins can be connected to the machines jack | 84 | of speaker/HP amplifiers, etc. Codec pins can be connected to the machines jack |
86 | sockets in the machine init function. See soc/pxa/spitz.c and dapm.txt for | 85 | sockets in the machine init function. |
87 | details. | ||
88 | 86 | ||
89 | 87 | ||
90 | Machine Controls | 88 | Machine Controls |
diff --git a/MAINTAINERS b/MAINTAINERS index 447560284996..b9db108f01c8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -511,8 +511,8 @@ M: Joerg Roedel <joerg.roedel@amd.com> | |||
511 | L: iommu@lists.linux-foundation.org | 511 | L: iommu@lists.linux-foundation.org |
512 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/linux-2.6-iommu.git | 512 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/linux-2.6-iommu.git |
513 | S: Supported | 513 | S: Supported |
514 | F: arch/x86/kernel/amd_iommu*.c | 514 | F: drivers/iommu/amd_iommu*.[ch] |
515 | F: arch/x86/include/asm/amd_iommu*.h | 515 | F: include/linux/amd-iommu.h |
516 | 516 | ||
517 | AMD MICROCODE UPDATE SUPPORT | 517 | AMD MICROCODE UPDATE SUPPORT |
518 | M: Andreas Herrmann <andreas.herrmann3@amd.com> | 518 | M: Andreas Herrmann <andreas.herrmann3@amd.com> |
@@ -1054,35 +1054,18 @@ ARM/SAMSUNG ARM ARCHITECTURES | |||
1054 | M: Ben Dooks <ben-linux@fluff.org> | 1054 | M: Ben Dooks <ben-linux@fluff.org> |
1055 | M: Kukjin Kim <kgene.kim@samsung.com> | 1055 | M: Kukjin Kim <kgene.kim@samsung.com> |
1056 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 1056 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
1057 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) | ||
1057 | W: http://www.fluff.org/ben/linux/ | 1058 | W: http://www.fluff.org/ben/linux/ |
1058 | S: Maintained | 1059 | S: Maintained |
1059 | F: arch/arm/plat-samsung/ | 1060 | F: arch/arm/plat-samsung/ |
1060 | F: arch/arm/plat-s3c24xx/ | 1061 | F: arch/arm/plat-s3c24xx/ |
1061 | F: arch/arm/plat-s5p/ | 1062 | F: arch/arm/plat-s5p/ |
1063 | F: arch/arm/mach-s3c24*/ | ||
1064 | F: arch/arm/mach-s3c64xx/ | ||
1062 | F: drivers/*/*s3c2410* | 1065 | F: drivers/*/*s3c2410* |
1063 | F: drivers/*/*/*s3c2410* | 1066 | F: drivers/*/*/*s3c2410* |
1064 | 1067 | F: drivers/spi/spi-s3c* | |
1065 | ARM/S3C2410 ARM ARCHITECTURE | 1068 | F: sound/soc/samsung/* |
1066 | M: Ben Dooks <ben-linux@fluff.org> | ||
1067 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
1068 | W: http://www.fluff.org/ben/linux/ | ||
1069 | S: Maintained | ||
1070 | F: arch/arm/mach-s3c2410/ | ||
1071 | |||
1072 | ARM/S3C244x ARM ARCHITECTURE | ||
1073 | M: Ben Dooks <ben-linux@fluff.org> | ||
1074 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
1075 | W: http://www.fluff.org/ben/linux/ | ||
1076 | S: Maintained | ||
1077 | F: arch/arm/mach-s3c2440/ | ||
1078 | F: arch/arm/mach-s3c2443/ | ||
1079 | |||
1080 | ARM/S3C64xx ARM ARCHITECTURE | ||
1081 | M: Ben Dooks <ben-linux@fluff.org> | ||
1082 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
1083 | W: http://www.fluff.org/ben/linux/ | ||
1084 | S: Maintained | ||
1085 | F: arch/arm/mach-s3c64xx/ | ||
1086 | 1069 | ||
1087 | ARM/S5P EXYNOS ARM ARCHITECTURES | 1070 | ARM/S5P EXYNOS ARM ARCHITECTURES |
1088 | M: Kukjin Kim <kgene.kim@samsung.com> | 1071 | M: Kukjin Kim <kgene.kim@samsung.com> |
@@ -4319,8 +4302,9 @@ F: include/linux/mm.h | |||
4319 | F: mm/ | 4302 | F: mm/ |
4320 | 4303 | ||
4321 | MEMORY RESOURCE CONTROLLER | 4304 | MEMORY RESOURCE CONTROLLER |
4305 | M: Johannes Weiner <hannes@cmpxchg.org> | ||
4306 | M: Michal Hocko <mhocko@suse.cz> | ||
4322 | M: Balbir Singh <bsingharora@gmail.com> | 4307 | M: Balbir Singh <bsingharora@gmail.com> |
4323 | M: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp> | ||
4324 | M: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> | 4308 | M: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> |
4325 | L: cgroups@vger.kernel.org | 4309 | L: cgroups@vger.kernel.org |
4326 | L: linux-mm@kvack.org | 4310 | L: linux-mm@kvack.org |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 3 | 1 | VERSION = 3 |
2 | PATCHLEVEL = 2 | 2 | PATCHLEVEL = 2 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = -rc4 | 4 | EXTRAVERSION = -rc5 |
5 | NAME = Saber-toothed Squirrel | 5 | NAME = Saber-toothed Squirrel |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig index a7e777581378..945a34f2a34d 100644 --- a/arch/arm/configs/omap1_defconfig +++ b/arch/arm/configs/omap1_defconfig | |||
@@ -48,12 +48,7 @@ CONFIG_MACH_SX1=y | |||
48 | CONFIG_MACH_NOKIA770=y | 48 | CONFIG_MACH_NOKIA770=y |
49 | CONFIG_MACH_AMS_DELTA=y | 49 | CONFIG_MACH_AMS_DELTA=y |
50 | CONFIG_MACH_OMAP_GENERIC=y | 50 | CONFIG_MACH_OMAP_GENERIC=y |
51 | CONFIG_OMAP_ARM_216MHZ=y | ||
52 | CONFIG_OMAP_ARM_195MHZ=y | ||
53 | CONFIG_OMAP_ARM_192MHZ=y | ||
54 | CONFIG_OMAP_ARM_182MHZ=y | 51 | CONFIG_OMAP_ARM_182MHZ=y |
55 | CONFIG_OMAP_ARM_168MHZ=y | ||
56 | # CONFIG_OMAP_ARM_60MHZ is not set | ||
57 | # CONFIG_ARM_THUMB is not set | 52 | # CONFIG_ARM_THUMB is not set |
58 | CONFIG_PCCARD=y | 53 | CONFIG_PCCARD=y |
59 | CONFIG_OMAP_CF=y | 54 | CONFIG_OMAP_CF=y |
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index c475379199b1..8e9c98edc068 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
@@ -353,15 +353,15 @@ validate_group(struct perf_event *event) | |||
353 | fake_pmu.used_mask = fake_used_mask; | 353 | fake_pmu.used_mask = fake_used_mask; |
354 | 354 | ||
355 | if (!validate_event(&fake_pmu, leader)) | 355 | if (!validate_event(&fake_pmu, leader)) |
356 | return -ENOSPC; | 356 | return -EINVAL; |
357 | 357 | ||
358 | list_for_each_entry(sibling, &leader->sibling_list, group_entry) { | 358 | list_for_each_entry(sibling, &leader->sibling_list, group_entry) { |
359 | if (!validate_event(&fake_pmu, sibling)) | 359 | if (!validate_event(&fake_pmu, sibling)) |
360 | return -ENOSPC; | 360 | return -EINVAL; |
361 | } | 361 | } |
362 | 362 | ||
363 | if (!validate_event(&fake_pmu, event)) | 363 | if (!validate_event(&fake_pmu, event)) |
364 | return -ENOSPC; | 364 | return -EINVAL; |
365 | 365 | ||
366 | return 0; | 366 | return 0; |
367 | } | 367 | } |
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 66591fa53e05..ad930688358c 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c | |||
@@ -83,7 +83,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {} | |||
83 | * USB Device (Gadget) | 83 | * USB Device (Gadget) |
84 | * -------------------------------------------------------------------- */ | 84 | * -------------------------------------------------------------------- */ |
85 | 85 | ||
86 | #ifdef CONFIG_USB_GADGET_AT91 | 86 | #ifdef CONFIG_USB_AT91 |
87 | static struct at91_udc_data udc_data; | 87 | static struct at91_udc_data udc_data; |
88 | 88 | ||
89 | static struct resource udc_resources[] = { | 89 | static struct resource udc_resources[] = { |
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index b84a9f642f59..0d20677fbef0 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c | |||
@@ -195,9 +195,9 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
195 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), | 195 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), |
196 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), | 196 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), |
197 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), | 197 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), |
198 | CLKDEV_CON_DEV_ID("t3_clk", "atmel_tcb.1", &tc3_clk), | 198 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk), |
199 | CLKDEV_CON_DEV_ID("t4_clk", "atmel_tcb.1", &tc4_clk), | 199 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), |
200 | CLKDEV_CON_DEV_ID("t5_clk", "atmel_tcb.1", &tc5_clk), | 200 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), |
201 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), | 201 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), |
202 | /* more usart lookup table for DT entries */ | 202 | /* more usart lookup table for DT entries */ |
203 | CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), | 203 | CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), |
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 25e3464fb07f..629fa9774972 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c | |||
@@ -84,7 +84,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {} | |||
84 | * USB Device (Gadget) | 84 | * USB Device (Gadget) |
85 | * -------------------------------------------------------------------- */ | 85 | * -------------------------------------------------------------------- */ |
86 | 86 | ||
87 | #ifdef CONFIG_USB_GADGET_AT91 | 87 | #ifdef CONFIG_USB_AT91 |
88 | static struct at91_udc_data udc_data; | 88 | static struct at91_udc_data udc_data; |
89 | 89 | ||
90 | static struct resource udc_resources[] = { | 90 | static struct resource udc_resources[] = { |
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index ae78f4d03b73..a178b58b0b9c 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c | |||
@@ -87,7 +87,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {} | |||
87 | * USB Device (Gadget) | 87 | * USB Device (Gadget) |
88 | * -------------------------------------------------------------------- */ | 88 | * -------------------------------------------------------------------- */ |
89 | 89 | ||
90 | #ifdef CONFIG_USB_GADGET_AT91 | 90 | #ifdef CONFIG_USB_AT91 |
91 | static struct at91_udc_data udc_data; | 91 | static struct at91_udc_data udc_data; |
92 | 92 | ||
93 | static struct resource udc_resources[] = { | 93 | static struct resource udc_resources[] = { |
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index ad017eb1f8df..d5fbac9ff4fa 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c | |||
@@ -92,7 +92,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {} | |||
92 | * USB Device (Gadget) | 92 | * USB Device (Gadget) |
93 | * -------------------------------------------------------------------- */ | 93 | * -------------------------------------------------------------------- */ |
94 | 94 | ||
95 | #ifdef CONFIG_USB_GADGET_AT91 | 95 | #ifdef CONFIG_USB_AT91 |
96 | static struct at91_udc_data udc_data; | 96 | static struct at91_udc_data udc_data; |
97 | 97 | ||
98 | static struct resource udc_resources[] = { | 98 | static struct resource udc_resources[] = { |
diff --git a/arch/arm/mach-at91/include/mach/system_rev.h b/arch/arm/mach-at91/include/mach/system_rev.h index 8f4866045b41..ec164a4124c9 100644 --- a/arch/arm/mach-at91/include/mach/system_rev.h +++ b/arch/arm/mach-at91/include/mach/system_rev.h | |||
@@ -19,7 +19,7 @@ | |||
19 | #define BOARD_HAVE_NAND_16BIT (1 << 31) | 19 | #define BOARD_HAVE_NAND_16BIT (1 << 31) |
20 | static inline int board_have_nand_16bit(void) | 20 | static inline int board_have_nand_16bit(void) |
21 | { | 21 | { |
22 | return system_rev & BOARD_HAVE_NAND_16BIT; | 22 | return (system_rev & BOARD_HAVE_NAND_16BIT) ? 1 : 0; |
23 | } | 23 | } |
24 | 24 | ||
25 | #endif /* __ARCH_SYSTEM_REV_H__ */ | 25 | #endif /* __ARCH_SYSTEM_REV_H__ */ |
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 1d7d24995226..6659a90dbcad 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c | |||
@@ -753,7 +753,7 @@ static struct snd_platform_data da850_evm_snd_data = { | |||
753 | .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), | 753 | .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), |
754 | .tdm_slots = 2, | 754 | .tdm_slots = 2, |
755 | .serial_dir = da850_iis_serializer_direction, | 755 | .serial_dir = da850_iis_serializer_direction, |
756 | .asp_chan_q = EVENTQ_1, | 756 | .asp_chan_q = EVENTQ_0, |
757 | .version = MCASP_VERSION_2, | 757 | .version = MCASP_VERSION_2, |
758 | .txnumevt = 1, | 758 | .txnumevt = 1, |
759 | .rxnumevt = 1, | 759 | .rxnumevt = 1, |
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 1918ae711428..46e1f4173b97 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c | |||
@@ -107,7 +107,7 @@ static struct mtd_partition davinci_nand_partitions[] = { | |||
107 | /* UBL (a few copies) plus U-Boot */ | 107 | /* UBL (a few copies) plus U-Boot */ |
108 | .name = "bootloader", | 108 | .name = "bootloader", |
109 | .offset = 0, | 109 | .offset = 0, |
110 | .size = 28 * NAND_BLOCK_SIZE, | 110 | .size = 30 * NAND_BLOCK_SIZE, |
111 | .mask_flags = MTD_WRITEABLE, /* force read-only */ | 111 | .mask_flags = MTD_WRITEABLE, /* force read-only */ |
112 | }, { | 112 | }, { |
113 | /* U-Boot environment */ | 113 | /* U-Boot environment */ |
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index e574d7f837a8..635bf7740157 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c | |||
@@ -564,7 +564,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) | |||
564 | int val; | 564 | int val; |
565 | u32 value; | 565 | u32 value; |
566 | 566 | ||
567 | if (!vpif_vsclkdis_reg || !cpld_client) | 567 | if (!vpif_vidclkctl_reg || !cpld_client) |
568 | return -ENXIO; | 568 | return -ENXIO; |
569 | 569 | ||
570 | val = i2c_smbus_read_byte(cpld_client); | 570 | val = i2c_smbus_read_byte(cpld_client); |
@@ -572,7 +572,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) | |||
572 | return val; | 572 | return val; |
573 | 573 | ||
574 | spin_lock_irqsave(&vpif_reg_lock, flags); | 574 | spin_lock_irqsave(&vpif_reg_lock, flags); |
575 | value = __raw_readl(vpif_vsclkdis_reg); | 575 | value = __raw_readl(vpif_vidclkctl_reg); |
576 | if (mux_mode) { | 576 | if (mux_mode) { |
577 | val &= VPIF_INPUT_TWO_CHANNEL; | 577 | val &= VPIF_INPUT_TWO_CHANNEL; |
578 | value |= VIDCH1CLK; | 578 | value |= VIDCH1CLK; |
@@ -580,7 +580,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) | |||
580 | val |= VPIF_INPUT_ONE_CHANNEL; | 580 | val |= VPIF_INPUT_ONE_CHANNEL; |
581 | value &= ~VIDCH1CLK; | 581 | value &= ~VIDCH1CLK; |
582 | } | 582 | } |
583 | __raw_writel(value, vpif_vsclkdis_reg); | 583 | __raw_writel(value, vpif_vidclkctl_reg); |
584 | spin_unlock_irqrestore(&vpif_reg_lock, flags); | 584 | spin_unlock_irqrestore(&vpif_reg_lock, flags); |
585 | 585 | ||
586 | err = i2c_smbus_write_byte(cpld_client, val); | 586 | err = i2c_smbus_write_byte(cpld_client, val); |
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 0b68ed534f8e..af27c130595f 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c | |||
@@ -161,7 +161,6 @@ static struct clk dsp_clk = { | |||
161 | .name = "dsp", | 161 | .name = "dsp", |
162 | .parent = &pll1_sysclk1, | 162 | .parent = &pll1_sysclk1, |
163 | .lpsc = DM646X_LPSC_C64X_CPU, | 163 | .lpsc = DM646X_LPSC_C64X_CPU, |
164 | .flags = PSC_DSP, | ||
165 | .usecount = 1, /* REVISIT how to disable? */ | 164 | .usecount = 1, /* REVISIT how to disable? */ |
166 | }; | 165 | }; |
167 | 166 | ||
diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index fa59c097223d..8bc3fc256171 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h | |||
@@ -233,7 +233,7 @@ | |||
233 | #define PTCMD 0x120 | 233 | #define PTCMD 0x120 |
234 | #define PTSTAT 0x128 | 234 | #define PTSTAT 0x128 |
235 | #define PDSTAT 0x200 | 235 | #define PDSTAT 0x200 |
236 | #define PDCTL1 0x304 | 236 | #define PDCTL 0x300 |
237 | #define MDSTAT 0x800 | 237 | #define MDSTAT 0x800 |
238 | #define MDCTL 0xA00 | 238 | #define MDCTL 0xA00 |
239 | 239 | ||
@@ -244,7 +244,10 @@ | |||
244 | #define PSC_STATE_ENABLE 3 | 244 | #define PSC_STATE_ENABLE 3 |
245 | 245 | ||
246 | #define MDSTAT_STATE_MASK 0x3f | 246 | #define MDSTAT_STATE_MASK 0x3f |
247 | #define PDSTAT_STATE_MASK 0x1f | ||
247 | #define MDCTL_FORCE BIT(31) | 248 | #define MDCTL_FORCE BIT(31) |
249 | #define PDCTL_NEXT BIT(1) | ||
250 | #define PDCTL_EPCGOOD BIT(8) | ||
248 | 251 | ||
249 | #ifndef __ASSEMBLER__ | 252 | #ifndef __ASSEMBLER__ |
250 | 253 | ||
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c index 1fb6bdff38c1..d7e210f4b55c 100644 --- a/arch/arm/mach-davinci/psc.c +++ b/arch/arm/mach-davinci/psc.c | |||
@@ -52,7 +52,7 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) | |||
52 | void davinci_psc_config(unsigned int domain, unsigned int ctlr, | 52 | void davinci_psc_config(unsigned int domain, unsigned int ctlr, |
53 | unsigned int id, bool enable, u32 flags) | 53 | unsigned int id, bool enable, u32 flags) |
54 | { | 54 | { |
55 | u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl; | 55 | u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl; |
56 | void __iomem *psc_base; | 56 | void __iomem *psc_base; |
57 | struct davinci_soc_info *soc_info = &davinci_soc_info; | 57 | struct davinci_soc_info *soc_info = &davinci_soc_info; |
58 | u32 next_state = PSC_STATE_ENABLE; | 58 | u32 next_state = PSC_STATE_ENABLE; |
@@ -79,11 +79,11 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, | |||
79 | mdctl |= MDCTL_FORCE; | 79 | mdctl |= MDCTL_FORCE; |
80 | __raw_writel(mdctl, psc_base + MDCTL + 4 * id); | 80 | __raw_writel(mdctl, psc_base + MDCTL + 4 * id); |
81 | 81 | ||
82 | pdstat = __raw_readl(psc_base + PDSTAT); | 82 | pdstat = __raw_readl(psc_base + PDSTAT + 4 * domain); |
83 | if ((pdstat & 0x00000001) == 0) { | 83 | if ((pdstat & PDSTAT_STATE_MASK) == 0) { |
84 | pdctl1 = __raw_readl(psc_base + PDCTL1); | 84 | pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); |
85 | pdctl1 |= 0x1; | 85 | pdctl |= PDCTL_NEXT; |
86 | __raw_writel(pdctl1, psc_base + PDCTL1); | 86 | __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); |
87 | 87 | ||
88 | ptcmd = 1 << domain; | 88 | ptcmd = 1 << domain; |
89 | __raw_writel(ptcmd, psc_base + PTCMD); | 89 | __raw_writel(ptcmd, psc_base + PTCMD); |
@@ -92,9 +92,9 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, | |||
92 | epcpr = __raw_readl(psc_base + EPCPR); | 92 | epcpr = __raw_readl(psc_base + EPCPR); |
93 | } while ((((epcpr >> domain) & 1) == 0)); | 93 | } while ((((epcpr >> domain) & 1) == 0)); |
94 | 94 | ||
95 | pdctl1 = __raw_readl(psc_base + PDCTL1); | 95 | pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); |
96 | pdctl1 |= 0x100; | 96 | pdctl |= PDCTL_EPCGOOD; |
97 | __raw_writel(pdctl1, psc_base + PDCTL1); | 97 | __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); |
98 | } else { | 98 | } else { |
99 | ptcmd = 1 << domain; | 99 | ptcmd = 1 << domain; |
100 | __raw_writel(ptcmd, psc_base + PTCMD); | 100 | __raw_writel(ptcmd, psc_base + PTCMD); |
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 9cd860a27af5..8deb012189b5 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c | |||
@@ -37,14 +37,15 @@ static void __init imx6q_map_io(void) | |||
37 | imx6q_clock_map_io(); | 37 | imx6q_clock_map_io(); |
38 | } | 38 | } |
39 | 39 | ||
40 | static void __init imx6q_gpio_add_irq_domain(struct device_node *np, | 40 | static int __init imx6q_gpio_add_irq_domain(struct device_node *np, |
41 | struct device_node *interrupt_parent) | 41 | struct device_node *interrupt_parent) |
42 | { | 42 | { |
43 | static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS - | 43 | static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; |
44 | 32 * 7; /* imx6q gets 7 gpio ports */ | ||
45 | 44 | ||
45 | gpio_irq_base -= 32; | ||
46 | irq_domain_add_simple(np, gpio_irq_base); | 46 | irq_domain_add_simple(np, gpio_irq_base); |
47 | gpio_irq_base += 32; | 47 | |
48 | return 0; | ||
48 | } | 49 | } |
49 | 50 | ||
50 | static const struct of_device_id imx6q_irq_match[] __initconst = { | 51 | static const struct of_device_id imx6q_irq_match[] __initconst = { |
diff --git a/arch/arm/mach-msm/devices-iommu.c b/arch/arm/mach-msm/devices-iommu.c index 24030d0da6e3..0fb7a17df398 100644 --- a/arch/arm/mach-msm/devices-iommu.c +++ b/arch/arm/mach-msm/devices-iommu.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/bootmem.h> | 20 | #include <linux/bootmem.h> |
21 | #include <linux/module.h> | ||
21 | #include <mach/irqs.h> | 22 | #include <mach/irqs.h> |
22 | #include <mach/iommu.h> | 23 | #include <mach/iommu.h> |
23 | 24 | ||
diff --git a/arch/arm/mach-mx5/imx51-dt.c b/arch/arm/mach-mx5/imx51-dt.c index ccc61585659b..596edd967dbf 100644 --- a/arch/arm/mach-mx5/imx51-dt.c +++ b/arch/arm/mach-mx5/imx51-dt.c | |||
@@ -44,20 +44,22 @@ static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = { | |||
44 | { /* sentinel */ } | 44 | { /* sentinel */ } |
45 | }; | 45 | }; |
46 | 46 | ||
47 | static void __init imx51_tzic_add_irq_domain(struct device_node *np, | 47 | static int __init imx51_tzic_add_irq_domain(struct device_node *np, |
48 | struct device_node *interrupt_parent) | 48 | struct device_node *interrupt_parent) |
49 | { | 49 | { |
50 | irq_domain_add_simple(np, 0); | 50 | irq_domain_add_simple(np, 0); |
51 | return 0; | ||
51 | } | 52 | } |
52 | 53 | ||
53 | static void __init imx51_gpio_add_irq_domain(struct device_node *np, | 54 | static int __init imx51_gpio_add_irq_domain(struct device_node *np, |
54 | struct device_node *interrupt_parent) | 55 | struct device_node *interrupt_parent) |
55 | { | 56 | { |
56 | static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS - | 57 | static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; |
57 | 32 * 4; /* imx51 gets 4 gpio ports */ | ||
58 | 58 | ||
59 | gpio_irq_base -= 32; | ||
59 | irq_domain_add_simple(np, gpio_irq_base); | 60 | irq_domain_add_simple(np, gpio_irq_base); |
60 | gpio_irq_base += 32; | 61 | |
62 | return 0; | ||
61 | } | 63 | } |
62 | 64 | ||
63 | static const struct of_device_id imx51_irq_match[] __initconst = { | 65 | static const struct of_device_id imx51_irq_match[] __initconst = { |
diff --git a/arch/arm/mach-mx5/imx53-dt.c b/arch/arm/mach-mx5/imx53-dt.c index ccaa0b81b768..85bfd5ff21b0 100644 --- a/arch/arm/mach-mx5/imx53-dt.c +++ b/arch/arm/mach-mx5/imx53-dt.c | |||
@@ -48,20 +48,22 @@ static const struct of_dev_auxdata imx53_auxdata_lookup[] __initconst = { | |||
48 | { /* sentinel */ } | 48 | { /* sentinel */ } |
49 | }; | 49 | }; |
50 | 50 | ||
51 | static void __init imx53_tzic_add_irq_domain(struct device_node *np, | 51 | static int __init imx53_tzic_add_irq_domain(struct device_node *np, |
52 | struct device_node *interrupt_parent) | 52 | struct device_node *interrupt_parent) |
53 | { | 53 | { |
54 | irq_domain_add_simple(np, 0); | 54 | irq_domain_add_simple(np, 0); |
55 | return 0; | ||
55 | } | 56 | } |
56 | 57 | ||
57 | static void __init imx53_gpio_add_irq_domain(struct device_node *np, | 58 | static int __init imx53_gpio_add_irq_domain(struct device_node *np, |
58 | struct device_node *interrupt_parent) | 59 | struct device_node *interrupt_parent) |
59 | { | 60 | { |
60 | static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS - | 61 | static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; |
61 | 32 * 7; /* imx53 gets 7 gpio ports */ | ||
62 | 62 | ||
63 | gpio_irq_base -= 32; | ||
63 | irq_domain_add_simple(np, gpio_irq_base); | 64 | irq_domain_add_simple(np, gpio_irq_base); |
64 | gpio_irq_base += 32; | 65 | |
66 | return 0; | ||
65 | } | 67 | } |
66 | 68 | ||
67 | static const struct of_device_id imx53_irq_match[] __initconst = { | 69 | static const struct of_device_id imx53_irq_match[] __initconst = { |
diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h index 75d86118b76a..30c7990f3c01 100644 --- a/arch/arm/mach-mxs/include/mach/mx28.h +++ b/arch/arm/mach-mxs/include/mach/mx28.h | |||
@@ -104,8 +104,8 @@ | |||
104 | #define MX28_INT_CAN1 9 | 104 | #define MX28_INT_CAN1 9 |
105 | #define MX28_INT_LRADC_TOUCH 10 | 105 | #define MX28_INT_LRADC_TOUCH 10 |
106 | #define MX28_INT_HSADC 13 | 106 | #define MX28_INT_HSADC 13 |
107 | #define MX28_INT_IRADC_THRESH0 14 | 107 | #define MX28_INT_LRADC_THRESH0 14 |
108 | #define MX28_INT_IRADC_THRESH1 15 | 108 | #define MX28_INT_LRADC_THRESH1 15 |
109 | #define MX28_INT_LRADC_CH0 16 | 109 | #define MX28_INT_LRADC_CH0 16 |
110 | #define MX28_INT_LRADC_CH1 17 | 110 | #define MX28_INT_LRADC_CH1 17 |
111 | #define MX28_INT_LRADC_CH2 18 | 111 | #define MX28_INT_LRADC_CH2 18 |
diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h index 0d2d2b470998..bde5f6634747 100644 --- a/arch/arm/mach-mxs/include/mach/mxs.h +++ b/arch/arm/mach-mxs/include/mach/mxs.h | |||
@@ -30,6 +30,7 @@ | |||
30 | */ | 30 | */ |
31 | #define cpu_is_mx23() ( \ | 31 | #define cpu_is_mx23() ( \ |
32 | machine_is_mx23evk() || \ | 32 | machine_is_mx23evk() || \ |
33 | machine_is_stmp378x() || \ | ||
33 | 0) | 34 | 0) |
34 | #define cpu_is_mx28() ( \ | 35 | #define cpu_is_mx28() ( \ |
35 | machine_is_mx28evk() || \ | 36 | machine_is_mx28evk() || \ |
diff --git a/arch/arm/mach-mxs/mach-m28evk.c b/arch/arm/mach-mxs/mach-m28evk.c index 3b1681e4f49a..6b00577b7025 100644 --- a/arch/arm/mach-mxs/mach-m28evk.c +++ b/arch/arm/mach-mxs/mach-m28evk.c | |||
@@ -361,6 +361,6 @@ static struct sys_timer m28evk_timer = { | |||
361 | MACHINE_START(M28EVK, "DENX M28 EVK") | 361 | MACHINE_START(M28EVK, "DENX M28 EVK") |
362 | .map_io = mx28_map_io, | 362 | .map_io = mx28_map_io, |
363 | .init_irq = mx28_init_irq, | 363 | .init_irq = mx28_init_irq, |
364 | .init_machine = m28evk_init, | ||
365 | .timer = &m28evk_timer, | 364 | .timer = &m28evk_timer, |
365 | .init_machine = m28evk_init, | ||
366 | MACHINE_END | 366 | MACHINE_END |
diff --git a/arch/arm/mach-mxs/mach-stmp378x_devb.c b/arch/arm/mach-mxs/mach-stmp378x_devb.c index 177e53123a02..6834dea38c04 100644 --- a/arch/arm/mach-mxs/mach-stmp378x_devb.c +++ b/arch/arm/mach-mxs/mach-stmp378x_devb.c | |||
@@ -115,6 +115,6 @@ static struct sys_timer stmp378x_dvb_timer = { | |||
115 | MACHINE_START(STMP378X, "STMP378X") | 115 | MACHINE_START(STMP378X, "STMP378X") |
116 | .map_io = mx23_map_io, | 116 | .map_io = mx23_map_io, |
117 | .init_irq = mx23_init_irq, | 117 | .init_irq = mx23_init_irq, |
118 | .init_machine = stmp378x_dvb_init, | ||
119 | .timer = &stmp378x_dvb_timer, | 118 | .timer = &stmp378x_dvb_timer, |
119 | .init_machine = stmp378x_dvb_init, | ||
120 | MACHINE_END | 120 | MACHINE_END |
diff --git a/arch/arm/mach-mxs/module-tx28.c b/arch/arm/mach-mxs/module-tx28.c index 0fcff47009cf..9a7b08b2a925 100644 --- a/arch/arm/mach-mxs/module-tx28.c +++ b/arch/arm/mach-mxs/module-tx28.c | |||
@@ -66,11 +66,11 @@ static const iomux_cfg_t tx28_fec1_pads[] __initconst = { | |||
66 | MX28_PAD_ENET0_CRS__ENET1_RX_EN, | 66 | MX28_PAD_ENET0_CRS__ENET1_RX_EN, |
67 | }; | 67 | }; |
68 | 68 | ||
69 | static struct fec_platform_data tx28_fec0_data = { | 69 | static const struct fec_platform_data tx28_fec0_data __initconst = { |
70 | .phy = PHY_INTERFACE_MODE_RMII, | 70 | .phy = PHY_INTERFACE_MODE_RMII, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | static struct fec_platform_data tx28_fec1_data = { | 73 | static const struct fec_platform_data tx28_fec1_data __initconst = { |
74 | .phy = PHY_INTERFACE_MODE_RMII, | 74 | .phy = PHY_INTERFACE_MODE_RMII, |
75 | }; | 75 | }; |
76 | 76 | ||
diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index 1297bb58869c..9ff90a744a21 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c | |||
@@ -16,6 +16,8 @@ | |||
16 | 16 | ||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
19 | #include <linux/cpufreq.h> | ||
20 | #include <linux/delay.h> | ||
19 | #include <linux/io.h> | 21 | #include <linux/io.h> |
20 | 22 | ||
21 | #include <asm/mach-types.h> /* for machine_is_* */ | 23 | #include <asm/mach-types.h> /* for machine_is_* */ |
@@ -927,16 +929,22 @@ int __init omap1_clk_init(void) | |||
927 | 929 | ||
928 | void __init omap1_clk_late_init(void) | 930 | void __init omap1_clk_late_init(void) |
929 | { | 931 | { |
930 | if (ck_dpll1.rate >= OMAP1_DPLL1_SANE_VALUE) | 932 | unsigned long rate = ck_dpll1.rate; |
933 | |||
934 | if (rate >= OMAP1_DPLL1_SANE_VALUE) | ||
931 | return; | 935 | return; |
932 | 936 | ||
937 | /* System booting at unusable rate, force reprogramming of DPLL1 */ | ||
938 | ck_dpll1_p->rate = 0; | ||
939 | |||
933 | /* Find the highest supported frequency and enable it */ | 940 | /* Find the highest supported frequency and enable it */ |
934 | if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { | 941 | if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { |
935 | pr_err("System frequencies not set, using default. Check your config.\n"); | 942 | pr_err("System frequencies not set, using default. Check your config.\n"); |
936 | omap_writew(0x2290, DPLL_CTL); | 943 | omap_writew(0x2290, DPLL_CTL); |
937 | omap_writew(cpu_is_omap7xx() ? 0x3005 : 0x1005, ARM_CKCTL); | 944 | omap_writew(cpu_is_omap7xx() ? 0x2005 : 0x0005, ARM_CKCTL); |
938 | ck_dpll1.rate = OMAP1_DPLL1_SANE_VALUE; | 945 | ck_dpll1.rate = OMAP1_DPLL1_SANE_VALUE; |
939 | } | 946 | } |
940 | propagate_rate(&ck_dpll1); | 947 | propagate_rate(&ck_dpll1); |
941 | omap1_show_rates(); | 948 | omap1_show_rates(); |
949 | loops_per_jiffy = cpufreq_scale(loops_per_jiffy, rate, ck_dpll1.rate); | ||
942 | } | 950 | } |
diff --git a/arch/arm/mach-prima2/pm.c b/arch/arm/mach-prima2/pm.c index cb53160f6c5d..26ebb57719df 100644 --- a/arch/arm/mach-prima2/pm.c +++ b/arch/arm/mach-prima2/pm.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/suspend.h> | 10 | #include <linux/suspend.h> |
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/module.h> | ||
12 | #include <linux/of.h> | 13 | #include <linux/of.h> |
13 | #include <linux/of_address.h> | 14 | #include <linux/of_address.h> |
14 | #include <linux/of_device.h> | 15 | #include <linux/of_device.h> |
diff --git a/arch/arm/mach-prima2/prima2.c b/arch/arm/mach-prima2/prima2.c index ef555c041962..a12b689a8702 100644 --- a/arch/arm/mach-prima2/prima2.c +++ b/arch/arm/mach-prima2/prima2.c | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <asm/sizes.h> | ||
11 | #include <asm/mach-types.h> | 12 | #include <asm/mach-types.h> |
12 | #include <asm/mach/arch.h> | 13 | #include <asm/mach/arch.h> |
13 | #include <linux/of.h> | 14 | #include <linux/of.h> |
diff --git a/arch/arm/mach-s3c64xx/dev-spi.c b/arch/arm/mach-s3c64xx/dev-spi.c index 5e6b42089eb4..3341fd118723 100644 --- a/arch/arm/mach-s3c64xx/dev-spi.c +++ b/arch/arm/mach-s3c64xx/dev-spi.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/string.h> | 12 | #include <linux/string.h> |
13 | #include <linux/export.h> | ||
13 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
14 | #include <linux/dma-mapping.h> | 15 | #include <linux/dma-mapping.h> |
15 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
diff --git a/arch/arm/mach-s3c64xx/s3c6400.c b/arch/arm/mach-s3c64xx/s3c6400.c index 7a3bc32df425..51c00f2453c6 100644 --- a/arch/arm/mach-s3c64xx/s3c6400.c +++ b/arch/arm/mach-s3c64xx/s3c6400.c | |||
@@ -70,7 +70,7 @@ void __init s3c6400_init_irq(void) | |||
70 | s3c64xx_init_irq(~0 & ~(0xf << 5), ~0); | 70 | s3c64xx_init_irq(~0 & ~(0xf << 5), ~0); |
71 | } | 71 | } |
72 | 72 | ||
73 | struct sysdev_class s3c6400_sysclass = { | 73 | static struct sysdev_class s3c6400_sysclass = { |
74 | .name = "s3c6400-core", | 74 | .name = "s3c6400-core", |
75 | }; | 75 | }; |
76 | 76 | ||
diff --git a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c index 83d2afb79e9f..2cf80026c58d 100644 --- a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c +++ b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <plat/fb.h> | 20 | #include <plat/fb.h> |
21 | #include <plat/gpio-cfg.h> | 21 | #include <plat/gpio-cfg.h> |
22 | 22 | ||
23 | extern void s3c64xx_fb_gpio_setup_24bpp(void) | 23 | void s3c64xx_fb_gpio_setup_24bpp(void) |
24 | { | 24 | { |
25 | s3c_gpio_cfgrange_nopull(S3C64XX_GPI(0), 16, S3C_GPIO_SFN(2)); | 25 | s3c_gpio_cfgrange_nopull(S3C64XX_GPI(0), 16, S3C_GPIO_SFN(2)); |
26 | s3c_gpio_cfgrange_nopull(S3C64XX_GPJ(0), 12, S3C_GPIO_SFN(2)); | 26 | s3c_gpio_cfgrange_nopull(S3C64XX_GPJ(0), 12, S3C_GPIO_SFN(2)); |
diff --git a/arch/arm/mach-sa1100/Makefile.boot b/arch/arm/mach-sa1100/Makefile.boot index 5a616f6e5612..f7951aa04562 100644 --- a/arch/arm/mach-sa1100/Makefile.boot +++ b/arch/arm/mach-sa1100/Makefile.boot | |||
@@ -1,5 +1,5 @@ | |||
1 | ifeq ($(CONFIG_ARCH_SA1100),y) | 1 | ifeq ($(CONFIG_SA1111),y) |
2 | zreladdr-$(CONFIG_SA1111) += 0xc0208000 | 2 | zreladdr-y += 0xc0208000 |
3 | else | 3 | else |
4 | zreladdr-y += 0xc0008000 | 4 | zreladdr-y += 0xc0008000 |
5 | endif | 5 | endif |
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index 43f984e93970..303192fc9260 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h | |||
@@ -350,10 +350,12 @@ | |||
350 | #define __NR_clock_adjtime 342 | 350 | #define __NR_clock_adjtime 342 |
351 | #define __NR_syncfs 343 | 351 | #define __NR_syncfs 343 |
352 | #define __NR_setns 344 | 352 | #define __NR_setns 344 |
353 | #define __NR_process_vm_readv 345 | ||
354 | #define __NR_process_vm_writev 346 | ||
353 | 355 | ||
354 | #ifdef __KERNEL__ | 356 | #ifdef __KERNEL__ |
355 | 357 | ||
356 | #define NR_syscalls 345 | 358 | #define NR_syscalls 347 |
357 | 359 | ||
358 | #define __ARCH_WANT_IPC_PARSE_VERSION | 360 | #define __ARCH_WANT_IPC_PARSE_VERSION |
359 | #define __ARCH_WANT_OLD_READDIR | 361 | #define __ARCH_WANT_OLD_READDIR |
diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S index c468f2edaa85..ce827b376110 100644 --- a/arch/m68k/kernel/syscalltable.S +++ b/arch/m68k/kernel/syscalltable.S | |||
@@ -365,4 +365,6 @@ ENTRY(sys_call_table) | |||
365 | .long sys_clock_adjtime | 365 | .long sys_clock_adjtime |
366 | .long sys_syncfs | 366 | .long sys_syncfs |
367 | .long sys_setns | 367 | .long sys_setns |
368 | .long sys_process_vm_readv /* 345 */ | ||
369 | .long sys_process_vm_writev | ||
368 | 370 | ||
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index 4f2971bcf8e5..315fc0b250f8 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c | |||
@@ -623,7 +623,7 @@ static int mipspmu_event_init(struct perf_event *event) | |||
623 | if (!atomic_inc_not_zero(&active_events)) { | 623 | if (!atomic_inc_not_zero(&active_events)) { |
624 | if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) { | 624 | if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) { |
625 | atomic_dec(&active_events); | 625 | atomic_dec(&active_events); |
626 | return -ENOSPC; | 626 | return -EINVAL; |
627 | } | 627 | } |
628 | 628 | ||
629 | mutex_lock(&pmu_reserve_mutex); | 629 | mutex_lock(&pmu_reserve_mutex); |
@@ -732,15 +732,15 @@ static int validate_group(struct perf_event *event) | |||
732 | memset(&fake_cpuc, 0, sizeof(fake_cpuc)); | 732 | memset(&fake_cpuc, 0, sizeof(fake_cpuc)); |
733 | 733 | ||
734 | if (!validate_event(&fake_cpuc, leader)) | 734 | if (!validate_event(&fake_cpuc, leader)) |
735 | return -ENOSPC; | 735 | return -EINVAL; |
736 | 736 | ||
737 | list_for_each_entry(sibling, &leader->sibling_list, group_entry) { | 737 | list_for_each_entry(sibling, &leader->sibling_list, group_entry) { |
738 | if (!validate_event(&fake_cpuc, sibling)) | 738 | if (!validate_event(&fake_cpuc, sibling)) |
739 | return -ENOSPC; | 739 | return -EINVAL; |
740 | } | 740 | } |
741 | 741 | ||
742 | if (!validate_event(&fake_cpuc, event)) | 742 | if (!validate_event(&fake_cpuc, event)) |
743 | return -ENOSPC; | 743 | return -EINVAL; |
744 | 744 | ||
745 | return 0; | 745 | return 0; |
746 | } | 746 | } |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 524d23b8610c..4f289ff0b7fe 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -599,10 +599,10 @@ static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste) | |||
599 | skey = page_get_storage_key(address); | 599 | skey = page_get_storage_key(address); |
600 | bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED); | 600 | bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED); |
601 | /* Clear page changed & referenced bit in the storage key */ | 601 | /* Clear page changed & referenced bit in the storage key */ |
602 | if (bits) { | 602 | if (bits & _PAGE_CHANGED) |
603 | skey ^= bits; | 603 | page_set_storage_key(address, skey ^ bits, 1); |
604 | page_set_storage_key(address, skey, 1); | 604 | else if (bits) |
605 | } | 605 | page_reset_referenced(address); |
606 | /* Transfer page changed & referenced bit to guest bits in pgste */ | 606 | /* Transfer page changed & referenced bit to guest bits in pgste */ |
607 | pgste_val(pgste) |= bits << 48; /* RCP_GR_BIT & RCP_GC_BIT */ | 607 | pgste_val(pgste) |= bits << 48; /* RCP_GR_BIT & RCP_GC_BIT */ |
608 | /* Get host changed & referenced bits from pgste */ | 608 | /* Get host changed & referenced bits from pgste */ |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 450931a45b68..573bc29551ef 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -296,13 +296,6 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) | |||
296 | ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA)))) | 296 | ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA)))) |
297 | /* Invalid psw mask. */ | 297 | /* Invalid psw mask. */ |
298 | return -EINVAL; | 298 | return -EINVAL; |
299 | if (addr == (addr_t) &dummy->regs.psw.addr) | ||
300 | /* | ||
301 | * The debugger changed the instruction address, | ||
302 | * reset system call restart, see signal.c:do_signal | ||
303 | */ | ||
304 | task_thread_info(child)->system_call = 0; | ||
305 | |||
306 | *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data; | 299 | *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data; |
307 | 300 | ||
308 | } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) { | 301 | } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) { |
@@ -614,11 +607,6 @@ static int __poke_user_compat(struct task_struct *child, | |||
614 | /* Transfer 31 bit amode bit to psw mask. */ | 607 | /* Transfer 31 bit amode bit to psw mask. */ |
615 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_BA) | | 608 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_BA) | |
616 | (__u64)(tmp & PSW32_ADDR_AMODE); | 609 | (__u64)(tmp & PSW32_ADDR_AMODE); |
617 | /* | ||
618 | * The debugger changed the instruction address, | ||
619 | * reset system call restart, see signal.c:do_signal | ||
620 | */ | ||
621 | task_thread_info(child)->system_call = 0; | ||
622 | } else { | 610 | } else { |
623 | /* gpr 0-15 */ | 611 | /* gpr 0-15 */ |
624 | *(__u32*)((addr_t) ®s->psw + addr*2 + 4) = tmp; | 612 | *(__u32*)((addr_t) ®s->psw + addr*2 + 4) = tmp; |
@@ -905,6 +893,14 @@ static int s390_last_break_get(struct task_struct *target, | |||
905 | return 0; | 893 | return 0; |
906 | } | 894 | } |
907 | 895 | ||
896 | static int s390_last_break_set(struct task_struct *target, | ||
897 | const struct user_regset *regset, | ||
898 | unsigned int pos, unsigned int count, | ||
899 | const void *kbuf, const void __user *ubuf) | ||
900 | { | ||
901 | return 0; | ||
902 | } | ||
903 | |||
908 | #endif | 904 | #endif |
909 | 905 | ||
910 | static int s390_system_call_get(struct task_struct *target, | 906 | static int s390_system_call_get(struct task_struct *target, |
@@ -951,6 +947,7 @@ static const struct user_regset s390_regsets[] = { | |||
951 | .size = sizeof(long), | 947 | .size = sizeof(long), |
952 | .align = sizeof(long), | 948 | .align = sizeof(long), |
953 | .get = s390_last_break_get, | 949 | .get = s390_last_break_get, |
950 | .set = s390_last_break_set, | ||
954 | }, | 951 | }, |
955 | #endif | 952 | #endif |
956 | [REGSET_SYSTEM_CALL] = { | 953 | [REGSET_SYSTEM_CALL] = { |
@@ -1116,6 +1113,14 @@ static int s390_compat_last_break_get(struct task_struct *target, | |||
1116 | return 0; | 1113 | return 0; |
1117 | } | 1114 | } |
1118 | 1115 | ||
1116 | static int s390_compat_last_break_set(struct task_struct *target, | ||
1117 | const struct user_regset *regset, | ||
1118 | unsigned int pos, unsigned int count, | ||
1119 | const void *kbuf, const void __user *ubuf) | ||
1120 | { | ||
1121 | return 0; | ||
1122 | } | ||
1123 | |||
1119 | static const struct user_regset s390_compat_regsets[] = { | 1124 | static const struct user_regset s390_compat_regsets[] = { |
1120 | [REGSET_GENERAL] = { | 1125 | [REGSET_GENERAL] = { |
1121 | .core_note_type = NT_PRSTATUS, | 1126 | .core_note_type = NT_PRSTATUS, |
@@ -1139,6 +1144,7 @@ static const struct user_regset s390_compat_regsets[] = { | |||
1139 | .size = sizeof(long), | 1144 | .size = sizeof(long), |
1140 | .align = sizeof(long), | 1145 | .align = sizeof(long), |
1141 | .get = s390_compat_last_break_get, | 1146 | .get = s390_compat_last_break_get, |
1147 | .set = s390_compat_last_break_set, | ||
1142 | }, | 1148 | }, |
1143 | [REGSET_SYSTEM_CALL] = { | 1149 | [REGSET_SYSTEM_CALL] = { |
1144 | .core_note_type = NT_S390_SYSTEM_CALL, | 1150 | .core_note_type = NT_S390_SYSTEM_CALL, |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index e58a462949b1..e54c4ff8abaa 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -579,7 +579,7 @@ static unsigned long __init find_crash_base(unsigned long crash_size, | |||
579 | *msg = "first memory chunk must be at least crashkernel size"; | 579 | *msg = "first memory chunk must be at least crashkernel size"; |
580 | return 0; | 580 | return 0; |
581 | } | 581 | } |
582 | if (is_kdump_kernel() && (crash_size == OLDMEM_SIZE)) | 582 | if (OLDMEM_BASE && crash_size == OLDMEM_SIZE) |
583 | return OLDMEM_BASE; | 583 | return OLDMEM_BASE; |
584 | 584 | ||
585 | for (i = MEMORY_CHUNKS - 1; i >= 0; i--) { | 585 | for (i = MEMORY_CHUNKS - 1; i >= 0; i--) { |
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 05a85bc14c98..7f6f9f354545 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
@@ -460,9 +460,9 @@ void do_signal(struct pt_regs *regs) | |||
460 | regs->svc_code >> 16); | 460 | regs->svc_code >> 16); |
461 | break; | 461 | break; |
462 | } | 462 | } |
463 | /* No longer in a system call */ | ||
464 | clear_thread_flag(TIF_SYSCALL); | ||
465 | } | 463 | } |
464 | /* No longer in a system call */ | ||
465 | clear_thread_flag(TIF_SYSCALL); | ||
466 | 466 | ||
467 | if ((is_compat_task() ? | 467 | if ((is_compat_task() ? |
468 | handle_signal32(signr, &ka, &info, oldset, regs) : | 468 | handle_signal32(signr, &ka, &info, oldset, regs) : |
@@ -486,6 +486,7 @@ void do_signal(struct pt_regs *regs) | |||
486 | } | 486 | } |
487 | 487 | ||
488 | /* No handlers present - check for system call restart */ | 488 | /* No handlers present - check for system call restart */ |
489 | clear_thread_flag(TIF_SYSCALL); | ||
489 | if (current_thread_info()->system_call) { | 490 | if (current_thread_info()->system_call) { |
490 | regs->svc_code = current_thread_info()->system_call; | 491 | regs->svc_code = current_thread_info()->system_call; |
491 | switch (regs->gprs[2]) { | 492 | switch (regs->gprs[2]) { |
@@ -500,9 +501,6 @@ void do_signal(struct pt_regs *regs) | |||
500 | regs->gprs[2] = regs->orig_gpr2; | 501 | regs->gprs[2] = regs->orig_gpr2; |
501 | set_thread_flag(TIF_SYSCALL); | 502 | set_thread_flag(TIF_SYSCALL); |
502 | break; | 503 | break; |
503 | default: | ||
504 | clear_thread_flag(TIF_SYSCALL); | ||
505 | break; | ||
506 | } | 504 | } |
507 | } | 505 | } |
508 | 506 | ||
diff --git a/arch/tile/include/asm/irq.h b/arch/tile/include/asm/irq.h index 94e9a511de84..f80f8ceabc67 100644 --- a/arch/tile/include/asm/irq.h +++ b/arch/tile/include/asm/irq.h | |||
@@ -74,16 +74,6 @@ enum { | |||
74 | */ | 74 | */ |
75 | void tile_irq_activate(unsigned int irq, int tile_irq_type); | 75 | void tile_irq_activate(unsigned int irq, int tile_irq_type); |
76 | 76 | ||
77 | /* | ||
78 | * For onboard, non-PCI (e.g. TILE_IRQ_PERCPU) devices, drivers know | ||
79 | * how to use enable/disable_percpu_irq() to manage interrupts on each | ||
80 | * core. We can't use the generic enable/disable_irq() because they | ||
81 | * use a single reference count per irq, rather than per cpu per irq. | ||
82 | */ | ||
83 | void enable_percpu_irq(unsigned int irq); | ||
84 | void disable_percpu_irq(unsigned int irq); | ||
85 | |||
86 | |||
87 | void setup_irq_regs(void); | 77 | void setup_irq_regs(void); |
88 | 78 | ||
89 | #endif /* _ASM_TILE_IRQ_H */ | 79 | #endif /* _ASM_TILE_IRQ_H */ |
diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c index aa0134db2dd6..02e628065012 100644 --- a/arch/tile/kernel/irq.c +++ b/arch/tile/kernel/irq.c | |||
@@ -152,14 +152,13 @@ void tile_dev_intr(struct pt_regs *regs, int intnum) | |||
152 | * Remove an irq from the disabled mask. If we're in an interrupt | 152 | * Remove an irq from the disabled mask. If we're in an interrupt |
153 | * context, defer enabling the HW interrupt until we leave. | 153 | * context, defer enabling the HW interrupt until we leave. |
154 | */ | 154 | */ |
155 | void enable_percpu_irq(unsigned int irq) | 155 | static void tile_irq_chip_enable(struct irq_data *d) |
156 | { | 156 | { |
157 | get_cpu_var(irq_disable_mask) &= ~(1UL << irq); | 157 | get_cpu_var(irq_disable_mask) &= ~(1UL << d->irq); |
158 | if (__get_cpu_var(irq_depth) == 0) | 158 | if (__get_cpu_var(irq_depth) == 0) |
159 | unmask_irqs(1UL << irq); | 159 | unmask_irqs(1UL << d->irq); |
160 | put_cpu_var(irq_disable_mask); | 160 | put_cpu_var(irq_disable_mask); |
161 | } | 161 | } |
162 | EXPORT_SYMBOL(enable_percpu_irq); | ||
163 | 162 | ||
164 | /* | 163 | /* |
165 | * Add an irq to the disabled mask. We disable the HW interrupt | 164 | * Add an irq to the disabled mask. We disable the HW interrupt |
@@ -167,13 +166,12 @@ EXPORT_SYMBOL(enable_percpu_irq); | |||
167 | * in an interrupt context, the return path is careful to avoid | 166 | * in an interrupt context, the return path is careful to avoid |
168 | * unmasking a newly disabled interrupt. | 167 | * unmasking a newly disabled interrupt. |
169 | */ | 168 | */ |
170 | void disable_percpu_irq(unsigned int irq) | 169 | static void tile_irq_chip_disable(struct irq_data *d) |
171 | { | 170 | { |
172 | get_cpu_var(irq_disable_mask) |= (1UL << irq); | 171 | get_cpu_var(irq_disable_mask) |= (1UL << d->irq); |
173 | mask_irqs(1UL << irq); | 172 | mask_irqs(1UL << d->irq); |
174 | put_cpu_var(irq_disable_mask); | 173 | put_cpu_var(irq_disable_mask); |
175 | } | 174 | } |
176 | EXPORT_SYMBOL(disable_percpu_irq); | ||
177 | 175 | ||
178 | /* Mask an interrupt. */ | 176 | /* Mask an interrupt. */ |
179 | static void tile_irq_chip_mask(struct irq_data *d) | 177 | static void tile_irq_chip_mask(struct irq_data *d) |
@@ -209,6 +207,8 @@ static void tile_irq_chip_eoi(struct irq_data *d) | |||
209 | 207 | ||
210 | static struct irq_chip tile_irq_chip = { | 208 | static struct irq_chip tile_irq_chip = { |
211 | .name = "tile_irq_chip", | 209 | .name = "tile_irq_chip", |
210 | .irq_enable = tile_irq_chip_enable, | ||
211 | .irq_disable = tile_irq_chip_disable, | ||
212 | .irq_ack = tile_irq_chip_ack, | 212 | .irq_ack = tile_irq_chip_ack, |
213 | .irq_eoi = tile_irq_chip_eoi, | 213 | .irq_eoi = tile_irq_chip_eoi, |
214 | .irq_mask = tile_irq_chip_mask, | 214 | .irq_mask = tile_irq_chip_mask, |
diff --git a/arch/tile/kernel/pci-dma.c b/arch/tile/kernel/pci-dma.c index 658f2ce426a4..b3ed19f8779c 100644 --- a/arch/tile/kernel/pci-dma.c +++ b/arch/tile/kernel/pci-dma.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
17 | #include <linux/vmalloc.h> | 17 | #include <linux/vmalloc.h> |
18 | #include <linux/export.h> | ||
18 | #include <asm/tlbflush.h> | 19 | #include <asm/tlbflush.h> |
19 | #include <asm/homecache.h> | 20 | #include <asm/homecache.h> |
20 | 21 | ||
diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index 2a8014cb1ff5..9d610d3fb11e 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/uaccess.h> | 26 | #include <linux/uaccess.h> |
27 | #include <linux/export.h> | ||
27 | 28 | ||
28 | #include <asm/processor.h> | 29 | #include <asm/processor.h> |
29 | #include <asm/sections.h> | 30 | #include <asm/sections.h> |
diff --git a/arch/tile/kernel/sysfs.c b/arch/tile/kernel/sysfs.c index b671a86f4515..602908268093 100644 --- a/arch/tile/kernel/sysfs.c +++ b/arch/tile/kernel/sysfs.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/cpu.h> | 18 | #include <linux/cpu.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/smp.h> | 20 | #include <linux/smp.h> |
21 | #include <linux/stat.h> | ||
21 | #include <hv/hypervisor.h> | 22 | #include <hv/hypervisor.h> |
22 | 23 | ||
23 | /* Return a string queried from the hypervisor, truncated to page size. */ | 24 | /* Return a string queried from the hypervisor, truncated to page size. */ |
diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c index a87d2a859ba9..2a81d32de0da 100644 --- a/arch/tile/lib/exports.c +++ b/arch/tile/lib/exports.c | |||
@@ -39,6 +39,9 @@ EXPORT_SYMBOL(finv_user_asm); | |||
39 | EXPORT_SYMBOL(current_text_addr); | 39 | EXPORT_SYMBOL(current_text_addr); |
40 | EXPORT_SYMBOL(dump_stack); | 40 | EXPORT_SYMBOL(dump_stack); |
41 | 41 | ||
42 | /* arch/tile/kernel/head.S */ | ||
43 | EXPORT_SYMBOL(empty_zero_page); | ||
44 | |||
42 | /* arch/tile/lib/, various memcpy files */ | 45 | /* arch/tile/lib/, various memcpy files */ |
43 | EXPORT_SYMBOL(memcpy); | 46 | EXPORT_SYMBOL(memcpy); |
44 | EXPORT_SYMBOL(__copy_to_user_inatomic); | 47 | EXPORT_SYMBOL(__copy_to_user_inatomic); |
diff --git a/arch/tile/mm/homecache.c b/arch/tile/mm/homecache.c index cbe6f4f9eca3..1cc6ae477c98 100644 --- a/arch/tile/mm/homecache.c +++ b/arch/tile/mm/homecache.c | |||
@@ -449,9 +449,12 @@ void homecache_free_pages(unsigned long addr, unsigned int order) | |||
449 | VM_BUG_ON(!virt_addr_valid((void *)addr)); | 449 | VM_BUG_ON(!virt_addr_valid((void *)addr)); |
450 | page = virt_to_page((void *)addr); | 450 | page = virt_to_page((void *)addr); |
451 | if (put_page_testzero(page)) { | 451 | if (put_page_testzero(page)) { |
452 | int pages = (1 << order); | ||
453 | homecache_change_page_home(page, order, initial_page_home()); | 452 | homecache_change_page_home(page, order, initial_page_home()); |
454 | while (pages--) | 453 | if (order == 0) { |
455 | __free_page(page++); | 454 | free_hot_cold_page(page, 0); |
455 | } else { | ||
456 | init_page_count(page); | ||
457 | __free_pages(page, order); | ||
458 | } | ||
456 | } | 459 | } |
457 | } | 460 | } |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index cb9a1044a771..efb42949cc09 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -390,7 +390,7 @@ config X86_INTEL_CE | |||
390 | This option compiles in support for the CE4100 SOC for settop | 390 | This option compiles in support for the CE4100 SOC for settop |
391 | boxes and media devices. | 391 | boxes and media devices. |
392 | 392 | ||
393 | config X86_INTEL_MID | 393 | config X86_WANT_INTEL_MID |
394 | bool "Intel MID platform support" | 394 | bool "Intel MID platform support" |
395 | depends on X86_32 | 395 | depends on X86_32 |
396 | depends on X86_EXTENDED_PLATFORM | 396 | depends on X86_EXTENDED_PLATFORM |
@@ -399,7 +399,10 @@ config X86_INTEL_MID | |||
399 | systems which do not have the PCI legacy interfaces (Moorestown, | 399 | systems which do not have the PCI legacy interfaces (Moorestown, |
400 | Medfield). If you are building for a PC class system say N here. | 400 | Medfield). If you are building for a PC class system say N here. |
401 | 401 | ||
402 | if X86_INTEL_MID | 402 | if X86_WANT_INTEL_MID |
403 | |||
404 | config X86_INTEL_MID | ||
405 | bool | ||
403 | 406 | ||
404 | config X86_MRST | 407 | config X86_MRST |
405 | bool "Moorestown MID platform" | 408 | bool "Moorestown MID platform" |
@@ -411,6 +414,7 @@ config X86_MRST | |||
411 | select SPI | 414 | select SPI |
412 | select INTEL_SCU_IPC | 415 | select INTEL_SCU_IPC |
413 | select X86_PLATFORM_DEVICES | 416 | select X86_PLATFORM_DEVICES |
417 | select X86_INTEL_MID | ||
414 | ---help--- | 418 | ---help--- |
415 | Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin | 419 | Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin |
416 | Internet Device(MID) platform. Moorestown consists of two chips: | 420 | Internet Device(MID) platform. Moorestown consists of two chips: |
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h index 908b96957d88..c9547033e38e 100644 --- a/arch/x86/include/asm/e820.h +++ b/arch/x86/include/asm/e820.h | |||
@@ -53,6 +53,13 @@ | |||
53 | */ | 53 | */ |
54 | #define E820_RESERVED_KERN 128 | 54 | #define E820_RESERVED_KERN 128 |
55 | 55 | ||
56 | /* | ||
57 | * Address ranges that need to be mapped by the kernel direct | ||
58 | * mapping. This is used to make sure regions such as | ||
59 | * EFI_RUNTIME_SERVICES_DATA are directly mapped. See setup_arch(). | ||
60 | */ | ||
61 | #define E820_RESERVED_EFI 129 | ||
62 | |||
56 | #ifndef __ASSEMBLY__ | 63 | #ifndef __ASSEMBLY__ |
57 | #include <linux/types.h> | 64 | #include <linux/types.h> |
58 | struct e820entry { | 65 | struct e820entry { |
@@ -115,6 +122,7 @@ static inline void early_memtest(unsigned long start, unsigned long end) | |||
115 | } | 122 | } |
116 | #endif | 123 | #endif |
117 | 124 | ||
125 | extern unsigned long e820_end_pfn(unsigned long limit_pfn, unsigned type); | ||
118 | extern unsigned long e820_end_of_ram_pfn(void); | 126 | extern unsigned long e820_end_of_ram_pfn(void); |
119 | extern unsigned long e820_end_of_low_ram_pfn(void); | 127 | extern unsigned long e820_end_of_low_ram_pfn(void); |
120 | extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align); | 128 | extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align); |
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 7093e4a6a0bc..b8d8bfcd44a9 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h | |||
@@ -33,8 +33,6 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...); | |||
33 | #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \ | 33 | #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \ |
34 | efi_call_virt(f, a1, a2, a3, a4, a5, a6) | 34 | efi_call_virt(f, a1, a2, a3, a4, a5, a6) |
35 | 35 | ||
36 | #define efi_ioremap(addr, size, type) ioremap_cache(addr, size) | ||
37 | |||
38 | #else /* !CONFIG_X86_32 */ | 36 | #else /* !CONFIG_X86_32 */ |
39 | 37 | ||
40 | extern u64 efi_call0(void *fp); | 38 | extern u64 efi_call0(void *fp); |
@@ -84,9 +82,6 @@ extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3, | |||
84 | efi_call6((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ | 82 | efi_call6((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ |
85 | (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6)) | 83 | (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6)) |
86 | 84 | ||
87 | extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size, | ||
88 | u32 type); | ||
89 | |||
90 | #endif /* CONFIG_X86_32 */ | 85 | #endif /* CONFIG_X86_32 */ |
91 | 86 | ||
92 | extern int add_efi_memmap; | 87 | extern int add_efi_memmap; |
diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h index 4420993acc47..925b605eb5c6 100644 --- a/arch/x86/include/asm/intel_scu_ipc.h +++ b/arch/x86/include/asm/intel_scu_ipc.h | |||
@@ -3,11 +3,15 @@ | |||
3 | 3 | ||
4 | #include <linux/notifier.h> | 4 | #include <linux/notifier.h> |
5 | 5 | ||
6 | #define IPCMSG_VRTC 0xFA /* Set vRTC device */ | 6 | #define IPCMSG_WARM_RESET 0xF0 |
7 | 7 | #define IPCMSG_COLD_RESET 0xF1 | |
8 | /* Command id associated with message IPCMSG_VRTC */ | 8 | #define IPCMSG_SOFT_RESET 0xF2 |
9 | #define IPC_CMD_VRTC_SETTIME 1 /* Set time */ | 9 | #define IPCMSG_COLD_BOOT 0xF3 |
10 | #define IPC_CMD_VRTC_SETALARM 2 /* Set alarm */ | 10 | |
11 | #define IPCMSG_VRTC 0xFA /* Set vRTC device */ | ||
12 | /* Command id associated with message IPCMSG_VRTC */ | ||
13 | #define IPC_CMD_VRTC_SETTIME 1 /* Set time */ | ||
14 | #define IPC_CMD_VRTC_SETALARM 2 /* Set alarm */ | ||
11 | 15 | ||
12 | /* Read single register */ | 16 | /* Read single register */ |
13 | int intel_scu_ipc_ioread8(u16 addr, u8 *data); | 17 | int intel_scu_ipc_ioread8(u16 addr, u8 *data); |
diff --git a/arch/x86/include/asm/mrst.h b/arch/x86/include/asm/mrst.h index e6283129c821..93f79094c224 100644 --- a/arch/x86/include/asm/mrst.h +++ b/arch/x86/include/asm/mrst.h | |||
@@ -31,11 +31,20 @@ enum mrst_cpu_type { | |||
31 | }; | 31 | }; |
32 | 32 | ||
33 | extern enum mrst_cpu_type __mrst_cpu_chip; | 33 | extern enum mrst_cpu_type __mrst_cpu_chip; |
34 | |||
35 | #ifdef CONFIG_X86_INTEL_MID | ||
36 | |||
34 | static inline enum mrst_cpu_type mrst_identify_cpu(void) | 37 | static inline enum mrst_cpu_type mrst_identify_cpu(void) |
35 | { | 38 | { |
36 | return __mrst_cpu_chip; | 39 | return __mrst_cpu_chip; |
37 | } | 40 | } |
38 | 41 | ||
42 | #else /* !CONFIG_X86_INTEL_MID */ | ||
43 | |||
44 | #define mrst_identify_cpu() (0) | ||
45 | |||
46 | #endif /* !CONFIG_X86_INTEL_MID */ | ||
47 | |||
39 | enum mrst_timer_options { | 48 | enum mrst_timer_options { |
40 | MRST_TIMER_DEFAULT, | 49 | MRST_TIMER_DEFAULT, |
41 | MRST_TIMER_APBT_ONLY, | 50 | MRST_TIMER_APBT_ONLY, |
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 084ef95274cd..95203d40ffdd 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h | |||
@@ -169,7 +169,14 @@ static inline int wrmsr_safe(unsigned msr, unsigned low, unsigned high) | |||
169 | return native_write_msr_safe(msr, low, high); | 169 | return native_write_msr_safe(msr, low, high); |
170 | } | 170 | } |
171 | 171 | ||
172 | /* rdmsr with exception handling */ | 172 | /* |
173 | * rdmsr with exception handling. | ||
174 | * | ||
175 | * Please note that the exception handling works only after we've | ||
176 | * switched to the "smart" #GP handler in trap_init() which knows about | ||
177 | * exception tables - using this macro earlier than that causes machine | ||
178 | * hangs on boxes which do not implement the @msr in the first argument. | ||
179 | */ | ||
173 | #define rdmsr_safe(msr, p1, p2) \ | 180 | #define rdmsr_safe(msr, p1, p2) \ |
174 | ({ \ | 181 | ({ \ |
175 | int __err; \ | 182 | int __err; \ |
diff --git a/arch/x86/include/asm/timer.h b/arch/x86/include/asm/timer.h index fa7b9176b76c..431793e5d484 100644 --- a/arch/x86/include/asm/timer.h +++ b/arch/x86/include/asm/timer.h | |||
@@ -32,6 +32,22 @@ extern int no_timer_check; | |||
32 | * (mathieu.desnoyers@polymtl.ca) | 32 | * (mathieu.desnoyers@polymtl.ca) |
33 | * | 33 | * |
34 | * -johnstul@us.ibm.com "math is hard, lets go shopping!" | 34 | * -johnstul@us.ibm.com "math is hard, lets go shopping!" |
35 | * | ||
36 | * In: | ||
37 | * | ||
38 | * ns = cycles * cyc2ns_scale / SC | ||
39 | * | ||
40 | * Although we may still have enough bits to store the value of ns, | ||
41 | * in some cases, we may not have enough bits to store cycles * cyc2ns_scale, | ||
42 | * leading to an incorrect result. | ||
43 | * | ||
44 | * To avoid this, we can decompose 'cycles' into quotient and remainder | ||
45 | * of division by SC. Then, | ||
46 | * | ||
47 | * ns = (quot * SC + rem) * cyc2ns_scale / SC | ||
48 | * = quot * cyc2ns_scale + (rem * cyc2ns_scale) / SC | ||
49 | * | ||
50 | * - sqazi@google.com | ||
35 | */ | 51 | */ |
36 | 52 | ||
37 | DECLARE_PER_CPU(unsigned long, cyc2ns); | 53 | DECLARE_PER_CPU(unsigned long, cyc2ns); |
@@ -41,9 +57,14 @@ DECLARE_PER_CPU(unsigned long long, cyc2ns_offset); | |||
41 | 57 | ||
42 | static inline unsigned long long __cycles_2_ns(unsigned long long cyc) | 58 | static inline unsigned long long __cycles_2_ns(unsigned long long cyc) |
43 | { | 59 | { |
60 | unsigned long long quot; | ||
61 | unsigned long long rem; | ||
44 | int cpu = smp_processor_id(); | 62 | int cpu = smp_processor_id(); |
45 | unsigned long long ns = per_cpu(cyc2ns_offset, cpu); | 63 | unsigned long long ns = per_cpu(cyc2ns_offset, cpu); |
46 | ns += cyc * per_cpu(cyc2ns, cpu) >> CYC2NS_SCALE_FACTOR; | 64 | quot = (cyc >> CYC2NS_SCALE_FACTOR); |
65 | rem = cyc & ((1ULL << CYC2NS_SCALE_FACTOR) - 1); | ||
66 | ns += quot * per_cpu(cyc2ns, cpu) + | ||
67 | ((rem * per_cpu(cyc2ns, cpu)) >> CYC2NS_SCALE_FACTOR); | ||
47 | return ns; | 68 | return ns; |
48 | } | 69 | } |
49 | 70 | ||
diff --git a/arch/x86/include/asm/uv/uv_mmrs.h b/arch/x86/include/asm/uv/uv_mmrs.h index 10474fb1185d..cf1d73643f60 100644 --- a/arch/x86/include/asm/uv/uv_mmrs.h +++ b/arch/x86/include/asm/uv/uv_mmrs.h | |||
@@ -57,6 +57,7 @@ | |||
57 | 57 | ||
58 | #define UV1_HUB_PART_NUMBER 0x88a5 | 58 | #define UV1_HUB_PART_NUMBER 0x88a5 |
59 | #define UV2_HUB_PART_NUMBER 0x8eb8 | 59 | #define UV2_HUB_PART_NUMBER 0x8eb8 |
60 | #define UV2_HUB_PART_NUMBER_X 0x1111 | ||
60 | 61 | ||
61 | /* Compat: if this #define is present, UV headers support UV2 */ | 62 | /* Compat: if this #define is present, UV headers support UV2 */ |
62 | #define UV2_HUB_IS_SUPPORTED 1 | 63 | #define UV2_HUB_IS_SUPPORTED 1 |
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 62ae3001ae02..9d59bbacd4e3 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -93,6 +93,8 @@ static int __init early_get_pnodeid(void) | |||
93 | 93 | ||
94 | if (node_id.s.part_number == UV2_HUB_PART_NUMBER) | 94 | if (node_id.s.part_number == UV2_HUB_PART_NUMBER) |
95 | uv_min_hub_revision_id += UV2_HUB_REVISION_BASE - 1; | 95 | uv_min_hub_revision_id += UV2_HUB_REVISION_BASE - 1; |
96 | if (node_id.s.part_number == UV2_HUB_PART_NUMBER_X) | ||
97 | uv_min_hub_revision_id += UV2_HUB_REVISION_BASE - 1; | ||
96 | 98 | ||
97 | uv_hub_info->hub_revision = uv_min_hub_revision_id; | 99 | uv_hub_info->hub_revision = uv_min_hub_revision_id; |
98 | pnode = (node_id.s.node_id >> 1) & ((1 << m_n_config.s.n_skt) - 1); | 100 | pnode = (node_id.s.node_id >> 1) & ((1 << m_n_config.s.n_skt) - 1); |
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index a71efcdbb092..97b26356e9ee 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c | |||
@@ -547,6 +547,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, | |||
547 | 547 | ||
548 | if (tmp != mask_lo) { | 548 | if (tmp != mask_lo) { |
549 | printk(KERN_WARNING "mtrr: your BIOS has configured an incorrect mask, fixing it.\n"); | 549 | printk(KERN_WARNING "mtrr: your BIOS has configured an incorrect mask, fixing it.\n"); |
550 | add_taint(TAINT_FIRMWARE_WORKAROUND); | ||
550 | mask_lo = tmp; | 551 | mask_lo = tmp; |
551 | } | 552 | } |
552 | } | 553 | } |
@@ -693,6 +694,7 @@ static void prepare_set(void) __acquires(set_atomicity_lock) | |||
693 | 694 | ||
694 | /* Disable MTRRs, and set the default type to uncached */ | 695 | /* Disable MTRRs, and set the default type to uncached */ |
695 | mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi); | 696 | mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi); |
697 | wbinvd(); | ||
696 | } | 698 | } |
697 | 699 | ||
698 | static void post_set(void) __releases(set_atomicity_lock) | 700 | static void post_set(void) __releases(set_atomicity_lock) |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 640891014b2a..2bda212a0010 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -312,12 +312,8 @@ int x86_setup_perfctr(struct perf_event *event) | |||
312 | return -EOPNOTSUPP; | 312 | return -EOPNOTSUPP; |
313 | } | 313 | } |
314 | 314 | ||
315 | /* | ||
316 | * Do not allow config1 (extended registers) to propagate, | ||
317 | * there's no sane user-space generalization yet: | ||
318 | */ | ||
319 | if (attr->type == PERF_TYPE_RAW) | 315 | if (attr->type == PERF_TYPE_RAW) |
320 | return 0; | 316 | return x86_pmu_extra_regs(event->attr.config, event); |
321 | 317 | ||
322 | if (attr->type == PERF_TYPE_HW_CACHE) | 318 | if (attr->type == PERF_TYPE_HW_CACHE) |
323 | return set_ext_hw_attr(hwc, event); | 319 | return set_ext_hw_attr(hwc, event); |
@@ -588,7 +584,7 @@ done: | |||
588 | x86_pmu.put_event_constraints(cpuc, cpuc->event_list[i]); | 584 | x86_pmu.put_event_constraints(cpuc, cpuc->event_list[i]); |
589 | } | 585 | } |
590 | } | 586 | } |
591 | return num ? -ENOSPC : 0; | 587 | return num ? -EINVAL : 0; |
592 | } | 588 | } |
593 | 589 | ||
594 | /* | 590 | /* |
@@ -607,7 +603,7 @@ static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader, | |||
607 | 603 | ||
608 | if (is_x86_event(leader)) { | 604 | if (is_x86_event(leader)) { |
609 | if (n >= max_count) | 605 | if (n >= max_count) |
610 | return -ENOSPC; | 606 | return -EINVAL; |
611 | cpuc->event_list[n] = leader; | 607 | cpuc->event_list[n] = leader; |
612 | n++; | 608 | n++; |
613 | } | 609 | } |
@@ -620,7 +616,7 @@ static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader, | |||
620 | continue; | 616 | continue; |
621 | 617 | ||
622 | if (n >= max_count) | 618 | if (n >= max_count) |
623 | return -ENOSPC; | 619 | return -EINVAL; |
624 | 620 | ||
625 | cpuc->event_list[n] = event; | 621 | cpuc->event_list[n] = event; |
626 | n++; | 622 | n++; |
@@ -1316,7 +1312,7 @@ static int validate_event(struct perf_event *event) | |||
1316 | c = x86_pmu.get_event_constraints(fake_cpuc, event); | 1312 | c = x86_pmu.get_event_constraints(fake_cpuc, event); |
1317 | 1313 | ||
1318 | if (!c || !c->weight) | 1314 | if (!c || !c->weight) |
1319 | ret = -ENOSPC; | 1315 | ret = -EINVAL; |
1320 | 1316 | ||
1321 | if (x86_pmu.put_event_constraints) | 1317 | if (x86_pmu.put_event_constraints) |
1322 | x86_pmu.put_event_constraints(fake_cpuc, event); | 1318 | x86_pmu.put_event_constraints(fake_cpuc, event); |
@@ -1341,7 +1337,7 @@ static int validate_group(struct perf_event *event) | |||
1341 | { | 1337 | { |
1342 | struct perf_event *leader = event->group_leader; | 1338 | struct perf_event *leader = event->group_leader; |
1343 | struct cpu_hw_events *fake_cpuc; | 1339 | struct cpu_hw_events *fake_cpuc; |
1344 | int ret = -ENOSPC, n; | 1340 | int ret = -EINVAL, n; |
1345 | 1341 | ||
1346 | fake_cpuc = allocate_fake_cpuc(); | 1342 | fake_cpuc = allocate_fake_cpuc(); |
1347 | if (IS_ERR(fake_cpuc)) | 1343 | if (IS_ERR(fake_cpuc)) |
diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c index ab6343d21825..3b8a2d30d14e 100644 --- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c +++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c | |||
@@ -199,8 +199,7 @@ static int force_ibs_eilvt_setup(void) | |||
199 | goto out; | 199 | goto out; |
200 | } | 200 | } |
201 | 201 | ||
202 | pr_err(FW_BUG "using offset %d for IBS interrupts\n", offset); | 202 | pr_info("IBS: LVT offset %d assigned\n", offset); |
203 | pr_err(FW_BUG "workaround enabled for IBS LVT offset\n"); | ||
204 | 203 | ||
205 | return 0; | 204 | return 0; |
206 | out: | 205 | out: |
@@ -265,19 +264,23 @@ perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void *h | |||
265 | static __init int amd_ibs_init(void) | 264 | static __init int amd_ibs_init(void) |
266 | { | 265 | { |
267 | u32 caps; | 266 | u32 caps; |
268 | int ret; | 267 | int ret = -EINVAL; |
269 | 268 | ||
270 | caps = __get_ibs_caps(); | 269 | caps = __get_ibs_caps(); |
271 | if (!caps) | 270 | if (!caps) |
272 | return -ENODEV; /* ibs not supported by the cpu */ | 271 | return -ENODEV; /* ibs not supported by the cpu */ |
273 | 272 | ||
274 | if (!ibs_eilvt_valid()) { | 273 | /* |
275 | ret = force_ibs_eilvt_setup(); | 274 | * Force LVT offset assignment for family 10h: The offsets are |
276 | if (ret) { | 275 | * not assigned by the BIOS for this family, so the OS is |
277 | pr_err("Failed to setup IBS, %d\n", ret); | 276 | * responsible for doing it. If the OS assignment fails, fall |
278 | return ret; | 277 | * back to BIOS settings and try to setup this. |
279 | } | 278 | */ |
280 | } | 279 | if (boot_cpu_data.x86 == 0x10) |
280 | force_ibs_eilvt_setup(); | ||
281 | |||
282 | if (!ibs_eilvt_valid()) | ||
283 | goto out; | ||
281 | 284 | ||
282 | get_online_cpus(); | 285 | get_online_cpus(); |
283 | ibs_caps = caps; | 286 | ibs_caps = caps; |
@@ -287,7 +290,11 @@ static __init int amd_ibs_init(void) | |||
287 | smp_call_function(setup_APIC_ibs, NULL, 1); | 290 | smp_call_function(setup_APIC_ibs, NULL, 1); |
288 | put_online_cpus(); | 291 | put_online_cpus(); |
289 | 292 | ||
290 | return perf_event_ibs_init(); | 293 | ret = perf_event_ibs_init(); |
294 | out: | ||
295 | if (ret) | ||
296 | pr_err("Failed to setup IBS, %d\n", ret); | ||
297 | return ret; | ||
291 | } | 298 | } |
292 | 299 | ||
293 | /* Since we need the pci subsystem to init ibs we can't do this earlier: */ | 300 | /* Since we need the pci subsystem to init ibs we can't do this earlier: */ |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 2be5ebe99872..8d601b18bf9f 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -1545,6 +1545,13 @@ static void intel_clovertown_quirks(void) | |||
1545 | x86_pmu.pebs_constraints = NULL; | 1545 | x86_pmu.pebs_constraints = NULL; |
1546 | } | 1546 | } |
1547 | 1547 | ||
1548 | static void intel_sandybridge_quirks(void) | ||
1549 | { | ||
1550 | printk(KERN_WARNING "PEBS disabled due to CPU errata.\n"); | ||
1551 | x86_pmu.pebs = 0; | ||
1552 | x86_pmu.pebs_constraints = NULL; | ||
1553 | } | ||
1554 | |||
1548 | __init int intel_pmu_init(void) | 1555 | __init int intel_pmu_init(void) |
1549 | { | 1556 | { |
1550 | union cpuid10_edx edx; | 1557 | union cpuid10_edx edx; |
@@ -1694,6 +1701,7 @@ __init int intel_pmu_init(void) | |||
1694 | break; | 1701 | break; |
1695 | 1702 | ||
1696 | case 42: /* SandyBridge */ | 1703 | case 42: /* SandyBridge */ |
1704 | x86_pmu.quirks = intel_sandybridge_quirks; | ||
1697 | case 45: /* SandyBridge, "Romely-EP" */ | 1705 | case 45: /* SandyBridge, "Romely-EP" */ |
1698 | memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, | 1706 | memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, |
1699 | sizeof(hw_cache_event_ids)); | 1707 | sizeof(hw_cache_event_ids)); |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index c0d238f49db8..73da6b64f5b7 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c | |||
@@ -493,6 +493,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) | |||
493 | unsigned long from = cpuc->lbr_entries[0].from; | 493 | unsigned long from = cpuc->lbr_entries[0].from; |
494 | unsigned long old_to, to = cpuc->lbr_entries[0].to; | 494 | unsigned long old_to, to = cpuc->lbr_entries[0].to; |
495 | unsigned long ip = regs->ip; | 495 | unsigned long ip = regs->ip; |
496 | int is_64bit = 0; | ||
496 | 497 | ||
497 | /* | 498 | /* |
498 | * We don't need to fixup if the PEBS assist is fault like | 499 | * We don't need to fixup if the PEBS assist is fault like |
@@ -544,7 +545,10 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) | |||
544 | } else | 545 | } else |
545 | kaddr = (void *)to; | 546 | kaddr = (void *)to; |
546 | 547 | ||
547 | kernel_insn_init(&insn, kaddr); | 548 | #ifdef CONFIG_X86_64 |
549 | is_64bit = kernel_ip(to) || !test_thread_flag(TIF_IA32); | ||
550 | #endif | ||
551 | insn_init(&insn, kaddr, is_64bit); | ||
548 | insn_get_length(&insn); | 552 | insn_get_length(&insn); |
549 | to += insn.length; | 553 | to += insn.length; |
550 | } while (to < ip); | 554 | } while (to < ip); |
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 492bf1358a7c..ef484d9d0a25 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c | |||
@@ -1268,7 +1268,7 @@ reserve: | |||
1268 | } | 1268 | } |
1269 | 1269 | ||
1270 | done: | 1270 | done: |
1271 | return num ? -ENOSPC : 0; | 1271 | return num ? -EINVAL : 0; |
1272 | } | 1272 | } |
1273 | 1273 | ||
1274 | static __initconst const struct x86_pmu p4_pmu = { | 1274 | static __initconst const struct x86_pmu p4_pmu = { |
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 303a0e48f076..65ffd110a81b 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
@@ -135,6 +135,7 @@ static void __init e820_print_type(u32 type) | |||
135 | printk(KERN_CONT "(usable)"); | 135 | printk(KERN_CONT "(usable)"); |
136 | break; | 136 | break; |
137 | case E820_RESERVED: | 137 | case E820_RESERVED: |
138 | case E820_RESERVED_EFI: | ||
138 | printk(KERN_CONT "(reserved)"); | 139 | printk(KERN_CONT "(reserved)"); |
139 | break; | 140 | break; |
140 | case E820_ACPI: | 141 | case E820_ACPI: |
@@ -783,7 +784,7 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align) | |||
783 | /* | 784 | /* |
784 | * Find the highest page frame number we have available | 785 | * Find the highest page frame number we have available |
785 | */ | 786 | */ |
786 | static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type) | 787 | unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type) |
787 | { | 788 | { |
788 | int i; | 789 | int i; |
789 | unsigned long last_pfn = 0; | 790 | unsigned long last_pfn = 0; |
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index b946a9eac7d9..1bb0bf4d92cd 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -1049,6 +1049,14 @@ int hpet_rtc_timer_init(void) | |||
1049 | } | 1049 | } |
1050 | EXPORT_SYMBOL_GPL(hpet_rtc_timer_init); | 1050 | EXPORT_SYMBOL_GPL(hpet_rtc_timer_init); |
1051 | 1051 | ||
1052 | static void hpet_disable_rtc_channel(void) | ||
1053 | { | ||
1054 | unsigned long cfg; | ||
1055 | cfg = hpet_readl(HPET_T1_CFG); | ||
1056 | cfg &= ~HPET_TN_ENABLE; | ||
1057 | hpet_writel(cfg, HPET_T1_CFG); | ||
1058 | } | ||
1059 | |||
1052 | /* | 1060 | /* |
1053 | * The functions below are called from rtc driver. | 1061 | * The functions below are called from rtc driver. |
1054 | * Return 0 if HPET is not being used. | 1062 | * Return 0 if HPET is not being used. |
@@ -1060,6 +1068,9 @@ int hpet_mask_rtc_irq_bit(unsigned long bit_mask) | |||
1060 | return 0; | 1068 | return 0; |
1061 | 1069 | ||
1062 | hpet_rtc_flags &= ~bit_mask; | 1070 | hpet_rtc_flags &= ~bit_mask; |
1071 | if (unlikely(!hpet_rtc_flags)) | ||
1072 | hpet_disable_rtc_channel(); | ||
1073 | |||
1063 | return 1; | 1074 | return 1; |
1064 | } | 1075 | } |
1065 | EXPORT_SYMBOL_GPL(hpet_mask_rtc_irq_bit); | 1076 | EXPORT_SYMBOL_GPL(hpet_mask_rtc_irq_bit); |
@@ -1125,15 +1136,11 @@ EXPORT_SYMBOL_GPL(hpet_rtc_dropped_irq); | |||
1125 | 1136 | ||
1126 | static void hpet_rtc_timer_reinit(void) | 1137 | static void hpet_rtc_timer_reinit(void) |
1127 | { | 1138 | { |
1128 | unsigned int cfg, delta; | 1139 | unsigned int delta; |
1129 | int lost_ints = -1; | 1140 | int lost_ints = -1; |
1130 | 1141 | ||
1131 | if (unlikely(!hpet_rtc_flags)) { | 1142 | if (unlikely(!hpet_rtc_flags)) |
1132 | cfg = hpet_readl(HPET_T1_CFG); | 1143 | hpet_disable_rtc_channel(); |
1133 | cfg &= ~HPET_TN_ENABLE; | ||
1134 | hpet_writel(cfg, HPET_T1_CFG); | ||
1135 | return; | ||
1136 | } | ||
1137 | 1144 | ||
1138 | if (!(hpet_rtc_flags & RTC_PIE) || hpet_pie_limit) | 1145 | if (!(hpet_rtc_flags & RTC_PIE) || hpet_pie_limit) |
1139 | delta = hpet_default_delta; | 1146 | delta = hpet_default_delta; |
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c index acf8fbf8fbda..69bca468c47a 100644 --- a/arch/x86/kernel/irq_64.c +++ b/arch/x86/kernel/irq_64.c | |||
@@ -38,6 +38,9 @@ static inline void stack_overflow_check(struct pt_regs *regs) | |||
38 | #ifdef CONFIG_DEBUG_STACKOVERFLOW | 38 | #ifdef CONFIG_DEBUG_STACKOVERFLOW |
39 | u64 curbase = (u64)task_stack_page(current); | 39 | u64 curbase = (u64)task_stack_page(current); |
40 | 40 | ||
41 | if (user_mode_vm(regs)) | ||
42 | return; | ||
43 | |||
41 | WARN_ONCE(regs->sp >= curbase && | 44 | WARN_ONCE(regs->sp >= curbase && |
42 | regs->sp <= curbase + THREAD_SIZE && | 45 | regs->sp <= curbase + THREAD_SIZE && |
43 | regs->sp < curbase + sizeof(struct thread_info) + | 46 | regs->sp < curbase + sizeof(struct thread_info) + |
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index f2d2a664e797..9d46f5e43b51 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c | |||
@@ -256,7 +256,7 @@ static int __init microcode_dev_init(void) | |||
256 | return 0; | 256 | return 0; |
257 | } | 257 | } |
258 | 258 | ||
259 | static void microcode_dev_exit(void) | 259 | static void __exit microcode_dev_exit(void) |
260 | { | 260 | { |
261 | misc_deregister(µcode_dev); | 261 | misc_deregister(µcode_dev); |
262 | } | 262 | } |
@@ -519,10 +519,8 @@ static int __init microcode_init(void) | |||
519 | 519 | ||
520 | microcode_pdev = platform_device_register_simple("microcode", -1, | 520 | microcode_pdev = platform_device_register_simple("microcode", -1, |
521 | NULL, 0); | 521 | NULL, 0); |
522 | if (IS_ERR(microcode_pdev)) { | 522 | if (IS_ERR(microcode_pdev)) |
523 | microcode_dev_exit(); | ||
524 | return PTR_ERR(microcode_pdev); | 523 | return PTR_ERR(microcode_pdev); |
525 | } | ||
526 | 524 | ||
527 | get_online_cpus(); | 525 | get_online_cpus(); |
528 | mutex_lock(µcode_mutex); | 526 | mutex_lock(µcode_mutex); |
@@ -532,14 +530,12 @@ static int __init microcode_init(void) | |||
532 | mutex_unlock(µcode_mutex); | 530 | mutex_unlock(µcode_mutex); |
533 | put_online_cpus(); | 531 | put_online_cpus(); |
534 | 532 | ||
535 | if (error) { | 533 | if (error) |
536 | platform_device_unregister(microcode_pdev); | 534 | goto out_pdev; |
537 | return error; | ||
538 | } | ||
539 | 535 | ||
540 | error = microcode_dev_init(); | 536 | error = microcode_dev_init(); |
541 | if (error) | 537 | if (error) |
542 | return error; | 538 | goto out_sysdev_driver; |
543 | 539 | ||
544 | register_syscore_ops(&mc_syscore_ops); | 540 | register_syscore_ops(&mc_syscore_ops); |
545 | register_hotcpu_notifier(&mc_cpu_notifier); | 541 | register_hotcpu_notifier(&mc_cpu_notifier); |
@@ -548,6 +544,20 @@ static int __init microcode_init(void) | |||
548 | " <tigran@aivazian.fsnet.co.uk>, Peter Oruba\n"); | 544 | " <tigran@aivazian.fsnet.co.uk>, Peter Oruba\n"); |
549 | 545 | ||
550 | return 0; | 546 | return 0; |
547 | |||
548 | out_sysdev_driver: | ||
549 | get_online_cpus(); | ||
550 | mutex_lock(µcode_mutex); | ||
551 | |||
552 | sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver); | ||
553 | |||
554 | mutex_unlock(µcode_mutex); | ||
555 | put_online_cpus(); | ||
556 | |||
557 | out_pdev: | ||
558 | platform_device_unregister(microcode_pdev); | ||
559 | return error; | ||
560 | |||
551 | } | 561 | } |
552 | module_init(microcode_init); | 562 | module_init(microcode_init); |
553 | 563 | ||
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 9103b89c145a..0741b062a304 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c | |||
@@ -95,8 +95,8 @@ static void __init MP_bus_info(struct mpc_bus *m) | |||
95 | } | 95 | } |
96 | #endif | 96 | #endif |
97 | 97 | ||
98 | set_bit(m->busid, mp_bus_not_pci); | ||
98 | if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA) - 1) == 0) { | 99 | if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA) - 1) == 0) { |
99 | set_bit(m->busid, mp_bus_not_pci); | ||
100 | #if defined(CONFIG_EISA) || defined(CONFIG_MCA) | 100 | #if defined(CONFIG_EISA) || defined(CONFIG_MCA) |
101 | mp_bus_id_to_type[m->busid] = MP_BUS_ISA; | 101 | mp_bus_id_to_type[m->busid] = MP_BUS_ISA; |
102 | #endif | 102 | #endif |
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index b78643d0f9a5..03920a15a632 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c | |||
@@ -553,4 +553,17 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC, | |||
553 | quirk_amd_nb_node); | 553 | quirk_amd_nb_node); |
554 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_LINK, | 554 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_LINK, |
555 | quirk_amd_nb_node); | 555 | quirk_amd_nb_node); |
556 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F0, | ||
557 | quirk_amd_nb_node); | ||
558 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F1, | ||
559 | quirk_amd_nb_node); | ||
560 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F2, | ||
561 | quirk_amd_nb_node); | ||
562 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F3, | ||
563 | quirk_amd_nb_node); | ||
564 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F4, | ||
565 | quirk_amd_nb_node); | ||
566 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F5, | ||
567 | quirk_amd_nb_node); | ||
568 | |||
556 | #endif | 569 | #endif |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index e334be1182b9..37a458b521a6 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -124,7 +124,7 @@ __setup("reboot=", reboot_setup); | |||
124 | */ | 124 | */ |
125 | 125 | ||
126 | /* | 126 | /* |
127 | * Some machines require the "reboot=b" commandline option, | 127 | * Some machines require the "reboot=b" or "reboot=k" commandline options, |
128 | * this quirk makes that automatic. | 128 | * this quirk makes that automatic. |
129 | */ | 129 | */ |
130 | static int __init set_bios_reboot(const struct dmi_system_id *d) | 130 | static int __init set_bios_reboot(const struct dmi_system_id *d) |
@@ -136,6 +136,15 @@ static int __init set_bios_reboot(const struct dmi_system_id *d) | |||
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
138 | 138 | ||
139 | static int __init set_kbd_reboot(const struct dmi_system_id *d) | ||
140 | { | ||
141 | if (reboot_type != BOOT_KBD) { | ||
142 | reboot_type = BOOT_KBD; | ||
143 | printk(KERN_INFO "%s series board detected. Selecting KBD-method for reboot.\n", d->ident); | ||
144 | } | ||
145 | return 0; | ||
146 | } | ||
147 | |||
139 | static struct dmi_system_id __initdata reboot_dmi_table[] = { | 148 | static struct dmi_system_id __initdata reboot_dmi_table[] = { |
140 | { /* Handle problems with rebooting on Dell E520's */ | 149 | { /* Handle problems with rebooting on Dell E520's */ |
141 | .callback = set_bios_reboot, | 150 | .callback = set_bios_reboot, |
@@ -295,7 +304,7 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | |||
295 | }, | 304 | }, |
296 | }, | 305 | }, |
297 | { /* Handle reboot issue on Acer Aspire one */ | 306 | { /* Handle reboot issue on Acer Aspire one */ |
298 | .callback = set_bios_reboot, | 307 | .callback = set_kbd_reboot, |
299 | .ident = "Acer Aspire One A110", | 308 | .ident = "Acer Aspire One A110", |
300 | .matches = { | 309 | .matches = { |
301 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 310 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
@@ -443,6 +452,14 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { | |||
443 | DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6420"), | 452 | DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6420"), |
444 | }, | 453 | }, |
445 | }, | 454 | }, |
455 | { /* Handle problems with rebooting on the OptiPlex 990. */ | ||
456 | .callback = set_pci_reboot, | ||
457 | .ident = "Dell OptiPlex 990", | ||
458 | .matches = { | ||
459 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
460 | DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"), | ||
461 | }, | ||
462 | }, | ||
446 | { } | 463 | { } |
447 | }; | 464 | }; |
448 | 465 | ||
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c index 348ce016a835..af6db6ec5b2a 100644 --- a/arch/x86/kernel/rtc.c +++ b/arch/x86/kernel/rtc.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <asm/vsyscall.h> | 12 | #include <asm/vsyscall.h> |
13 | #include <asm/x86_init.h> | 13 | #include <asm/x86_init.h> |
14 | #include <asm/time.h> | 14 | #include <asm/time.h> |
15 | #include <asm/mrst.h> | ||
15 | 16 | ||
16 | #ifdef CONFIG_X86_32 | 17 | #ifdef CONFIG_X86_32 |
17 | /* | 18 | /* |
@@ -242,6 +243,10 @@ static __init int add_rtc_cmos(void) | |||
242 | if (of_have_populated_dt()) | 243 | if (of_have_populated_dt()) |
243 | return 0; | 244 | return 0; |
244 | 245 | ||
246 | /* Intel MID platforms don't have ioport rtc */ | ||
247 | if (mrst_identify_cpu()) | ||
248 | return -ENODEV; | ||
249 | |||
245 | platform_device_register(&rtc_device); | 250 | platform_device_register(&rtc_device); |
246 | dev_info(&rtc_device.dev, | 251 | dev_info(&rtc_device.dev, |
247 | "registered platform RTC device (no PNP device found)\n"); | 252 | "registered platform RTC device (no PNP device found)\n"); |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index cf0ef986cb6d..9a9e40fb091c 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -691,6 +691,8 @@ early_param("reservelow", parse_reservelow); | |||
691 | 691 | ||
692 | void __init setup_arch(char **cmdline_p) | 692 | void __init setup_arch(char **cmdline_p) |
693 | { | 693 | { |
694 | unsigned long end_pfn; | ||
695 | |||
694 | #ifdef CONFIG_X86_32 | 696 | #ifdef CONFIG_X86_32 |
695 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); | 697 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); |
696 | visws_early_detect(); | 698 | visws_early_detect(); |
@@ -932,7 +934,24 @@ void __init setup_arch(char **cmdline_p) | |||
932 | init_gbpages(); | 934 | init_gbpages(); |
933 | 935 | ||
934 | /* max_pfn_mapped is updated here */ | 936 | /* max_pfn_mapped is updated here */ |
935 | max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT); | 937 | end_pfn = max_low_pfn; |
938 | |||
939 | #ifdef CONFIG_X86_64 | ||
940 | /* | ||
941 | * There may be regions after the last E820_RAM region that we | ||
942 | * want to include in the kernel direct mapping, such as | ||
943 | * EFI_RUNTIME_SERVICES_DATA. | ||
944 | */ | ||
945 | if (efi_enabled) { | ||
946 | unsigned long efi_end; | ||
947 | |||
948 | efi_end = e820_end_pfn(MAXMEM>>PAGE_SHIFT, E820_RESERVED_EFI); | ||
949 | if (efi_end > max_low_pfn) | ||
950 | end_pfn = efi_end; | ||
951 | } | ||
952 | #endif | ||
953 | |||
954 | max_low_pfn_mapped = init_memory_mapping(0, end_pfn << PAGE_SHIFT); | ||
936 | max_pfn_mapped = max_low_pfn_mapped; | 955 | max_pfn_mapped = max_low_pfn_mapped; |
937 | 956 | ||
938 | #ifdef CONFIG_X86_64 | 957 | #ifdef CONFIG_X86_64 |
diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c index ea305856151c..dd74e46828c0 100644 --- a/arch/x86/mm/gup.c +++ b/arch/x86/mm/gup.c | |||
@@ -201,6 +201,8 @@ static noinline int gup_huge_pud(pud_t pud, unsigned long addr, | |||
201 | do { | 201 | do { |
202 | VM_BUG_ON(compound_head(page) != head); | 202 | VM_BUG_ON(compound_head(page) != head); |
203 | pages[*nr] = page; | 203 | pages[*nr] = page; |
204 | if (PageTail(page)) | ||
205 | get_huge_page_tail(page); | ||
204 | (*nr)++; | 206 | (*nr)++; |
205 | page++; | 207 | page++; |
206 | refs++; | 208 | refs++; |
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c index b49962662101..f4f29b19fac5 100644 --- a/arch/x86/mm/highmem_32.c +++ b/arch/x86/mm/highmem_32.c | |||
@@ -45,6 +45,7 @@ void *kmap_atomic_prot(struct page *page, pgprot_t prot) | |||
45 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 45 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
46 | BUG_ON(!pte_none(*(kmap_pte-idx))); | 46 | BUG_ON(!pte_none(*(kmap_pte-idx))); |
47 | set_pte(kmap_pte-idx, mk_pte(page, prot)); | 47 | set_pte(kmap_pte-idx, mk_pte(page, prot)); |
48 | arch_flush_lazy_mmu_mode(); | ||
48 | 49 | ||
49 | return (void *)vaddr; | 50 | return (void *)vaddr; |
50 | } | 51 | } |
@@ -88,6 +89,7 @@ void __kunmap_atomic(void *kvaddr) | |||
88 | */ | 89 | */ |
89 | kpte_clear_flush(kmap_pte-idx, vaddr); | 90 | kpte_clear_flush(kmap_pte-idx, vaddr); |
90 | kmap_atomic_idx_pop(); | 91 | kmap_atomic_idx_pop(); |
92 | arch_flush_lazy_mmu_mode(); | ||
91 | } | 93 | } |
92 | #ifdef CONFIG_DEBUG_HIGHMEM | 94 | #ifdef CONFIG_DEBUG_HIGHMEM |
93 | else { | 95 | else { |
diff --git a/arch/x86/oprofile/init.c b/arch/x86/oprofile/init.c index cdfe4c54deca..f148cf652678 100644 --- a/arch/x86/oprofile/init.c +++ b/arch/x86/oprofile/init.c | |||
@@ -21,6 +21,7 @@ extern int op_nmi_timer_init(struct oprofile_operations *ops); | |||
21 | extern void op_nmi_exit(void); | 21 | extern void op_nmi_exit(void); |
22 | extern void x86_backtrace(struct pt_regs * const regs, unsigned int depth); | 22 | extern void x86_backtrace(struct pt_regs * const regs, unsigned int depth); |
23 | 23 | ||
24 | static int nmi_timer; | ||
24 | 25 | ||
25 | int __init oprofile_arch_init(struct oprofile_operations *ops) | 26 | int __init oprofile_arch_init(struct oprofile_operations *ops) |
26 | { | 27 | { |
@@ -31,8 +32,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
31 | #ifdef CONFIG_X86_LOCAL_APIC | 32 | #ifdef CONFIG_X86_LOCAL_APIC |
32 | ret = op_nmi_init(ops); | 33 | ret = op_nmi_init(ops); |
33 | #endif | 34 | #endif |
35 | nmi_timer = (ret != 0); | ||
34 | #ifdef CONFIG_X86_IO_APIC | 36 | #ifdef CONFIG_X86_IO_APIC |
35 | if (ret < 0) | 37 | if (nmi_timer) |
36 | ret = op_nmi_timer_init(ops); | 38 | ret = op_nmi_timer_init(ops); |
37 | #endif | 39 | #endif |
38 | ops->backtrace = x86_backtrace; | 40 | ops->backtrace = x86_backtrace; |
@@ -44,6 +46,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
44 | void oprofile_arch_exit(void) | 46 | void oprofile_arch_exit(void) |
45 | { | 47 | { |
46 | #ifdef CONFIG_X86_LOCAL_APIC | 48 | #ifdef CONFIG_X86_LOCAL_APIC |
47 | op_nmi_exit(); | 49 | if (!nmi_timer) |
50 | op_nmi_exit(); | ||
48 | #endif | 51 | #endif |
49 | } | 52 | } |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 37718f0f053d..c9718a16be15 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -323,10 +323,13 @@ static void __init do_add_efi_memmap(void) | |||
323 | case EFI_UNUSABLE_MEMORY: | 323 | case EFI_UNUSABLE_MEMORY: |
324 | e820_type = E820_UNUSABLE; | 324 | e820_type = E820_UNUSABLE; |
325 | break; | 325 | break; |
326 | case EFI_RUNTIME_SERVICES_DATA: | ||
327 | e820_type = E820_RESERVED_EFI; | ||
328 | break; | ||
326 | default: | 329 | default: |
327 | /* | 330 | /* |
328 | * EFI_RESERVED_TYPE EFI_RUNTIME_SERVICES_CODE | 331 | * EFI_RESERVED_TYPE EFI_RUNTIME_SERVICES_CODE |
329 | * EFI_RUNTIME_SERVICES_DATA EFI_MEMORY_MAPPED_IO | 332 | * EFI_MEMORY_MAPPED_IO |
330 | * EFI_MEMORY_MAPPED_IO_PORT_SPACE EFI_PAL_CODE | 333 | * EFI_MEMORY_MAPPED_IO_PORT_SPACE EFI_PAL_CODE |
331 | */ | 334 | */ |
332 | e820_type = E820_RESERVED; | 335 | e820_type = E820_RESERVED; |
@@ -671,10 +674,21 @@ void __init efi_enter_virtual_mode(void) | |||
671 | end_pfn = PFN_UP(end); | 674 | end_pfn = PFN_UP(end); |
672 | if (end_pfn <= max_low_pfn_mapped | 675 | if (end_pfn <= max_low_pfn_mapped |
673 | || (end_pfn > (1UL << (32 - PAGE_SHIFT)) | 676 | || (end_pfn > (1UL << (32 - PAGE_SHIFT)) |
674 | && end_pfn <= max_pfn_mapped)) | 677 | && end_pfn <= max_pfn_mapped)) { |
675 | va = __va(md->phys_addr); | 678 | va = __va(md->phys_addr); |
676 | else | 679 | |
677 | va = efi_ioremap(md->phys_addr, size, md->type); | 680 | if (!(md->attribute & EFI_MEMORY_WB)) { |
681 | addr = (u64) (unsigned long)va; | ||
682 | npages = md->num_pages; | ||
683 | memrange_efi_to_native(&addr, &npages); | ||
684 | set_memory_uc(addr, npages); | ||
685 | } | ||
686 | } else { | ||
687 | if (!(md->attribute & EFI_MEMORY_WB)) | ||
688 | va = ioremap_nocache(md->phys_addr, size); | ||
689 | else | ||
690 | va = ioremap_cache(md->phys_addr, size); | ||
691 | } | ||
678 | 692 | ||
679 | md->virt_addr = (u64) (unsigned long) va; | 693 | md->virt_addr = (u64) (unsigned long) va; |
680 | 694 | ||
@@ -684,13 +698,6 @@ void __init efi_enter_virtual_mode(void) | |||
684 | continue; | 698 | continue; |
685 | } | 699 | } |
686 | 700 | ||
687 | if (!(md->attribute & EFI_MEMORY_WB)) { | ||
688 | addr = md->virt_addr; | ||
689 | npages = md->num_pages; | ||
690 | memrange_efi_to_native(&addr, &npages); | ||
691 | set_memory_uc(addr, npages); | ||
692 | } | ||
693 | |||
694 | systab = (u64) (unsigned long) efi_phys.systab; | 701 | systab = (u64) (unsigned long) efi_phys.systab; |
695 | if (md->phys_addr <= systab && systab < end) { | 702 | if (md->phys_addr <= systab && systab < end) { |
696 | systab += md->virt_addr - md->phys_addr; | 703 | systab += md->virt_addr - md->phys_addr; |
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index ac3aa54e2654..312250c6b2de 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c | |||
@@ -80,20 +80,3 @@ void __init efi_call_phys_epilog(void) | |||
80 | local_irq_restore(efi_flags); | 80 | local_irq_restore(efi_flags); |
81 | early_code_mapping_set_exec(0); | 81 | early_code_mapping_set_exec(0); |
82 | } | 82 | } |
83 | |||
84 | void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size, | ||
85 | u32 type) | ||
86 | { | ||
87 | unsigned long last_map_pfn; | ||
88 | |||
89 | if (type == EFI_MEMORY_MAPPED_IO) | ||
90 | return ioremap(phys_addr, size); | ||
91 | |||
92 | last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size); | ||
93 | if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size) { | ||
94 | unsigned long top = last_map_pfn << PAGE_SHIFT; | ||
95 | efi_ioremap(top, size - (top - phys_addr), type); | ||
96 | } | ||
97 | |||
98 | return (void __iomem *)__va(phys_addr); | ||
99 | } | ||
diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c index b1489a06a49d..ad4ec1cb097e 100644 --- a/arch/x86/platform/mrst/mrst.c +++ b/arch/x86/platform/mrst/mrst.c | |||
@@ -76,6 +76,20 @@ struct sfi_rtc_table_entry sfi_mrtc_array[SFI_MRTC_MAX]; | |||
76 | EXPORT_SYMBOL_GPL(sfi_mrtc_array); | 76 | EXPORT_SYMBOL_GPL(sfi_mrtc_array); |
77 | int sfi_mrtc_num; | 77 | int sfi_mrtc_num; |
78 | 78 | ||
79 | static void mrst_power_off(void) | ||
80 | { | ||
81 | if (__mrst_cpu_chip == MRST_CPU_CHIP_LINCROFT) | ||
82 | intel_scu_ipc_simple_command(IPCMSG_COLD_RESET, 1); | ||
83 | } | ||
84 | |||
85 | static void mrst_reboot(void) | ||
86 | { | ||
87 | if (__mrst_cpu_chip == MRST_CPU_CHIP_LINCROFT) | ||
88 | intel_scu_ipc_simple_command(IPCMSG_COLD_RESET, 0); | ||
89 | else | ||
90 | intel_scu_ipc_simple_command(IPCMSG_COLD_BOOT, 0); | ||
91 | } | ||
92 | |||
79 | /* parse all the mtimer info to a static mtimer array */ | 93 | /* parse all the mtimer info to a static mtimer array */ |
80 | static int __init sfi_parse_mtmr(struct sfi_table_header *table) | 94 | static int __init sfi_parse_mtmr(struct sfi_table_header *table) |
81 | { | 95 | { |
@@ -265,17 +279,6 @@ static int mrst_i8042_detect(void) | |||
265 | return 0; | 279 | return 0; |
266 | } | 280 | } |
267 | 281 | ||
268 | /* Reboot and power off are handled by the SCU on a MID device */ | ||
269 | static void mrst_power_off(void) | ||
270 | { | ||
271 | intel_scu_ipc_simple_command(0xf1, 1); | ||
272 | } | ||
273 | |||
274 | static void mrst_reboot(void) | ||
275 | { | ||
276 | intel_scu_ipc_simple_command(0xf1, 0); | ||
277 | } | ||
278 | |||
279 | /* | 282 | /* |
280 | * Moorestown does not have external NMI source nor port 0x61 to report | 283 | * Moorestown does not have external NMI source nor port 0x61 to report |
281 | * NMI status. The possible NMI sources are from pmu as a result of NMI | 284 | * NMI status. The possible NMI sources are from pmu as a result of NMI |
@@ -484,6 +487,46 @@ static void __init *max7315_platform_data(void *info) | |||
484 | return max7315; | 487 | return max7315; |
485 | } | 488 | } |
486 | 489 | ||
490 | static void *tca6416_platform_data(void *info) | ||
491 | { | ||
492 | static struct pca953x_platform_data tca6416; | ||
493 | struct i2c_board_info *i2c_info = info; | ||
494 | int gpio_base, intr; | ||
495 | char base_pin_name[SFI_NAME_LEN + 1]; | ||
496 | char intr_pin_name[SFI_NAME_LEN + 1]; | ||
497 | |||
498 | strcpy(i2c_info->type, "tca6416"); | ||
499 | strcpy(base_pin_name, "tca6416_base"); | ||
500 | strcpy(intr_pin_name, "tca6416_int"); | ||
501 | |||
502 | gpio_base = get_gpio_by_name(base_pin_name); | ||
503 | intr = get_gpio_by_name(intr_pin_name); | ||
504 | |||
505 | if (gpio_base == -1) | ||
506 | return NULL; | ||
507 | tca6416.gpio_base = gpio_base; | ||
508 | if (intr != -1) { | ||
509 | i2c_info->irq = intr + MRST_IRQ_OFFSET; | ||
510 | tca6416.irq_base = gpio_base + MRST_IRQ_OFFSET; | ||
511 | } else { | ||
512 | i2c_info->irq = -1; | ||
513 | tca6416.irq_base = -1; | ||
514 | } | ||
515 | return &tca6416; | ||
516 | } | ||
517 | |||
518 | static void *mpu3050_platform_data(void *info) | ||
519 | { | ||
520 | struct i2c_board_info *i2c_info = info; | ||
521 | int intr = get_gpio_by_name("mpu3050_int"); | ||
522 | |||
523 | if (intr == -1) | ||
524 | return NULL; | ||
525 | |||
526 | i2c_info->irq = intr + MRST_IRQ_OFFSET; | ||
527 | return NULL; | ||
528 | } | ||
529 | |||
487 | static void __init *emc1403_platform_data(void *info) | 530 | static void __init *emc1403_platform_data(void *info) |
488 | { | 531 | { |
489 | static short intr2nd_pdata; | 532 | static short intr2nd_pdata; |
@@ -646,12 +689,15 @@ static void *msic_ocd_platform_data(void *info) | |||
646 | static const struct devs_id __initconst device_ids[] = { | 689 | static const struct devs_id __initconst device_ids[] = { |
647 | {"bma023", SFI_DEV_TYPE_I2C, 1, &no_platform_data}, | 690 | {"bma023", SFI_DEV_TYPE_I2C, 1, &no_platform_data}, |
648 | {"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data}, | 691 | {"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data}, |
692 | {"pmic_gpio", SFI_DEV_TYPE_IPC, 1, &pmic_gpio_platform_data}, | ||
649 | {"spi_max3111", SFI_DEV_TYPE_SPI, 0, &max3111_platform_data}, | 693 | {"spi_max3111", SFI_DEV_TYPE_SPI, 0, &max3111_platform_data}, |
650 | {"i2c_max7315", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data}, | 694 | {"i2c_max7315", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data}, |
651 | {"i2c_max7315_2", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data}, | 695 | {"i2c_max7315_2", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data}, |
696 | {"tca6416", SFI_DEV_TYPE_I2C, 1, &tca6416_platform_data}, | ||
652 | {"emc1403", SFI_DEV_TYPE_I2C, 1, &emc1403_platform_data}, | 697 | {"emc1403", SFI_DEV_TYPE_I2C, 1, &emc1403_platform_data}, |
653 | {"i2c_accel", SFI_DEV_TYPE_I2C, 0, &lis331dl_platform_data}, | 698 | {"i2c_accel", SFI_DEV_TYPE_I2C, 0, &lis331dl_platform_data}, |
654 | {"pmic_audio", SFI_DEV_TYPE_IPC, 1, &no_platform_data}, | 699 | {"pmic_audio", SFI_DEV_TYPE_IPC, 1, &no_platform_data}, |
700 | {"mpu3050", SFI_DEV_TYPE_I2C, 1, &mpu3050_platform_data}, | ||
655 | 701 | ||
656 | /* MSIC subdevices */ | 702 | /* MSIC subdevices */ |
657 | {"msic_battery", SFI_DEV_TYPE_IPC, 1, &msic_battery_platform_data}, | 703 | {"msic_battery", SFI_DEV_TYPE_IPC, 1, &msic_battery_platform_data}, |
diff --git a/drivers/base/core.c b/drivers/base/core.c index d8b3d89db043..919daa7cd5b1 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -1743,8 +1743,10 @@ void device_shutdown(void) | |||
1743 | */ | 1743 | */ |
1744 | list_del_init(&dev->kobj.entry); | 1744 | list_del_init(&dev->kobj.entry); |
1745 | spin_unlock(&devices_kset->list_lock); | 1745 | spin_unlock(&devices_kset->list_lock); |
1746 | /* Disable all device's runtime power management */ | 1746 | |
1747 | pm_runtime_disable(dev); | 1747 | /* Don't allow any more runtime suspends */ |
1748 | pm_runtime_get_noresume(dev); | ||
1749 | pm_runtime_barrier(dev); | ||
1748 | 1750 | ||
1749 | if (dev->bus && dev->bus->shutdown) { | 1751 | if (dev->bus && dev->bus->shutdown) { |
1750 | dev_dbg(dev, "shutdown\n"); | 1752 | dev_dbg(dev, "shutdown\n"); |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index dbcb0bcfd8da..4e018d6a7639 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -18,7 +18,7 @@ obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o | |||
18 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o | 18 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o |
19 | obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o | 19 | obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o |
20 | obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o | 20 | obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o |
21 | obj-$(CONFIG_MACH_KS8695) += gpio-ks8695.o | 21 | obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o |
22 | obj-$(CONFIG_GPIO_LANGWELL) += gpio-langwell.o | 22 | obj-$(CONFIG_GPIO_LANGWELL) += gpio-langwell.o |
23 | obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o | 23 | obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o |
24 | obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o | 24 | obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8359dc777041..60ff1b63b568 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2026,8 +2026,13 @@ i915_wait_request(struct intel_ring_buffer *ring, | |||
2026 | * to handle this, the waiter on a request often wants an associated | 2026 | * to handle this, the waiter on a request often wants an associated |
2027 | * buffer to have made it to the inactive list, and we would need | 2027 | * buffer to have made it to the inactive list, and we would need |
2028 | * a separate wait queue to handle that. | 2028 | * a separate wait queue to handle that. |
2029 | * | ||
2030 | * To avoid a recursion with the ilk VT-d workaround (that calls | ||
2031 | * gpu_idle when unbinding objects with interruptible==false) don't | ||
2032 | * retire requests in that case (because it might call unbind if the | ||
2033 | * active list holds the last reference to the object). | ||
2029 | */ | 2034 | */ |
2030 | if (ret == 0) | 2035 | if (ret == 0 && dev_priv->mm.interruptible) |
2031 | i915_gem_retire_requests_ring(ring); | 2036 | i915_gem_retire_requests_ring(ring); |
2032 | 2037 | ||
2033 | return ret; | 2038 | return ret; |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 06e413e6a920..4b27efa4405b 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -233,13 +233,12 @@ u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder) | |||
233 | switch (radeon_encoder->encoder_id) { | 233 | switch (radeon_encoder->encoder_id) { |
234 | case ENCODER_OBJECT_ID_TRAVIS: | 234 | case ENCODER_OBJECT_ID_TRAVIS: |
235 | case ENCODER_OBJECT_ID_NUTMEG: | 235 | case ENCODER_OBJECT_ID_NUTMEG: |
236 | return true; | 236 | return radeon_encoder->encoder_id; |
237 | default: | 237 | default: |
238 | return false; | 238 | return ENCODER_OBJECT_ID_NONE; |
239 | } | 239 | } |
240 | } | 240 | } |
241 | 241 | return ENCODER_OBJECT_ID_NONE; | |
242 | return false; | ||
243 | } | 242 | } |
244 | 243 | ||
245 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, | 244 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 3f6343502d1f..5ff561d4e0b4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | |||
@@ -140,7 +140,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data, | |||
140 | goto out_clips; | 140 | goto out_clips; |
141 | } | 141 | } |
142 | 142 | ||
143 | clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); | 143 | clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL); |
144 | if (clips == NULL) { | 144 | if (clips == NULL) { |
145 | DRM_ERROR("Failed to allocate clip rect list.\n"); | 145 | DRM_ERROR("Failed to allocate clip rect list.\n"); |
146 | ret = -ENOMEM; | 146 | ret = -ENOMEM; |
@@ -232,7 +232,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data, | |||
232 | goto out_clips; | 232 | goto out_clips; |
233 | } | 233 | } |
234 | 234 | ||
235 | clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); | 235 | clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL); |
236 | if (clips == NULL) { | 236 | if (clips == NULL) { |
237 | DRM_ERROR("Failed to allocate clip rect list.\n"); | 237 | DRM_ERROR("Failed to allocate clip rect list.\n"); |
238 | ret = -ENOMEM; | 238 | ret = -ENOMEM; |
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 5414253b185a..6bea6962f8ee 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig | |||
@@ -34,7 +34,9 @@ config AMD_IOMMU | |||
34 | bool "AMD IOMMU support" | 34 | bool "AMD IOMMU support" |
35 | select SWIOTLB | 35 | select SWIOTLB |
36 | select PCI_MSI | 36 | select PCI_MSI |
37 | select PCI_IOV | 37 | select PCI_ATS |
38 | select PCI_PRI | ||
39 | select PCI_PASID | ||
38 | select IOMMU_API | 40 | select IOMMU_API |
39 | depends on X86_64 && PCI && ACPI | 41 | depends on X86_64 && PCI && ACPI |
40 | ---help--- | 42 | ---help--- |
@@ -58,6 +60,15 @@ config AMD_IOMMU_STATS | |||
58 | information to userspace via debugfs. | 60 | information to userspace via debugfs. |
59 | If unsure, say N. | 61 | If unsure, say N. |
60 | 62 | ||
63 | config AMD_IOMMU_V2 | ||
64 | tristate "AMD IOMMU Version 2 driver (EXPERIMENTAL)" | ||
65 | depends on AMD_IOMMU && PROFILING && EXPERIMENTAL | ||
66 | select MMU_NOTIFIER | ||
67 | ---help--- | ||
68 | This option enables support for the AMD IOMMUv2 features of the IOMMU | ||
69 | hardware. Select this option if you want to use devices that support | ||
70 | the the PCI PRI and PASID interface. | ||
71 | |||
61 | # Intel IOMMU support | 72 | # Intel IOMMU support |
62 | config DMAR_TABLE | 73 | config DMAR_TABLE |
63 | bool | 74 | bool |
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 2f4448794bc7..0e36b4934aff 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile | |||
@@ -1,6 +1,7 @@ | |||
1 | obj-$(CONFIG_IOMMU_API) += iommu.o | 1 | obj-$(CONFIG_IOMMU_API) += iommu.o |
2 | obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o msm_iommu_dev.o | 2 | obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o msm_iommu_dev.o |
3 | obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o | 3 | obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o |
4 | obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o | ||
4 | obj-$(CONFIG_DMAR_TABLE) += dmar.o | 5 | obj-$(CONFIG_DMAR_TABLE) += dmar.o |
5 | obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o | 6 | obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o |
6 | obj-$(CONFIG_IRQ_REMAP) += intr_remapping.o | 7 | obj-$(CONFIG_IRQ_REMAP) += intr_remapping.o |
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 4ee277a8521a..a7cbcd46af9e 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -17,6 +17,7 @@ | |||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/ratelimit.h> | ||
20 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
21 | #include <linux/pci-ats.h> | 22 | #include <linux/pci-ats.h> |
22 | #include <linux/bitmap.h> | 23 | #include <linux/bitmap.h> |
@@ -28,6 +29,8 @@ | |||
28 | #include <linux/iommu.h> | 29 | #include <linux/iommu.h> |
29 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
30 | #include <linux/amd-iommu.h> | 31 | #include <linux/amd-iommu.h> |
32 | #include <linux/notifier.h> | ||
33 | #include <linux/export.h> | ||
31 | #include <asm/msidef.h> | 34 | #include <asm/msidef.h> |
32 | #include <asm/proto.h> | 35 | #include <asm/proto.h> |
33 | #include <asm/iommu.h> | 36 | #include <asm/iommu.h> |
@@ -41,6 +44,24 @@ | |||
41 | 44 | ||
42 | #define LOOP_TIMEOUT 100000 | 45 | #define LOOP_TIMEOUT 100000 |
43 | 46 | ||
47 | /* | ||
48 | * This bitmap is used to advertise the page sizes our hardware support | ||
49 | * to the IOMMU core, which will then use this information to split | ||
50 | * physically contiguous memory regions it is mapping into page sizes | ||
51 | * that we support. | ||
52 | * | ||
53 | * Traditionally the IOMMU core just handed us the mappings directly, | ||
54 | * after making sure the size is an order of a 4KiB page and that the | ||
55 | * mapping has natural alignment. | ||
56 | * | ||
57 | * To retain this behavior, we currently advertise that we support | ||
58 | * all page sizes that are an order of 4KiB. | ||
59 | * | ||
60 | * If at some point we'd like to utilize the IOMMU core's new behavior, | ||
61 | * we could change this to advertise the real page sizes we support. | ||
62 | */ | ||
63 | #define AMD_IOMMU_PGSIZES (~0xFFFUL) | ||
64 | |||
44 | static DEFINE_RWLOCK(amd_iommu_devtable_lock); | 65 | static DEFINE_RWLOCK(amd_iommu_devtable_lock); |
45 | 66 | ||
46 | /* A list of preallocated protection domains */ | 67 | /* A list of preallocated protection domains */ |
@@ -59,6 +80,9 @@ static struct protection_domain *pt_domain; | |||
59 | 80 | ||
60 | static struct iommu_ops amd_iommu_ops; | 81 | static struct iommu_ops amd_iommu_ops; |
61 | 82 | ||
83 | static ATOMIC_NOTIFIER_HEAD(ppr_notifier); | ||
84 | int amd_iommu_max_glx_val = -1; | ||
85 | |||
62 | /* | 86 | /* |
63 | * general struct to manage commands send to an IOMMU | 87 | * general struct to manage commands send to an IOMMU |
64 | */ | 88 | */ |
@@ -67,6 +91,7 @@ struct iommu_cmd { | |||
67 | }; | 91 | }; |
68 | 92 | ||
69 | static void update_domain(struct protection_domain *domain); | 93 | static void update_domain(struct protection_domain *domain); |
94 | static int __init alloc_passthrough_domain(void); | ||
70 | 95 | ||
71 | /**************************************************************************** | 96 | /**************************************************************************** |
72 | * | 97 | * |
@@ -147,6 +172,33 @@ static struct iommu_dev_data *get_dev_data(struct device *dev) | |||
147 | return dev->archdata.iommu; | 172 | return dev->archdata.iommu; |
148 | } | 173 | } |
149 | 174 | ||
175 | static bool pci_iommuv2_capable(struct pci_dev *pdev) | ||
176 | { | ||
177 | static const int caps[] = { | ||
178 | PCI_EXT_CAP_ID_ATS, | ||
179 | PCI_PRI_CAP, | ||
180 | PCI_PASID_CAP, | ||
181 | }; | ||
182 | int i, pos; | ||
183 | |||
184 | for (i = 0; i < 3; ++i) { | ||
185 | pos = pci_find_ext_capability(pdev, caps[i]); | ||
186 | if (pos == 0) | ||
187 | return false; | ||
188 | } | ||
189 | |||
190 | return true; | ||
191 | } | ||
192 | |||
193 | static bool pdev_pri_erratum(struct pci_dev *pdev, u32 erratum) | ||
194 | { | ||
195 | struct iommu_dev_data *dev_data; | ||
196 | |||
197 | dev_data = get_dev_data(&pdev->dev); | ||
198 | |||
199 | return dev_data->errata & (1 << erratum) ? true : false; | ||
200 | } | ||
201 | |||
150 | /* | 202 | /* |
151 | * In this function the list of preallocated protection domains is traversed to | 203 | * In this function the list of preallocated protection domains is traversed to |
152 | * find the domain for a specific device | 204 | * find the domain for a specific device |
@@ -204,6 +256,7 @@ static bool check_device(struct device *dev) | |||
204 | 256 | ||
205 | static int iommu_init_device(struct device *dev) | 257 | static int iommu_init_device(struct device *dev) |
206 | { | 258 | { |
259 | struct pci_dev *pdev = to_pci_dev(dev); | ||
207 | struct iommu_dev_data *dev_data; | 260 | struct iommu_dev_data *dev_data; |
208 | u16 alias; | 261 | u16 alias; |
209 | 262 | ||
@@ -228,6 +281,13 @@ static int iommu_init_device(struct device *dev) | |||
228 | dev_data->alias_data = alias_data; | 281 | dev_data->alias_data = alias_data; |
229 | } | 282 | } |
230 | 283 | ||
284 | if (pci_iommuv2_capable(pdev)) { | ||
285 | struct amd_iommu *iommu; | ||
286 | |||
287 | iommu = amd_iommu_rlookup_table[dev_data->devid]; | ||
288 | dev_data->iommu_v2 = iommu->is_iommu_v2; | ||
289 | } | ||
290 | |||
231 | dev->archdata.iommu = dev_data; | 291 | dev->archdata.iommu = dev_data; |
232 | 292 | ||
233 | return 0; | 293 | return 0; |
@@ -317,6 +377,11 @@ DECLARE_STATS_COUNTER(domain_flush_single); | |||
317 | DECLARE_STATS_COUNTER(domain_flush_all); | 377 | DECLARE_STATS_COUNTER(domain_flush_all); |
318 | DECLARE_STATS_COUNTER(alloced_io_mem); | 378 | DECLARE_STATS_COUNTER(alloced_io_mem); |
319 | DECLARE_STATS_COUNTER(total_map_requests); | 379 | DECLARE_STATS_COUNTER(total_map_requests); |
380 | DECLARE_STATS_COUNTER(complete_ppr); | ||
381 | DECLARE_STATS_COUNTER(invalidate_iotlb); | ||
382 | DECLARE_STATS_COUNTER(invalidate_iotlb_all); | ||
383 | DECLARE_STATS_COUNTER(pri_requests); | ||
384 | |||
320 | 385 | ||
321 | static struct dentry *stats_dir; | 386 | static struct dentry *stats_dir; |
322 | static struct dentry *de_fflush; | 387 | static struct dentry *de_fflush; |
@@ -351,6 +416,10 @@ static void amd_iommu_stats_init(void) | |||
351 | amd_iommu_stats_add(&domain_flush_all); | 416 | amd_iommu_stats_add(&domain_flush_all); |
352 | amd_iommu_stats_add(&alloced_io_mem); | 417 | amd_iommu_stats_add(&alloced_io_mem); |
353 | amd_iommu_stats_add(&total_map_requests); | 418 | amd_iommu_stats_add(&total_map_requests); |
419 | amd_iommu_stats_add(&complete_ppr); | ||
420 | amd_iommu_stats_add(&invalidate_iotlb); | ||
421 | amd_iommu_stats_add(&invalidate_iotlb_all); | ||
422 | amd_iommu_stats_add(&pri_requests); | ||
354 | } | 423 | } |
355 | 424 | ||
356 | #endif | 425 | #endif |
@@ -365,8 +434,8 @@ static void dump_dte_entry(u16 devid) | |||
365 | { | 434 | { |
366 | int i; | 435 | int i; |
367 | 436 | ||
368 | for (i = 0; i < 8; ++i) | 437 | for (i = 0; i < 4; ++i) |
369 | pr_err("AMD-Vi: DTE[%d]: %08x\n", i, | 438 | pr_err("AMD-Vi: DTE[%d]: %016llx\n", i, |
370 | amd_iommu_dev_table[devid].data[i]); | 439 | amd_iommu_dev_table[devid].data[i]); |
371 | } | 440 | } |
372 | 441 | ||
@@ -461,12 +530,84 @@ static void iommu_poll_events(struct amd_iommu *iommu) | |||
461 | spin_unlock_irqrestore(&iommu->lock, flags); | 530 | spin_unlock_irqrestore(&iommu->lock, flags); |
462 | } | 531 | } |
463 | 532 | ||
533 | static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u32 head) | ||
534 | { | ||
535 | struct amd_iommu_fault fault; | ||
536 | volatile u64 *raw; | ||
537 | int i; | ||
538 | |||
539 | INC_STATS_COUNTER(pri_requests); | ||
540 | |||
541 | raw = (u64 *)(iommu->ppr_log + head); | ||
542 | |||
543 | /* | ||
544 | * Hardware bug: Interrupt may arrive before the entry is written to | ||
545 | * memory. If this happens we need to wait for the entry to arrive. | ||
546 | */ | ||
547 | for (i = 0; i < LOOP_TIMEOUT; ++i) { | ||
548 | if (PPR_REQ_TYPE(raw[0]) != 0) | ||
549 | break; | ||
550 | udelay(1); | ||
551 | } | ||
552 | |||
553 | if (PPR_REQ_TYPE(raw[0]) != PPR_REQ_FAULT) { | ||
554 | pr_err_ratelimited("AMD-Vi: Unknown PPR request received\n"); | ||
555 | return; | ||
556 | } | ||
557 | |||
558 | fault.address = raw[1]; | ||
559 | fault.pasid = PPR_PASID(raw[0]); | ||
560 | fault.device_id = PPR_DEVID(raw[0]); | ||
561 | fault.tag = PPR_TAG(raw[0]); | ||
562 | fault.flags = PPR_FLAGS(raw[0]); | ||
563 | |||
564 | /* | ||
565 | * To detect the hardware bug we need to clear the entry | ||
566 | * to back to zero. | ||
567 | */ | ||
568 | raw[0] = raw[1] = 0; | ||
569 | |||
570 | atomic_notifier_call_chain(&ppr_notifier, 0, &fault); | ||
571 | } | ||
572 | |||
573 | static void iommu_poll_ppr_log(struct amd_iommu *iommu) | ||
574 | { | ||
575 | unsigned long flags; | ||
576 | u32 head, tail; | ||
577 | |||
578 | if (iommu->ppr_log == NULL) | ||
579 | return; | ||
580 | |||
581 | spin_lock_irqsave(&iommu->lock, flags); | ||
582 | |||
583 | head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); | ||
584 | tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); | ||
585 | |||
586 | while (head != tail) { | ||
587 | |||
588 | /* Handle PPR entry */ | ||
589 | iommu_handle_ppr_entry(iommu, head); | ||
590 | |||
591 | /* Update and refresh ring-buffer state*/ | ||
592 | head = (head + PPR_ENTRY_SIZE) % PPR_LOG_SIZE; | ||
593 | writel(head, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); | ||
594 | tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); | ||
595 | } | ||
596 | |||
597 | /* enable ppr interrupts again */ | ||
598 | writel(MMIO_STATUS_PPR_INT_MASK, iommu->mmio_base + MMIO_STATUS_OFFSET); | ||
599 | |||
600 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
601 | } | ||
602 | |||
464 | irqreturn_t amd_iommu_int_thread(int irq, void *data) | 603 | irqreturn_t amd_iommu_int_thread(int irq, void *data) |
465 | { | 604 | { |
466 | struct amd_iommu *iommu; | 605 | struct amd_iommu *iommu; |
467 | 606 | ||
468 | for_each_iommu(iommu) | 607 | for_each_iommu(iommu) { |
469 | iommu_poll_events(iommu); | 608 | iommu_poll_events(iommu); |
609 | iommu_poll_ppr_log(iommu); | ||
610 | } | ||
470 | 611 | ||
471 | return IRQ_HANDLED; | 612 | return IRQ_HANDLED; |
472 | } | 613 | } |
@@ -595,6 +736,60 @@ static void build_inv_iotlb_pages(struct iommu_cmd *cmd, u16 devid, int qdep, | |||
595 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; | 736 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; |
596 | } | 737 | } |
597 | 738 | ||
739 | static void build_inv_iommu_pasid(struct iommu_cmd *cmd, u16 domid, int pasid, | ||
740 | u64 address, bool size) | ||
741 | { | ||
742 | memset(cmd, 0, sizeof(*cmd)); | ||
743 | |||
744 | address &= ~(0xfffULL); | ||
745 | |||
746 | cmd->data[0] = pasid & PASID_MASK; | ||
747 | cmd->data[1] = domid; | ||
748 | cmd->data[2] = lower_32_bits(address); | ||
749 | cmd->data[3] = upper_32_bits(address); | ||
750 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK; | ||
751 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_GN_MASK; | ||
752 | if (size) | ||
753 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; | ||
754 | CMD_SET_TYPE(cmd, CMD_INV_IOMMU_PAGES); | ||
755 | } | ||
756 | |||
757 | static void build_inv_iotlb_pasid(struct iommu_cmd *cmd, u16 devid, int pasid, | ||
758 | int qdep, u64 address, bool size) | ||
759 | { | ||
760 | memset(cmd, 0, sizeof(*cmd)); | ||
761 | |||
762 | address &= ~(0xfffULL); | ||
763 | |||
764 | cmd->data[0] = devid; | ||
765 | cmd->data[0] |= (pasid & 0xff) << 16; | ||
766 | cmd->data[0] |= (qdep & 0xff) << 24; | ||
767 | cmd->data[1] = devid; | ||
768 | cmd->data[1] |= ((pasid >> 8) & 0xfff) << 16; | ||
769 | cmd->data[2] = lower_32_bits(address); | ||
770 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_GN_MASK; | ||
771 | cmd->data[3] = upper_32_bits(address); | ||
772 | if (size) | ||
773 | cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; | ||
774 | CMD_SET_TYPE(cmd, CMD_INV_IOTLB_PAGES); | ||
775 | } | ||
776 | |||
777 | static void build_complete_ppr(struct iommu_cmd *cmd, u16 devid, int pasid, | ||
778 | int status, int tag, bool gn) | ||
779 | { | ||
780 | memset(cmd, 0, sizeof(*cmd)); | ||
781 | |||
782 | cmd->data[0] = devid; | ||
783 | if (gn) { | ||
784 | cmd->data[1] = pasid & PASID_MASK; | ||
785 | cmd->data[2] = CMD_INV_IOMMU_PAGES_GN_MASK; | ||
786 | } | ||
787 | cmd->data[3] = tag & 0x1ff; | ||
788 | cmd->data[3] |= (status & PPR_STATUS_MASK) << PPR_STATUS_SHIFT; | ||
789 | |||
790 | CMD_SET_TYPE(cmd, CMD_COMPLETE_PPR); | ||
791 | } | ||
792 | |||
598 | static void build_inv_all(struct iommu_cmd *cmd) | 793 | static void build_inv_all(struct iommu_cmd *cmd) |
599 | { | 794 | { |
600 | memset(cmd, 0, sizeof(*cmd)); | 795 | memset(cmd, 0, sizeof(*cmd)); |
@@ -1496,6 +1691,48 @@ static void free_pagetable(struct protection_domain *domain) | |||
1496 | domain->pt_root = NULL; | 1691 | domain->pt_root = NULL; |
1497 | } | 1692 | } |
1498 | 1693 | ||
1694 | static void free_gcr3_tbl_level1(u64 *tbl) | ||
1695 | { | ||
1696 | u64 *ptr; | ||
1697 | int i; | ||
1698 | |||
1699 | for (i = 0; i < 512; ++i) { | ||
1700 | if (!(tbl[i] & GCR3_VALID)) | ||
1701 | continue; | ||
1702 | |||
1703 | ptr = __va(tbl[i] & PAGE_MASK); | ||
1704 | |||
1705 | free_page((unsigned long)ptr); | ||
1706 | } | ||
1707 | } | ||
1708 | |||
1709 | static void free_gcr3_tbl_level2(u64 *tbl) | ||
1710 | { | ||
1711 | u64 *ptr; | ||
1712 | int i; | ||
1713 | |||
1714 | for (i = 0; i < 512; ++i) { | ||
1715 | if (!(tbl[i] & GCR3_VALID)) | ||
1716 | continue; | ||
1717 | |||
1718 | ptr = __va(tbl[i] & PAGE_MASK); | ||
1719 | |||
1720 | free_gcr3_tbl_level1(ptr); | ||
1721 | } | ||
1722 | } | ||
1723 | |||
1724 | static void free_gcr3_table(struct protection_domain *domain) | ||
1725 | { | ||
1726 | if (domain->glx == 2) | ||
1727 | free_gcr3_tbl_level2(domain->gcr3_tbl); | ||
1728 | else if (domain->glx == 1) | ||
1729 | free_gcr3_tbl_level1(domain->gcr3_tbl); | ||
1730 | else if (domain->glx != 0) | ||
1731 | BUG(); | ||
1732 | |||
1733 | free_page((unsigned long)domain->gcr3_tbl); | ||
1734 | } | ||
1735 | |||
1499 | /* | 1736 | /* |
1500 | * Free a domain, only used if something went wrong in the | 1737 | * Free a domain, only used if something went wrong in the |
1501 | * allocation path and we need to free an already allocated page table | 1738 | * allocation path and we need to free an already allocated page table |
@@ -1582,20 +1819,52 @@ static bool dma_ops_domain(struct protection_domain *domain) | |||
1582 | 1819 | ||
1583 | static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats) | 1820 | static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats) |
1584 | { | 1821 | { |
1585 | u64 pte_root = virt_to_phys(domain->pt_root); | 1822 | u64 pte_root = 0; |
1586 | u32 flags = 0; | 1823 | u64 flags = 0; |
1824 | |||
1825 | if (domain->mode != PAGE_MODE_NONE) | ||
1826 | pte_root = virt_to_phys(domain->pt_root); | ||
1587 | 1827 | ||
1588 | pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK) | 1828 | pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK) |
1589 | << DEV_ENTRY_MODE_SHIFT; | 1829 | << DEV_ENTRY_MODE_SHIFT; |
1590 | pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV; | 1830 | pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV; |
1591 | 1831 | ||
1832 | flags = amd_iommu_dev_table[devid].data[1]; | ||
1833 | |||
1592 | if (ats) | 1834 | if (ats) |
1593 | flags |= DTE_FLAG_IOTLB; | 1835 | flags |= DTE_FLAG_IOTLB; |
1594 | 1836 | ||
1595 | amd_iommu_dev_table[devid].data[3] |= flags; | 1837 | if (domain->flags & PD_IOMMUV2_MASK) { |
1596 | amd_iommu_dev_table[devid].data[2] = domain->id; | 1838 | u64 gcr3 = __pa(domain->gcr3_tbl); |
1597 | amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root); | 1839 | u64 glx = domain->glx; |
1598 | amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root); | 1840 | u64 tmp; |
1841 | |||
1842 | pte_root |= DTE_FLAG_GV; | ||
1843 | pte_root |= (glx & DTE_GLX_MASK) << DTE_GLX_SHIFT; | ||
1844 | |||
1845 | /* First mask out possible old values for GCR3 table */ | ||
1846 | tmp = DTE_GCR3_VAL_B(~0ULL) << DTE_GCR3_SHIFT_B; | ||
1847 | flags &= ~tmp; | ||
1848 | |||
1849 | tmp = DTE_GCR3_VAL_C(~0ULL) << DTE_GCR3_SHIFT_C; | ||
1850 | flags &= ~tmp; | ||
1851 | |||
1852 | /* Encode GCR3 table into DTE */ | ||
1853 | tmp = DTE_GCR3_VAL_A(gcr3) << DTE_GCR3_SHIFT_A; | ||
1854 | pte_root |= tmp; | ||
1855 | |||
1856 | tmp = DTE_GCR3_VAL_B(gcr3) << DTE_GCR3_SHIFT_B; | ||
1857 | flags |= tmp; | ||
1858 | |||
1859 | tmp = DTE_GCR3_VAL_C(gcr3) << DTE_GCR3_SHIFT_C; | ||
1860 | flags |= tmp; | ||
1861 | } | ||
1862 | |||
1863 | flags &= ~(0xffffUL); | ||
1864 | flags |= domain->id; | ||
1865 | |||
1866 | amd_iommu_dev_table[devid].data[1] = flags; | ||
1867 | amd_iommu_dev_table[devid].data[0] = pte_root; | ||
1599 | } | 1868 | } |
1600 | 1869 | ||
1601 | static void clear_dte_entry(u16 devid) | 1870 | static void clear_dte_entry(u16 devid) |
@@ -1603,7 +1872,6 @@ static void clear_dte_entry(u16 devid) | |||
1603 | /* remove entry from the device table seen by the hardware */ | 1872 | /* remove entry from the device table seen by the hardware */ |
1604 | amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV; | 1873 | amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV; |
1605 | amd_iommu_dev_table[devid].data[1] = 0; | 1874 | amd_iommu_dev_table[devid].data[1] = 0; |
1606 | amd_iommu_dev_table[devid].data[2] = 0; | ||
1607 | 1875 | ||
1608 | amd_iommu_apply_erratum_63(devid); | 1876 | amd_iommu_apply_erratum_63(devid); |
1609 | } | 1877 | } |
@@ -1696,6 +1964,93 @@ out_unlock: | |||
1696 | return ret; | 1964 | return ret; |
1697 | } | 1965 | } |
1698 | 1966 | ||
1967 | |||
1968 | static void pdev_iommuv2_disable(struct pci_dev *pdev) | ||
1969 | { | ||
1970 | pci_disable_ats(pdev); | ||
1971 | pci_disable_pri(pdev); | ||
1972 | pci_disable_pasid(pdev); | ||
1973 | } | ||
1974 | |||
1975 | /* FIXME: Change generic reset-function to do the same */ | ||
1976 | static int pri_reset_while_enabled(struct pci_dev *pdev) | ||
1977 | { | ||
1978 | u16 control; | ||
1979 | int pos; | ||
1980 | |||
1981 | pos = pci_find_ext_capability(pdev, PCI_PRI_CAP); | ||
1982 | if (!pos) | ||
1983 | return -EINVAL; | ||
1984 | |||
1985 | pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control); | ||
1986 | control |= PCI_PRI_RESET; | ||
1987 | pci_write_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, control); | ||
1988 | |||
1989 | return 0; | ||
1990 | } | ||
1991 | |||
1992 | static int pdev_iommuv2_enable(struct pci_dev *pdev) | ||
1993 | { | ||
1994 | bool reset_enable; | ||
1995 | int reqs, ret; | ||
1996 | |||
1997 | /* FIXME: Hardcode number of outstanding requests for now */ | ||
1998 | reqs = 32; | ||
1999 | if (pdev_pri_erratum(pdev, AMD_PRI_DEV_ERRATUM_LIMIT_REQ_ONE)) | ||
2000 | reqs = 1; | ||
2001 | reset_enable = pdev_pri_erratum(pdev, AMD_PRI_DEV_ERRATUM_ENABLE_RESET); | ||
2002 | |||
2003 | /* Only allow access to user-accessible pages */ | ||
2004 | ret = pci_enable_pasid(pdev, 0); | ||
2005 | if (ret) | ||
2006 | goto out_err; | ||
2007 | |||
2008 | /* First reset the PRI state of the device */ | ||
2009 | ret = pci_reset_pri(pdev); | ||
2010 | if (ret) | ||
2011 | goto out_err; | ||
2012 | |||
2013 | /* Enable PRI */ | ||
2014 | ret = pci_enable_pri(pdev, reqs); | ||
2015 | if (ret) | ||
2016 | goto out_err; | ||
2017 | |||
2018 | if (reset_enable) { | ||
2019 | ret = pri_reset_while_enabled(pdev); | ||
2020 | if (ret) | ||
2021 | goto out_err; | ||
2022 | } | ||
2023 | |||
2024 | ret = pci_enable_ats(pdev, PAGE_SHIFT); | ||
2025 | if (ret) | ||
2026 | goto out_err; | ||
2027 | |||
2028 | return 0; | ||
2029 | |||
2030 | out_err: | ||
2031 | pci_disable_pri(pdev); | ||
2032 | pci_disable_pasid(pdev); | ||
2033 | |||
2034 | return ret; | ||
2035 | } | ||
2036 | |||
2037 | /* FIXME: Move this to PCI code */ | ||
2038 | #define PCI_PRI_TLP_OFF (1 << 2) | ||
2039 | |||
2040 | bool pci_pri_tlp_required(struct pci_dev *pdev) | ||
2041 | { | ||
2042 | u16 control; | ||
2043 | int pos; | ||
2044 | |||
2045 | pos = pci_find_ext_capability(pdev, PCI_PRI_CAP); | ||
2046 | if (!pos) | ||
2047 | return false; | ||
2048 | |||
2049 | pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control); | ||
2050 | |||
2051 | return (control & PCI_PRI_TLP_OFF) ? true : false; | ||
2052 | } | ||
2053 | |||
1699 | /* | 2054 | /* |
1700 | * If a device is not yet associated with a domain, this function does | 2055 | * If a device is not yet associated with a domain, this function does |
1701 | * assigns it visible for the hardware | 2056 | * assigns it visible for the hardware |
@@ -1710,7 +2065,18 @@ static int attach_device(struct device *dev, | |||
1710 | 2065 | ||
1711 | dev_data = get_dev_data(dev); | 2066 | dev_data = get_dev_data(dev); |
1712 | 2067 | ||
1713 | if (amd_iommu_iotlb_sup && pci_enable_ats(pdev, PAGE_SHIFT) == 0) { | 2068 | if (domain->flags & PD_IOMMUV2_MASK) { |
2069 | if (!dev_data->iommu_v2 || !dev_data->passthrough) | ||
2070 | return -EINVAL; | ||
2071 | |||
2072 | if (pdev_iommuv2_enable(pdev) != 0) | ||
2073 | return -EINVAL; | ||
2074 | |||
2075 | dev_data->ats.enabled = true; | ||
2076 | dev_data->ats.qdep = pci_ats_queue_depth(pdev); | ||
2077 | dev_data->pri_tlp = pci_pri_tlp_required(pdev); | ||
2078 | } else if (amd_iommu_iotlb_sup && | ||
2079 | pci_enable_ats(pdev, PAGE_SHIFT) == 0) { | ||
1714 | dev_data->ats.enabled = true; | 2080 | dev_data->ats.enabled = true; |
1715 | dev_data->ats.qdep = pci_ats_queue_depth(pdev); | 2081 | dev_data->ats.qdep = pci_ats_queue_depth(pdev); |
1716 | } | 2082 | } |
@@ -1760,7 +2126,7 @@ static void __detach_device(struct iommu_dev_data *dev_data) | |||
1760 | * passthrough domain if it is detached from any other domain. | 2126 | * passthrough domain if it is detached from any other domain. |
1761 | * Make sure we can deassign from the pt_domain itself. | 2127 | * Make sure we can deassign from the pt_domain itself. |
1762 | */ | 2128 | */ |
1763 | if (iommu_pass_through && | 2129 | if (dev_data->passthrough && |
1764 | (dev_data->domain == NULL && domain != pt_domain)) | 2130 | (dev_data->domain == NULL && domain != pt_domain)) |
1765 | __attach_device(dev_data, pt_domain); | 2131 | __attach_device(dev_data, pt_domain); |
1766 | } | 2132 | } |
@@ -1770,20 +2136,24 @@ static void __detach_device(struct iommu_dev_data *dev_data) | |||
1770 | */ | 2136 | */ |
1771 | static void detach_device(struct device *dev) | 2137 | static void detach_device(struct device *dev) |
1772 | { | 2138 | { |
2139 | struct protection_domain *domain; | ||
1773 | struct iommu_dev_data *dev_data; | 2140 | struct iommu_dev_data *dev_data; |
1774 | unsigned long flags; | 2141 | unsigned long flags; |
1775 | 2142 | ||
1776 | dev_data = get_dev_data(dev); | 2143 | dev_data = get_dev_data(dev); |
2144 | domain = dev_data->domain; | ||
1777 | 2145 | ||
1778 | /* lock device table */ | 2146 | /* lock device table */ |
1779 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); | 2147 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); |
1780 | __detach_device(dev_data); | 2148 | __detach_device(dev_data); |
1781 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | 2149 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); |
1782 | 2150 | ||
1783 | if (dev_data->ats.enabled) { | 2151 | if (domain->flags & PD_IOMMUV2_MASK) |
2152 | pdev_iommuv2_disable(to_pci_dev(dev)); | ||
2153 | else if (dev_data->ats.enabled) | ||
1784 | pci_disable_ats(to_pci_dev(dev)); | 2154 | pci_disable_ats(to_pci_dev(dev)); |
1785 | dev_data->ats.enabled = false; | 2155 | |
1786 | } | 2156 | dev_data->ats.enabled = false; |
1787 | } | 2157 | } |
1788 | 2158 | ||
1789 | /* | 2159 | /* |
@@ -1818,18 +2188,20 @@ static struct protection_domain *domain_for_device(struct device *dev) | |||
1818 | static int device_change_notifier(struct notifier_block *nb, | 2188 | static int device_change_notifier(struct notifier_block *nb, |
1819 | unsigned long action, void *data) | 2189 | unsigned long action, void *data) |
1820 | { | 2190 | { |
1821 | struct device *dev = data; | ||
1822 | u16 devid; | ||
1823 | struct protection_domain *domain; | ||
1824 | struct dma_ops_domain *dma_domain; | 2191 | struct dma_ops_domain *dma_domain; |
2192 | struct protection_domain *domain; | ||
2193 | struct iommu_dev_data *dev_data; | ||
2194 | struct device *dev = data; | ||
1825 | struct amd_iommu *iommu; | 2195 | struct amd_iommu *iommu; |
1826 | unsigned long flags; | 2196 | unsigned long flags; |
2197 | u16 devid; | ||
1827 | 2198 | ||
1828 | if (!check_device(dev)) | 2199 | if (!check_device(dev)) |
1829 | return 0; | 2200 | return 0; |
1830 | 2201 | ||
1831 | devid = get_device_id(dev); | 2202 | devid = get_device_id(dev); |
1832 | iommu = amd_iommu_rlookup_table[devid]; | 2203 | iommu = amd_iommu_rlookup_table[devid]; |
2204 | dev_data = get_dev_data(dev); | ||
1833 | 2205 | ||
1834 | switch (action) { | 2206 | switch (action) { |
1835 | case BUS_NOTIFY_UNBOUND_DRIVER: | 2207 | case BUS_NOTIFY_UNBOUND_DRIVER: |
@@ -1838,7 +2210,7 @@ static int device_change_notifier(struct notifier_block *nb, | |||
1838 | 2210 | ||
1839 | if (!domain) | 2211 | if (!domain) |
1840 | goto out; | 2212 | goto out; |
1841 | if (iommu_pass_through) | 2213 | if (dev_data->passthrough) |
1842 | break; | 2214 | break; |
1843 | detach_device(dev); | 2215 | detach_device(dev); |
1844 | break; | 2216 | break; |
@@ -2434,8 +2806,9 @@ static int amd_iommu_dma_supported(struct device *dev, u64 mask) | |||
2434 | */ | 2806 | */ |
2435 | static void prealloc_protection_domains(void) | 2807 | static void prealloc_protection_domains(void) |
2436 | { | 2808 | { |
2437 | struct pci_dev *dev = NULL; | 2809 | struct iommu_dev_data *dev_data; |
2438 | struct dma_ops_domain *dma_dom; | 2810 | struct dma_ops_domain *dma_dom; |
2811 | struct pci_dev *dev = NULL; | ||
2439 | u16 devid; | 2812 | u16 devid; |
2440 | 2813 | ||
2441 | for_each_pci_dev(dev) { | 2814 | for_each_pci_dev(dev) { |
@@ -2444,6 +2817,16 @@ static void prealloc_protection_domains(void) | |||
2444 | if (!check_device(&dev->dev)) | 2817 | if (!check_device(&dev->dev)) |
2445 | continue; | 2818 | continue; |
2446 | 2819 | ||
2820 | dev_data = get_dev_data(&dev->dev); | ||
2821 | if (!amd_iommu_force_isolation && dev_data->iommu_v2) { | ||
2822 | /* Make sure passthrough domain is allocated */ | ||
2823 | alloc_passthrough_domain(); | ||
2824 | dev_data->passthrough = true; | ||
2825 | attach_device(&dev->dev, pt_domain); | ||
2826 | pr_info("AMD-Vi: Using passthough domain for device %s\n", | ||
2827 | dev_name(&dev->dev)); | ||
2828 | } | ||
2829 | |||
2447 | /* Is there already any domain for it? */ | 2830 | /* Is there already any domain for it? */ |
2448 | if (domain_for_device(&dev->dev)) | 2831 | if (domain_for_device(&dev->dev)) |
2449 | continue; | 2832 | continue; |
@@ -2474,6 +2857,7 @@ static struct dma_map_ops amd_iommu_dma_ops = { | |||
2474 | 2857 | ||
2475 | static unsigned device_dma_ops_init(void) | 2858 | static unsigned device_dma_ops_init(void) |
2476 | { | 2859 | { |
2860 | struct iommu_dev_data *dev_data; | ||
2477 | struct pci_dev *pdev = NULL; | 2861 | struct pci_dev *pdev = NULL; |
2478 | unsigned unhandled = 0; | 2862 | unsigned unhandled = 0; |
2479 | 2863 | ||
@@ -2483,7 +2867,12 @@ static unsigned device_dma_ops_init(void) | |||
2483 | continue; | 2867 | continue; |
2484 | } | 2868 | } |
2485 | 2869 | ||
2486 | pdev->dev.archdata.dma_ops = &amd_iommu_dma_ops; | 2870 | dev_data = get_dev_data(&pdev->dev); |
2871 | |||
2872 | if (!dev_data->passthrough) | ||
2873 | pdev->dev.archdata.dma_ops = &amd_iommu_dma_ops; | ||
2874 | else | ||
2875 | pdev->dev.archdata.dma_ops = &nommu_dma_ops; | ||
2487 | } | 2876 | } |
2488 | 2877 | ||
2489 | return unhandled; | 2878 | return unhandled; |
@@ -2610,6 +2999,20 @@ out_err: | |||
2610 | return NULL; | 2999 | return NULL; |
2611 | } | 3000 | } |
2612 | 3001 | ||
3002 | static int __init alloc_passthrough_domain(void) | ||
3003 | { | ||
3004 | if (pt_domain != NULL) | ||
3005 | return 0; | ||
3006 | |||
3007 | /* allocate passthrough domain */ | ||
3008 | pt_domain = protection_domain_alloc(); | ||
3009 | if (!pt_domain) | ||
3010 | return -ENOMEM; | ||
3011 | |||
3012 | pt_domain->mode = PAGE_MODE_NONE; | ||
3013 | |||
3014 | return 0; | ||
3015 | } | ||
2613 | static int amd_iommu_domain_init(struct iommu_domain *dom) | 3016 | static int amd_iommu_domain_init(struct iommu_domain *dom) |
2614 | { | 3017 | { |
2615 | struct protection_domain *domain; | 3018 | struct protection_domain *domain; |
@@ -2623,6 +3026,8 @@ static int amd_iommu_domain_init(struct iommu_domain *dom) | |||
2623 | if (!domain->pt_root) | 3026 | if (!domain->pt_root) |
2624 | goto out_free; | 3027 | goto out_free; |
2625 | 3028 | ||
3029 | domain->iommu_domain = dom; | ||
3030 | |||
2626 | dom->priv = domain; | 3031 | dom->priv = domain; |
2627 | 3032 | ||
2628 | return 0; | 3033 | return 0; |
@@ -2645,7 +3050,11 @@ static void amd_iommu_domain_destroy(struct iommu_domain *dom) | |||
2645 | 3050 | ||
2646 | BUG_ON(domain->dev_cnt != 0); | 3051 | BUG_ON(domain->dev_cnt != 0); |
2647 | 3052 | ||
2648 | free_pagetable(domain); | 3053 | if (domain->mode != PAGE_MODE_NONE) |
3054 | free_pagetable(domain); | ||
3055 | |||
3056 | if (domain->flags & PD_IOMMUV2_MASK) | ||
3057 | free_gcr3_table(domain); | ||
2649 | 3058 | ||
2650 | protection_domain_free(domain); | 3059 | protection_domain_free(domain); |
2651 | 3060 | ||
@@ -2702,13 +3111,15 @@ static int amd_iommu_attach_device(struct iommu_domain *dom, | |||
2702 | } | 3111 | } |
2703 | 3112 | ||
2704 | static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, | 3113 | static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, |
2705 | phys_addr_t paddr, int gfp_order, int iommu_prot) | 3114 | phys_addr_t paddr, size_t page_size, int iommu_prot) |
2706 | { | 3115 | { |
2707 | unsigned long page_size = 0x1000UL << gfp_order; | ||
2708 | struct protection_domain *domain = dom->priv; | 3116 | struct protection_domain *domain = dom->priv; |
2709 | int prot = 0; | 3117 | int prot = 0; |
2710 | int ret; | 3118 | int ret; |
2711 | 3119 | ||
3120 | if (domain->mode == PAGE_MODE_NONE) | ||
3121 | return -EINVAL; | ||
3122 | |||
2712 | if (iommu_prot & IOMMU_READ) | 3123 | if (iommu_prot & IOMMU_READ) |
2713 | prot |= IOMMU_PROT_IR; | 3124 | prot |= IOMMU_PROT_IR; |
2714 | if (iommu_prot & IOMMU_WRITE) | 3125 | if (iommu_prot & IOMMU_WRITE) |
@@ -2721,13 +3132,14 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, | |||
2721 | return ret; | 3132 | return ret; |
2722 | } | 3133 | } |
2723 | 3134 | ||
2724 | static int amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, | 3135 | static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, |
2725 | int gfp_order) | 3136 | size_t page_size) |
2726 | { | 3137 | { |
2727 | struct protection_domain *domain = dom->priv; | 3138 | struct protection_domain *domain = dom->priv; |
2728 | unsigned long page_size, unmap_size; | 3139 | size_t unmap_size; |
2729 | 3140 | ||
2730 | page_size = 0x1000UL << gfp_order; | 3141 | if (domain->mode == PAGE_MODE_NONE) |
3142 | return -EINVAL; | ||
2731 | 3143 | ||
2732 | mutex_lock(&domain->api_lock); | 3144 | mutex_lock(&domain->api_lock); |
2733 | unmap_size = iommu_unmap_page(domain, iova, page_size); | 3145 | unmap_size = iommu_unmap_page(domain, iova, page_size); |
@@ -2735,7 +3147,7 @@ static int amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, | |||
2735 | 3147 | ||
2736 | domain_flush_tlb_pde(domain); | 3148 | domain_flush_tlb_pde(domain); |
2737 | 3149 | ||
2738 | return get_order(unmap_size); | 3150 | return unmap_size; |
2739 | } | 3151 | } |
2740 | 3152 | ||
2741 | static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, | 3153 | static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, |
@@ -2746,6 +3158,9 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, | |||
2746 | phys_addr_t paddr; | 3158 | phys_addr_t paddr; |
2747 | u64 *pte, __pte; | 3159 | u64 *pte, __pte; |
2748 | 3160 | ||
3161 | if (domain->mode == PAGE_MODE_NONE) | ||
3162 | return iova; | ||
3163 | |||
2749 | pte = fetch_pte(domain, iova); | 3164 | pte = fetch_pte(domain, iova); |
2750 | 3165 | ||
2751 | if (!pte || !IOMMU_PTE_PRESENT(*pte)) | 3166 | if (!pte || !IOMMU_PTE_PRESENT(*pte)) |
@@ -2782,6 +3197,7 @@ static struct iommu_ops amd_iommu_ops = { | |||
2782 | .unmap = amd_iommu_unmap, | 3197 | .unmap = amd_iommu_unmap, |
2783 | .iova_to_phys = amd_iommu_iova_to_phys, | 3198 | .iova_to_phys = amd_iommu_iova_to_phys, |
2784 | .domain_has_cap = amd_iommu_domain_has_cap, | 3199 | .domain_has_cap = amd_iommu_domain_has_cap, |
3200 | .pgsize_bitmap = AMD_IOMMU_PGSIZES, | ||
2785 | }; | 3201 | }; |
2786 | 3202 | ||
2787 | /***************************************************************************** | 3203 | /***************************************************************************** |
@@ -2796,21 +3212,23 @@ static struct iommu_ops amd_iommu_ops = { | |||
2796 | 3212 | ||
2797 | int __init amd_iommu_init_passthrough(void) | 3213 | int __init amd_iommu_init_passthrough(void) |
2798 | { | 3214 | { |
2799 | struct amd_iommu *iommu; | 3215 | struct iommu_dev_data *dev_data; |
2800 | struct pci_dev *dev = NULL; | 3216 | struct pci_dev *dev = NULL; |
3217 | struct amd_iommu *iommu; | ||
2801 | u16 devid; | 3218 | u16 devid; |
3219 | int ret; | ||
2802 | 3220 | ||
2803 | /* allocate passthrough domain */ | 3221 | ret = alloc_passthrough_domain(); |
2804 | pt_domain = protection_domain_alloc(); | 3222 | if (ret) |
2805 | if (!pt_domain) | 3223 | return ret; |
2806 | return -ENOMEM; | ||
2807 | |||
2808 | pt_domain->mode |= PAGE_MODE_NONE; | ||
2809 | 3224 | ||
2810 | for_each_pci_dev(dev) { | 3225 | for_each_pci_dev(dev) { |
2811 | if (!check_device(&dev->dev)) | 3226 | if (!check_device(&dev->dev)) |
2812 | continue; | 3227 | continue; |
2813 | 3228 | ||
3229 | dev_data = get_dev_data(&dev->dev); | ||
3230 | dev_data->passthrough = true; | ||
3231 | |||
2814 | devid = get_device_id(&dev->dev); | 3232 | devid = get_device_id(&dev->dev); |
2815 | 3233 | ||
2816 | iommu = amd_iommu_rlookup_table[devid]; | 3234 | iommu = amd_iommu_rlookup_table[devid]; |
@@ -2824,3 +3242,326 @@ int __init amd_iommu_init_passthrough(void) | |||
2824 | 3242 | ||
2825 | return 0; | 3243 | return 0; |
2826 | } | 3244 | } |
3245 | |||
3246 | /* IOMMUv2 specific functions */ | ||
3247 | int amd_iommu_register_ppr_notifier(struct notifier_block *nb) | ||
3248 | { | ||
3249 | return atomic_notifier_chain_register(&ppr_notifier, nb); | ||
3250 | } | ||
3251 | EXPORT_SYMBOL(amd_iommu_register_ppr_notifier); | ||
3252 | |||
3253 | int amd_iommu_unregister_ppr_notifier(struct notifier_block *nb) | ||
3254 | { | ||
3255 | return atomic_notifier_chain_unregister(&ppr_notifier, nb); | ||
3256 | } | ||
3257 | EXPORT_SYMBOL(amd_iommu_unregister_ppr_notifier); | ||
3258 | |||
3259 | void amd_iommu_domain_direct_map(struct iommu_domain *dom) | ||
3260 | { | ||
3261 | struct protection_domain *domain = dom->priv; | ||
3262 | unsigned long flags; | ||
3263 | |||
3264 | spin_lock_irqsave(&domain->lock, flags); | ||
3265 | |||
3266 | /* Update data structure */ | ||
3267 | domain->mode = PAGE_MODE_NONE; | ||
3268 | domain->updated = true; | ||
3269 | |||
3270 | /* Make changes visible to IOMMUs */ | ||
3271 | update_domain(domain); | ||
3272 | |||
3273 | /* Page-table is not visible to IOMMU anymore, so free it */ | ||
3274 | free_pagetable(domain); | ||
3275 | |||
3276 | spin_unlock_irqrestore(&domain->lock, flags); | ||
3277 | } | ||
3278 | EXPORT_SYMBOL(amd_iommu_domain_direct_map); | ||
3279 | |||
3280 | int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids) | ||
3281 | { | ||
3282 | struct protection_domain *domain = dom->priv; | ||
3283 | unsigned long flags; | ||
3284 | int levels, ret; | ||
3285 | |||
3286 | if (pasids <= 0 || pasids > (PASID_MASK + 1)) | ||
3287 | return -EINVAL; | ||
3288 | |||
3289 | /* Number of GCR3 table levels required */ | ||
3290 | for (levels = 0; (pasids - 1) & ~0x1ff; pasids >>= 9) | ||
3291 | levels += 1; | ||
3292 | |||
3293 | if (levels > amd_iommu_max_glx_val) | ||
3294 | return -EINVAL; | ||
3295 | |||
3296 | spin_lock_irqsave(&domain->lock, flags); | ||
3297 | |||
3298 | /* | ||
3299 | * Save us all sanity checks whether devices already in the | ||
3300 | * domain support IOMMUv2. Just force that the domain has no | ||
3301 | * devices attached when it is switched into IOMMUv2 mode. | ||
3302 | */ | ||
3303 | ret = -EBUSY; | ||
3304 | if (domain->dev_cnt > 0 || domain->flags & PD_IOMMUV2_MASK) | ||
3305 | goto out; | ||
3306 | |||
3307 | ret = -ENOMEM; | ||
3308 | domain->gcr3_tbl = (void *)get_zeroed_page(GFP_ATOMIC); | ||
3309 | if (domain->gcr3_tbl == NULL) | ||
3310 | goto out; | ||
3311 | |||
3312 | domain->glx = levels; | ||
3313 | domain->flags |= PD_IOMMUV2_MASK; | ||
3314 | domain->updated = true; | ||
3315 | |||
3316 | update_domain(domain); | ||
3317 | |||
3318 | ret = 0; | ||
3319 | |||
3320 | out: | ||
3321 | spin_unlock_irqrestore(&domain->lock, flags); | ||
3322 | |||
3323 | return ret; | ||
3324 | } | ||
3325 | EXPORT_SYMBOL(amd_iommu_domain_enable_v2); | ||
3326 | |||
3327 | static int __flush_pasid(struct protection_domain *domain, int pasid, | ||
3328 | u64 address, bool size) | ||
3329 | { | ||
3330 | struct iommu_dev_data *dev_data; | ||
3331 | struct iommu_cmd cmd; | ||
3332 | int i, ret; | ||
3333 | |||
3334 | if (!(domain->flags & PD_IOMMUV2_MASK)) | ||
3335 | return -EINVAL; | ||
3336 | |||
3337 | build_inv_iommu_pasid(&cmd, domain->id, pasid, address, size); | ||
3338 | |||
3339 | /* | ||
3340 | * IOMMU TLB needs to be flushed before Device TLB to | ||
3341 | * prevent device TLB refill from IOMMU TLB | ||
3342 | */ | ||
3343 | for (i = 0; i < amd_iommus_present; ++i) { | ||
3344 | if (domain->dev_iommu[i] == 0) | ||
3345 | continue; | ||
3346 | |||
3347 | ret = iommu_queue_command(amd_iommus[i], &cmd); | ||
3348 | if (ret != 0) | ||
3349 | goto out; | ||
3350 | } | ||
3351 | |||
3352 | /* Wait until IOMMU TLB flushes are complete */ | ||
3353 | domain_flush_complete(domain); | ||
3354 | |||
3355 | /* Now flush device TLBs */ | ||
3356 | list_for_each_entry(dev_data, &domain->dev_list, list) { | ||
3357 | struct amd_iommu *iommu; | ||
3358 | int qdep; | ||
3359 | |||
3360 | BUG_ON(!dev_data->ats.enabled); | ||
3361 | |||
3362 | qdep = dev_data->ats.qdep; | ||
3363 | iommu = amd_iommu_rlookup_table[dev_data->devid]; | ||
3364 | |||
3365 | build_inv_iotlb_pasid(&cmd, dev_data->devid, pasid, | ||
3366 | qdep, address, size); | ||
3367 | |||
3368 | ret = iommu_queue_command(iommu, &cmd); | ||
3369 | if (ret != 0) | ||
3370 | goto out; | ||
3371 | } | ||
3372 | |||
3373 | /* Wait until all device TLBs are flushed */ | ||
3374 | domain_flush_complete(domain); | ||
3375 | |||
3376 | ret = 0; | ||
3377 | |||
3378 | out: | ||
3379 | |||
3380 | return ret; | ||
3381 | } | ||
3382 | |||
3383 | static int __amd_iommu_flush_page(struct protection_domain *domain, int pasid, | ||
3384 | u64 address) | ||
3385 | { | ||
3386 | INC_STATS_COUNTER(invalidate_iotlb); | ||
3387 | |||
3388 | return __flush_pasid(domain, pasid, address, false); | ||
3389 | } | ||
3390 | |||
3391 | int amd_iommu_flush_page(struct iommu_domain *dom, int pasid, | ||
3392 | u64 address) | ||
3393 | { | ||
3394 | struct protection_domain *domain = dom->priv; | ||
3395 | unsigned long flags; | ||
3396 | int ret; | ||
3397 | |||
3398 | spin_lock_irqsave(&domain->lock, flags); | ||
3399 | ret = __amd_iommu_flush_page(domain, pasid, address); | ||
3400 | spin_unlock_irqrestore(&domain->lock, flags); | ||
3401 | |||
3402 | return ret; | ||
3403 | } | ||
3404 | EXPORT_SYMBOL(amd_iommu_flush_page); | ||
3405 | |||
3406 | static int __amd_iommu_flush_tlb(struct protection_domain *domain, int pasid) | ||
3407 | { | ||
3408 | INC_STATS_COUNTER(invalidate_iotlb_all); | ||
3409 | |||
3410 | return __flush_pasid(domain, pasid, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, | ||
3411 | true); | ||
3412 | } | ||
3413 | |||
3414 | int amd_iommu_flush_tlb(struct iommu_domain *dom, int pasid) | ||
3415 | { | ||
3416 | struct protection_domain *domain = dom->priv; | ||
3417 | unsigned long flags; | ||
3418 | int ret; | ||
3419 | |||
3420 | spin_lock_irqsave(&domain->lock, flags); | ||
3421 | ret = __amd_iommu_flush_tlb(domain, pasid); | ||
3422 | spin_unlock_irqrestore(&domain->lock, flags); | ||
3423 | |||
3424 | return ret; | ||
3425 | } | ||
3426 | EXPORT_SYMBOL(amd_iommu_flush_tlb); | ||
3427 | |||
3428 | static u64 *__get_gcr3_pte(u64 *root, int level, int pasid, bool alloc) | ||
3429 | { | ||
3430 | int index; | ||
3431 | u64 *pte; | ||
3432 | |||
3433 | while (true) { | ||
3434 | |||
3435 | index = (pasid >> (9 * level)) & 0x1ff; | ||
3436 | pte = &root[index]; | ||
3437 | |||
3438 | if (level == 0) | ||
3439 | break; | ||
3440 | |||
3441 | if (!(*pte & GCR3_VALID)) { | ||
3442 | if (!alloc) | ||
3443 | return NULL; | ||
3444 | |||
3445 | root = (void *)get_zeroed_page(GFP_ATOMIC); | ||
3446 | if (root == NULL) | ||
3447 | return NULL; | ||
3448 | |||
3449 | *pte = __pa(root) | GCR3_VALID; | ||
3450 | } | ||
3451 | |||
3452 | root = __va(*pte & PAGE_MASK); | ||
3453 | |||
3454 | level -= 1; | ||
3455 | } | ||
3456 | |||
3457 | return pte; | ||
3458 | } | ||
3459 | |||
3460 | static int __set_gcr3(struct protection_domain *domain, int pasid, | ||
3461 | unsigned long cr3) | ||
3462 | { | ||
3463 | u64 *pte; | ||
3464 | |||
3465 | if (domain->mode != PAGE_MODE_NONE) | ||
3466 | return -EINVAL; | ||
3467 | |||
3468 | pte = __get_gcr3_pte(domain->gcr3_tbl, domain->glx, pasid, true); | ||
3469 | if (pte == NULL) | ||
3470 | return -ENOMEM; | ||
3471 | |||
3472 | *pte = (cr3 & PAGE_MASK) | GCR3_VALID; | ||
3473 | |||
3474 | return __amd_iommu_flush_tlb(domain, pasid); | ||
3475 | } | ||
3476 | |||
3477 | static int __clear_gcr3(struct protection_domain *domain, int pasid) | ||
3478 | { | ||
3479 | u64 *pte; | ||
3480 | |||
3481 | if (domain->mode != PAGE_MODE_NONE) | ||
3482 | return -EINVAL; | ||
3483 | |||
3484 | pte = __get_gcr3_pte(domain->gcr3_tbl, domain->glx, pasid, false); | ||
3485 | if (pte == NULL) | ||
3486 | return 0; | ||
3487 | |||
3488 | *pte = 0; | ||
3489 | |||
3490 | return __amd_iommu_flush_tlb(domain, pasid); | ||
3491 | } | ||
3492 | |||
3493 | int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid, | ||
3494 | unsigned long cr3) | ||
3495 | { | ||
3496 | struct protection_domain *domain = dom->priv; | ||
3497 | unsigned long flags; | ||
3498 | int ret; | ||
3499 | |||
3500 | spin_lock_irqsave(&domain->lock, flags); | ||
3501 | ret = __set_gcr3(domain, pasid, cr3); | ||
3502 | spin_unlock_irqrestore(&domain->lock, flags); | ||
3503 | |||
3504 | return ret; | ||
3505 | } | ||
3506 | EXPORT_SYMBOL(amd_iommu_domain_set_gcr3); | ||
3507 | |||
3508 | int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid) | ||
3509 | { | ||
3510 | struct protection_domain *domain = dom->priv; | ||
3511 | unsigned long flags; | ||
3512 | int ret; | ||
3513 | |||
3514 | spin_lock_irqsave(&domain->lock, flags); | ||
3515 | ret = __clear_gcr3(domain, pasid); | ||
3516 | spin_unlock_irqrestore(&domain->lock, flags); | ||
3517 | |||
3518 | return ret; | ||
3519 | } | ||
3520 | EXPORT_SYMBOL(amd_iommu_domain_clear_gcr3); | ||
3521 | |||
3522 | int amd_iommu_complete_ppr(struct pci_dev *pdev, int pasid, | ||
3523 | int status, int tag) | ||
3524 | { | ||
3525 | struct iommu_dev_data *dev_data; | ||
3526 | struct amd_iommu *iommu; | ||
3527 | struct iommu_cmd cmd; | ||
3528 | |||
3529 | INC_STATS_COUNTER(complete_ppr); | ||
3530 | |||
3531 | dev_data = get_dev_data(&pdev->dev); | ||
3532 | iommu = amd_iommu_rlookup_table[dev_data->devid]; | ||
3533 | |||
3534 | build_complete_ppr(&cmd, dev_data->devid, pasid, status, | ||
3535 | tag, dev_data->pri_tlp); | ||
3536 | |||
3537 | return iommu_queue_command(iommu, &cmd); | ||
3538 | } | ||
3539 | EXPORT_SYMBOL(amd_iommu_complete_ppr); | ||
3540 | |||
3541 | struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev) | ||
3542 | { | ||
3543 | struct protection_domain *domain; | ||
3544 | |||
3545 | domain = get_domain(&pdev->dev); | ||
3546 | if (IS_ERR(domain)) | ||
3547 | return NULL; | ||
3548 | |||
3549 | /* Only return IOMMUv2 domains */ | ||
3550 | if (!(domain->flags & PD_IOMMUV2_MASK)) | ||
3551 | return NULL; | ||
3552 | |||
3553 | return domain->iommu_domain; | ||
3554 | } | ||
3555 | EXPORT_SYMBOL(amd_iommu_get_v2_domain); | ||
3556 | |||
3557 | void amd_iommu_enable_device_erratum(struct pci_dev *pdev, u32 erratum) | ||
3558 | { | ||
3559 | struct iommu_dev_data *dev_data; | ||
3560 | |||
3561 | if (!amd_iommu_v2_supported()) | ||
3562 | return; | ||
3563 | |||
3564 | dev_data = get_dev_data(&pdev->dev); | ||
3565 | dev_data->errata |= (1 << erratum); | ||
3566 | } | ||
3567 | EXPORT_SYMBOL(amd_iommu_enable_device_erratum); | ||
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 82d2410f4205..c7a5d7e14547 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/msi.h> | 26 | #include <linux/msi.h> |
27 | #include <linux/amd-iommu.h> | 27 | #include <linux/amd-iommu.h> |
28 | #include <linux/export.h> | ||
28 | #include <asm/pci-direct.h> | 29 | #include <asm/pci-direct.h> |
29 | #include <asm/iommu.h> | 30 | #include <asm/iommu.h> |
30 | #include <asm/gart.h> | 31 | #include <asm/gart.h> |
@@ -141,6 +142,12 @@ int amd_iommus_present; | |||
141 | bool amd_iommu_np_cache __read_mostly; | 142 | bool amd_iommu_np_cache __read_mostly; |
142 | bool amd_iommu_iotlb_sup __read_mostly = true; | 143 | bool amd_iommu_iotlb_sup __read_mostly = true; |
143 | 144 | ||
145 | u32 amd_iommu_max_pasids __read_mostly = ~0; | ||
146 | |||
147 | bool amd_iommu_v2_present __read_mostly; | ||
148 | |||
149 | bool amd_iommu_force_isolation __read_mostly; | ||
150 | |||
144 | /* | 151 | /* |
145 | * The ACPI table parsing functions set this variable on an error | 152 | * The ACPI table parsing functions set this variable on an error |
146 | */ | 153 | */ |
@@ -581,21 +588,69 @@ static void __init free_event_buffer(struct amd_iommu *iommu) | |||
581 | free_pages((unsigned long)iommu->evt_buf, get_order(EVT_BUFFER_SIZE)); | 588 | free_pages((unsigned long)iommu->evt_buf, get_order(EVT_BUFFER_SIZE)); |
582 | } | 589 | } |
583 | 590 | ||
591 | /* allocates the memory where the IOMMU will log its events to */ | ||
592 | static u8 * __init alloc_ppr_log(struct amd_iommu *iommu) | ||
593 | { | ||
594 | iommu->ppr_log = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, | ||
595 | get_order(PPR_LOG_SIZE)); | ||
596 | |||
597 | if (iommu->ppr_log == NULL) | ||
598 | return NULL; | ||
599 | |||
600 | return iommu->ppr_log; | ||
601 | } | ||
602 | |||
603 | static void iommu_enable_ppr_log(struct amd_iommu *iommu) | ||
604 | { | ||
605 | u64 entry; | ||
606 | |||
607 | if (iommu->ppr_log == NULL) | ||
608 | return; | ||
609 | |||
610 | entry = (u64)virt_to_phys(iommu->ppr_log) | PPR_LOG_SIZE_512; | ||
611 | |||
612 | memcpy_toio(iommu->mmio_base + MMIO_PPR_LOG_OFFSET, | ||
613 | &entry, sizeof(entry)); | ||
614 | |||
615 | /* set head and tail to zero manually */ | ||
616 | writel(0x00, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); | ||
617 | writel(0x00, iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); | ||
618 | |||
619 | iommu_feature_enable(iommu, CONTROL_PPFLOG_EN); | ||
620 | iommu_feature_enable(iommu, CONTROL_PPR_EN); | ||
621 | } | ||
622 | |||
623 | static void __init free_ppr_log(struct amd_iommu *iommu) | ||
624 | { | ||
625 | if (iommu->ppr_log == NULL) | ||
626 | return; | ||
627 | |||
628 | free_pages((unsigned long)iommu->ppr_log, get_order(PPR_LOG_SIZE)); | ||
629 | } | ||
630 | |||
631 | static void iommu_enable_gt(struct amd_iommu *iommu) | ||
632 | { | ||
633 | if (!iommu_feature(iommu, FEATURE_GT)) | ||
634 | return; | ||
635 | |||
636 | iommu_feature_enable(iommu, CONTROL_GT_EN); | ||
637 | } | ||
638 | |||
584 | /* sets a specific bit in the device table entry. */ | 639 | /* sets a specific bit in the device table entry. */ |
585 | static void set_dev_entry_bit(u16 devid, u8 bit) | 640 | static void set_dev_entry_bit(u16 devid, u8 bit) |
586 | { | 641 | { |
587 | int i = (bit >> 5) & 0x07; | 642 | int i = (bit >> 6) & 0x03; |
588 | int _bit = bit & 0x1f; | 643 | int _bit = bit & 0x3f; |
589 | 644 | ||
590 | amd_iommu_dev_table[devid].data[i] |= (1 << _bit); | 645 | amd_iommu_dev_table[devid].data[i] |= (1UL << _bit); |
591 | } | 646 | } |
592 | 647 | ||
593 | static int get_dev_entry_bit(u16 devid, u8 bit) | 648 | static int get_dev_entry_bit(u16 devid, u8 bit) |
594 | { | 649 | { |
595 | int i = (bit >> 5) & 0x07; | 650 | int i = (bit >> 6) & 0x03; |
596 | int _bit = bit & 0x1f; | 651 | int _bit = bit & 0x3f; |
597 | 652 | ||
598 | return (amd_iommu_dev_table[devid].data[i] & (1 << _bit)) >> _bit; | 653 | return (amd_iommu_dev_table[devid].data[i] & (1UL << _bit)) >> _bit; |
599 | } | 654 | } |
600 | 655 | ||
601 | 656 | ||
@@ -699,6 +754,32 @@ static void __init init_iommu_from_pci(struct amd_iommu *iommu) | |||
699 | 754 | ||
700 | iommu->features = ((u64)high << 32) | low; | 755 | iommu->features = ((u64)high << 32) | low; |
701 | 756 | ||
757 | if (iommu_feature(iommu, FEATURE_GT)) { | ||
758 | int glxval; | ||
759 | u32 pasids; | ||
760 | u64 shift; | ||
761 | |||
762 | shift = iommu->features & FEATURE_PASID_MASK; | ||
763 | shift >>= FEATURE_PASID_SHIFT; | ||
764 | pasids = (1 << shift); | ||
765 | |||
766 | amd_iommu_max_pasids = min(amd_iommu_max_pasids, pasids); | ||
767 | |||
768 | glxval = iommu->features & FEATURE_GLXVAL_MASK; | ||
769 | glxval >>= FEATURE_GLXVAL_SHIFT; | ||
770 | |||
771 | if (amd_iommu_max_glx_val == -1) | ||
772 | amd_iommu_max_glx_val = glxval; | ||
773 | else | ||
774 | amd_iommu_max_glx_val = min(amd_iommu_max_glx_val, glxval); | ||
775 | } | ||
776 | |||
777 | if (iommu_feature(iommu, FEATURE_GT) && | ||
778 | iommu_feature(iommu, FEATURE_PPR)) { | ||
779 | iommu->is_iommu_v2 = true; | ||
780 | amd_iommu_v2_present = true; | ||
781 | } | ||
782 | |||
702 | if (!is_rd890_iommu(iommu->dev)) | 783 | if (!is_rd890_iommu(iommu->dev)) |
703 | return; | 784 | return; |
704 | 785 | ||
@@ -901,6 +982,7 @@ static void __init free_iommu_one(struct amd_iommu *iommu) | |||
901 | { | 982 | { |
902 | free_command_buffer(iommu); | 983 | free_command_buffer(iommu); |
903 | free_event_buffer(iommu); | 984 | free_event_buffer(iommu); |
985 | free_ppr_log(iommu); | ||
904 | iommu_unmap_mmio_space(iommu); | 986 | iommu_unmap_mmio_space(iommu); |
905 | } | 987 | } |
906 | 988 | ||
@@ -964,6 +1046,12 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h) | |||
964 | init_iommu_from_acpi(iommu, h); | 1046 | init_iommu_from_acpi(iommu, h); |
965 | init_iommu_devices(iommu); | 1047 | init_iommu_devices(iommu); |
966 | 1048 | ||
1049 | if (iommu_feature(iommu, FEATURE_PPR)) { | ||
1050 | iommu->ppr_log = alloc_ppr_log(iommu); | ||
1051 | if (!iommu->ppr_log) | ||
1052 | return -ENOMEM; | ||
1053 | } | ||
1054 | |||
967 | if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE)) | 1055 | if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE)) |
968 | amd_iommu_np_cache = true; | 1056 | amd_iommu_np_cache = true; |
969 | 1057 | ||
@@ -1050,6 +1138,9 @@ static int iommu_setup_msi(struct amd_iommu *iommu) | |||
1050 | iommu->int_enabled = true; | 1138 | iommu->int_enabled = true; |
1051 | iommu_feature_enable(iommu, CONTROL_EVT_INT_EN); | 1139 | iommu_feature_enable(iommu, CONTROL_EVT_INT_EN); |
1052 | 1140 | ||
1141 | if (iommu->ppr_log != NULL) | ||
1142 | iommu_feature_enable(iommu, CONTROL_PPFINT_EN); | ||
1143 | |||
1053 | return 0; | 1144 | return 0; |
1054 | } | 1145 | } |
1055 | 1146 | ||
@@ -1274,6 +1365,8 @@ static void enable_iommus(void) | |||
1274 | iommu_set_device_table(iommu); | 1365 | iommu_set_device_table(iommu); |
1275 | iommu_enable_command_buffer(iommu); | 1366 | iommu_enable_command_buffer(iommu); |
1276 | iommu_enable_event_buffer(iommu); | 1367 | iommu_enable_event_buffer(iommu); |
1368 | iommu_enable_ppr_log(iommu); | ||
1369 | iommu_enable_gt(iommu); | ||
1277 | iommu_set_exclusion_range(iommu); | 1370 | iommu_set_exclusion_range(iommu); |
1278 | iommu_init_msi(iommu); | 1371 | iommu_init_msi(iommu); |
1279 | iommu_enable(iommu); | 1372 | iommu_enable(iommu); |
@@ -1560,6 +1653,8 @@ static int __init parse_amd_iommu_options(char *str) | |||
1560 | amd_iommu_unmap_flush = true; | 1653 | amd_iommu_unmap_flush = true; |
1561 | if (strncmp(str, "off", 3) == 0) | 1654 | if (strncmp(str, "off", 3) == 0) |
1562 | amd_iommu_disabled = true; | 1655 | amd_iommu_disabled = true; |
1656 | if (strncmp(str, "force_isolation", 15) == 0) | ||
1657 | amd_iommu_force_isolation = true; | ||
1563 | } | 1658 | } |
1564 | 1659 | ||
1565 | return 1; | 1660 | return 1; |
@@ -1572,3 +1667,9 @@ IOMMU_INIT_FINISH(amd_iommu_detect, | |||
1572 | gart_iommu_hole_init, | 1667 | gart_iommu_hole_init, |
1573 | 0, | 1668 | 0, |
1574 | 0); | 1669 | 0); |
1670 | |||
1671 | bool amd_iommu_v2_supported(void) | ||
1672 | { | ||
1673 | return amd_iommu_v2_present; | ||
1674 | } | ||
1675 | EXPORT_SYMBOL(amd_iommu_v2_supported); | ||
diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 7ffaa64410b0..1a7f41c6cc66 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h | |||
@@ -31,6 +31,30 @@ extern int amd_iommu_init_devices(void); | |||
31 | extern void amd_iommu_uninit_devices(void); | 31 | extern void amd_iommu_uninit_devices(void); |
32 | extern void amd_iommu_init_notifier(void); | 32 | extern void amd_iommu_init_notifier(void); |
33 | extern void amd_iommu_init_api(void); | 33 | extern void amd_iommu_init_api(void); |
34 | |||
35 | /* IOMMUv2 specific functions */ | ||
36 | struct iommu_domain; | ||
37 | |||
38 | extern bool amd_iommu_v2_supported(void); | ||
39 | extern int amd_iommu_register_ppr_notifier(struct notifier_block *nb); | ||
40 | extern int amd_iommu_unregister_ppr_notifier(struct notifier_block *nb); | ||
41 | extern void amd_iommu_domain_direct_map(struct iommu_domain *dom); | ||
42 | extern int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids); | ||
43 | extern int amd_iommu_flush_page(struct iommu_domain *dom, int pasid, | ||
44 | u64 address); | ||
45 | extern int amd_iommu_flush_tlb(struct iommu_domain *dom, int pasid); | ||
46 | extern int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid, | ||
47 | unsigned long cr3); | ||
48 | extern int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid); | ||
49 | extern struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev); | ||
50 | |||
51 | #define PPR_SUCCESS 0x0 | ||
52 | #define PPR_INVALID 0x1 | ||
53 | #define PPR_FAILURE 0xf | ||
54 | |||
55 | extern int amd_iommu_complete_ppr(struct pci_dev *pdev, int pasid, | ||
56 | int status, int tag); | ||
57 | |||
34 | #ifndef CONFIG_AMD_IOMMU_STATS | 58 | #ifndef CONFIG_AMD_IOMMU_STATS |
35 | 59 | ||
36 | static inline void amd_iommu_stats_init(void) { } | 60 | static inline void amd_iommu_stats_init(void) { } |
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 5b9c5075e81a..6ad8b10b3130 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h | |||
@@ -69,11 +69,14 @@ | |||
69 | #define MMIO_EXCL_BASE_OFFSET 0x0020 | 69 | #define MMIO_EXCL_BASE_OFFSET 0x0020 |
70 | #define MMIO_EXCL_LIMIT_OFFSET 0x0028 | 70 | #define MMIO_EXCL_LIMIT_OFFSET 0x0028 |
71 | #define MMIO_EXT_FEATURES 0x0030 | 71 | #define MMIO_EXT_FEATURES 0x0030 |
72 | #define MMIO_PPR_LOG_OFFSET 0x0038 | ||
72 | #define MMIO_CMD_HEAD_OFFSET 0x2000 | 73 | #define MMIO_CMD_HEAD_OFFSET 0x2000 |
73 | #define MMIO_CMD_TAIL_OFFSET 0x2008 | 74 | #define MMIO_CMD_TAIL_OFFSET 0x2008 |
74 | #define MMIO_EVT_HEAD_OFFSET 0x2010 | 75 | #define MMIO_EVT_HEAD_OFFSET 0x2010 |
75 | #define MMIO_EVT_TAIL_OFFSET 0x2018 | 76 | #define MMIO_EVT_TAIL_OFFSET 0x2018 |
76 | #define MMIO_STATUS_OFFSET 0x2020 | 77 | #define MMIO_STATUS_OFFSET 0x2020 |
78 | #define MMIO_PPR_HEAD_OFFSET 0x2030 | ||
79 | #define MMIO_PPR_TAIL_OFFSET 0x2038 | ||
77 | 80 | ||
78 | 81 | ||
79 | /* Extended Feature Bits */ | 82 | /* Extended Feature Bits */ |
@@ -87,8 +90,17 @@ | |||
87 | #define FEATURE_HE (1ULL<<8) | 90 | #define FEATURE_HE (1ULL<<8) |
88 | #define FEATURE_PC (1ULL<<9) | 91 | #define FEATURE_PC (1ULL<<9) |
89 | 92 | ||
93 | #define FEATURE_PASID_SHIFT 32 | ||
94 | #define FEATURE_PASID_MASK (0x1fULL << FEATURE_PASID_SHIFT) | ||
95 | |||
96 | #define FEATURE_GLXVAL_SHIFT 14 | ||
97 | #define FEATURE_GLXVAL_MASK (0x03ULL << FEATURE_GLXVAL_SHIFT) | ||
98 | |||
99 | #define PASID_MASK 0x000fffff | ||
100 | |||
90 | /* MMIO status bits */ | 101 | /* MMIO status bits */ |
91 | #define MMIO_STATUS_COM_WAIT_INT_MASK 0x04 | 102 | #define MMIO_STATUS_COM_WAIT_INT_MASK (1 << 2) |
103 | #define MMIO_STATUS_PPR_INT_MASK (1 << 6) | ||
92 | 104 | ||
93 | /* event logging constants */ | 105 | /* event logging constants */ |
94 | #define EVENT_ENTRY_SIZE 0x10 | 106 | #define EVENT_ENTRY_SIZE 0x10 |
@@ -122,18 +134,25 @@ | |||
122 | #define CONTROL_CMDBUF_EN 0x0cULL | 134 | #define CONTROL_CMDBUF_EN 0x0cULL |
123 | #define CONTROL_PPFLOG_EN 0x0dULL | 135 | #define CONTROL_PPFLOG_EN 0x0dULL |
124 | #define CONTROL_PPFINT_EN 0x0eULL | 136 | #define CONTROL_PPFINT_EN 0x0eULL |
137 | #define CONTROL_PPR_EN 0x0fULL | ||
138 | #define CONTROL_GT_EN 0x10ULL | ||
125 | 139 | ||
126 | /* command specific defines */ | 140 | /* command specific defines */ |
127 | #define CMD_COMPL_WAIT 0x01 | 141 | #define CMD_COMPL_WAIT 0x01 |
128 | #define CMD_INV_DEV_ENTRY 0x02 | 142 | #define CMD_INV_DEV_ENTRY 0x02 |
129 | #define CMD_INV_IOMMU_PAGES 0x03 | 143 | #define CMD_INV_IOMMU_PAGES 0x03 |
130 | #define CMD_INV_IOTLB_PAGES 0x04 | 144 | #define CMD_INV_IOTLB_PAGES 0x04 |
145 | #define CMD_COMPLETE_PPR 0x07 | ||
131 | #define CMD_INV_ALL 0x08 | 146 | #define CMD_INV_ALL 0x08 |
132 | 147 | ||
133 | #define CMD_COMPL_WAIT_STORE_MASK 0x01 | 148 | #define CMD_COMPL_WAIT_STORE_MASK 0x01 |
134 | #define CMD_COMPL_WAIT_INT_MASK 0x02 | 149 | #define CMD_COMPL_WAIT_INT_MASK 0x02 |
135 | #define CMD_INV_IOMMU_PAGES_SIZE_MASK 0x01 | 150 | #define CMD_INV_IOMMU_PAGES_SIZE_MASK 0x01 |
136 | #define CMD_INV_IOMMU_PAGES_PDE_MASK 0x02 | 151 | #define CMD_INV_IOMMU_PAGES_PDE_MASK 0x02 |
152 | #define CMD_INV_IOMMU_PAGES_GN_MASK 0x04 | ||
153 | |||
154 | #define PPR_STATUS_MASK 0xf | ||
155 | #define PPR_STATUS_SHIFT 12 | ||
137 | 156 | ||
138 | #define CMD_INV_IOMMU_ALL_PAGES_ADDRESS 0x7fffffffffffffffULL | 157 | #define CMD_INV_IOMMU_ALL_PAGES_ADDRESS 0x7fffffffffffffffULL |
139 | 158 | ||
@@ -165,6 +184,23 @@ | |||
165 | #define EVT_BUFFER_SIZE 8192 /* 512 entries */ | 184 | #define EVT_BUFFER_SIZE 8192 /* 512 entries */ |
166 | #define EVT_LEN_MASK (0x9ULL << 56) | 185 | #define EVT_LEN_MASK (0x9ULL << 56) |
167 | 186 | ||
187 | /* Constants for PPR Log handling */ | ||
188 | #define PPR_LOG_ENTRIES 512 | ||
189 | #define PPR_LOG_SIZE_SHIFT 56 | ||
190 | #define PPR_LOG_SIZE_512 (0x9ULL << PPR_LOG_SIZE_SHIFT) | ||
191 | #define PPR_ENTRY_SIZE 16 | ||
192 | #define PPR_LOG_SIZE (PPR_ENTRY_SIZE * PPR_LOG_ENTRIES) | ||
193 | |||
194 | #define PPR_REQ_TYPE(x) (((x) >> 60) & 0xfULL) | ||
195 | #define PPR_FLAGS(x) (((x) >> 48) & 0xfffULL) | ||
196 | #define PPR_DEVID(x) ((x) & 0xffffULL) | ||
197 | #define PPR_TAG(x) (((x) >> 32) & 0x3ffULL) | ||
198 | #define PPR_PASID1(x) (((x) >> 16) & 0xffffULL) | ||
199 | #define PPR_PASID2(x) (((x) >> 42) & 0xfULL) | ||
200 | #define PPR_PASID(x) ((PPR_PASID2(x) << 16) | PPR_PASID1(x)) | ||
201 | |||
202 | #define PPR_REQ_FAULT 0x01 | ||
203 | |||
168 | #define PAGE_MODE_NONE 0x00 | 204 | #define PAGE_MODE_NONE 0x00 |
169 | #define PAGE_MODE_1_LEVEL 0x01 | 205 | #define PAGE_MODE_1_LEVEL 0x01 |
170 | #define PAGE_MODE_2_LEVEL 0x02 | 206 | #define PAGE_MODE_2_LEVEL 0x02 |
@@ -230,7 +266,24 @@ | |||
230 | #define IOMMU_PTE_IR (1ULL << 61) | 266 | #define IOMMU_PTE_IR (1ULL << 61) |
231 | #define IOMMU_PTE_IW (1ULL << 62) | 267 | #define IOMMU_PTE_IW (1ULL << 62) |
232 | 268 | ||
233 | #define DTE_FLAG_IOTLB 0x01 | 269 | #define DTE_FLAG_IOTLB (0x01UL << 32) |
270 | #define DTE_FLAG_GV (0x01ULL << 55) | ||
271 | #define DTE_GLX_SHIFT (56) | ||
272 | #define DTE_GLX_MASK (3) | ||
273 | |||
274 | #define DTE_GCR3_VAL_A(x) (((x) >> 12) & 0x00007ULL) | ||
275 | #define DTE_GCR3_VAL_B(x) (((x) >> 15) & 0x0ffffULL) | ||
276 | #define DTE_GCR3_VAL_C(x) (((x) >> 31) & 0xfffffULL) | ||
277 | |||
278 | #define DTE_GCR3_INDEX_A 0 | ||
279 | #define DTE_GCR3_INDEX_B 1 | ||
280 | #define DTE_GCR3_INDEX_C 1 | ||
281 | |||
282 | #define DTE_GCR3_SHIFT_A 58 | ||
283 | #define DTE_GCR3_SHIFT_B 16 | ||
284 | #define DTE_GCR3_SHIFT_C 43 | ||
285 | |||
286 | #define GCR3_VALID 0x01ULL | ||
234 | 287 | ||
235 | #define IOMMU_PAGE_MASK (((1ULL << 52) - 1) & ~0xfffULL) | 288 | #define IOMMU_PAGE_MASK (((1ULL << 52) - 1) & ~0xfffULL) |
236 | #define IOMMU_PTE_PRESENT(pte) ((pte) & IOMMU_PTE_P) | 289 | #define IOMMU_PTE_PRESENT(pte) ((pte) & IOMMU_PTE_P) |
@@ -257,6 +310,7 @@ | |||
257 | domain for an IOMMU */ | 310 | domain for an IOMMU */ |
258 | #define PD_PASSTHROUGH_MASK (1UL << 2) /* domain has no page | 311 | #define PD_PASSTHROUGH_MASK (1UL << 2) /* domain has no page |
259 | translation */ | 312 | translation */ |
313 | #define PD_IOMMUV2_MASK (1UL << 3) /* domain has gcr3 table */ | ||
260 | 314 | ||
261 | extern bool amd_iommu_dump; | 315 | extern bool amd_iommu_dump; |
262 | #define DUMP_printk(format, arg...) \ | 316 | #define DUMP_printk(format, arg...) \ |
@@ -285,6 +339,29 @@ extern bool amd_iommu_iotlb_sup; | |||
285 | #define APERTURE_RANGE_INDEX(a) ((a) >> APERTURE_RANGE_SHIFT) | 339 | #define APERTURE_RANGE_INDEX(a) ((a) >> APERTURE_RANGE_SHIFT) |
286 | #define APERTURE_PAGE_INDEX(a) (((a) >> 21) & 0x3fULL) | 340 | #define APERTURE_PAGE_INDEX(a) (((a) >> 21) & 0x3fULL) |
287 | 341 | ||
342 | |||
343 | /* | ||
344 | * This struct is used to pass information about | ||
345 | * incoming PPR faults around. | ||
346 | */ | ||
347 | struct amd_iommu_fault { | ||
348 | u64 address; /* IO virtual address of the fault*/ | ||
349 | u32 pasid; /* Address space identifier */ | ||
350 | u16 device_id; /* Originating PCI device id */ | ||
351 | u16 tag; /* PPR tag */ | ||
352 | u16 flags; /* Fault flags */ | ||
353 | |||
354 | }; | ||
355 | |||
356 | #define PPR_FAULT_EXEC (1 << 1) | ||
357 | #define PPR_FAULT_READ (1 << 2) | ||
358 | #define PPR_FAULT_WRITE (1 << 5) | ||
359 | #define PPR_FAULT_USER (1 << 6) | ||
360 | #define PPR_FAULT_RSVD (1 << 7) | ||
361 | #define PPR_FAULT_GN (1 << 8) | ||
362 | |||
363 | struct iommu_domain; | ||
364 | |||
288 | /* | 365 | /* |
289 | * This structure contains generic data for IOMMU protection domains | 366 | * This structure contains generic data for IOMMU protection domains |
290 | * independent of their use. | 367 | * independent of their use. |
@@ -297,11 +374,15 @@ struct protection_domain { | |||
297 | u16 id; /* the domain id written to the device table */ | 374 | u16 id; /* the domain id written to the device table */ |
298 | int mode; /* paging mode (0-6 levels) */ | 375 | int mode; /* paging mode (0-6 levels) */ |
299 | u64 *pt_root; /* page table root pointer */ | 376 | u64 *pt_root; /* page table root pointer */ |
377 | int glx; /* Number of levels for GCR3 table */ | ||
378 | u64 *gcr3_tbl; /* Guest CR3 table */ | ||
300 | unsigned long flags; /* flags to find out type of domain */ | 379 | unsigned long flags; /* flags to find out type of domain */ |
301 | bool updated; /* complete domain flush required */ | 380 | bool updated; /* complete domain flush required */ |
302 | unsigned dev_cnt; /* devices assigned to this domain */ | 381 | unsigned dev_cnt; /* devices assigned to this domain */ |
303 | unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */ | 382 | unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */ |
304 | void *priv; /* private data */ | 383 | void *priv; /* private data */ |
384 | struct iommu_domain *iommu_domain; /* Pointer to generic | ||
385 | domain structure */ | ||
305 | 386 | ||
306 | }; | 387 | }; |
307 | 388 | ||
@@ -315,10 +396,15 @@ struct iommu_dev_data { | |||
315 | struct protection_domain *domain; /* Domain the device is bound to */ | 396 | struct protection_domain *domain; /* Domain the device is bound to */ |
316 | atomic_t bind; /* Domain attach reverent count */ | 397 | atomic_t bind; /* Domain attach reverent count */ |
317 | u16 devid; /* PCI Device ID */ | 398 | u16 devid; /* PCI Device ID */ |
399 | bool iommu_v2; /* Device can make use of IOMMUv2 */ | ||
400 | bool passthrough; /* Default for device is pt_domain */ | ||
318 | struct { | 401 | struct { |
319 | bool enabled; | 402 | bool enabled; |
320 | int qdep; | 403 | int qdep; |
321 | } ats; /* ATS state */ | 404 | } ats; /* ATS state */ |
405 | bool pri_tlp; /* PASID TLB required for | ||
406 | PPR completions */ | ||
407 | u32 errata; /* Bitmap for errata to apply */ | ||
322 | }; | 408 | }; |
323 | 409 | ||
324 | /* | 410 | /* |
@@ -399,6 +485,9 @@ struct amd_iommu { | |||
399 | /* Extended features */ | 485 | /* Extended features */ |
400 | u64 features; | 486 | u64 features; |
401 | 487 | ||
488 | /* IOMMUv2 */ | ||
489 | bool is_iommu_v2; | ||
490 | |||
402 | /* | 491 | /* |
403 | * Capability pointer. There could be more than one IOMMU per PCI | 492 | * Capability pointer. There could be more than one IOMMU per PCI |
404 | * device function if there are more than one AMD IOMMU capability | 493 | * device function if there are more than one AMD IOMMU capability |
@@ -431,6 +520,9 @@ struct amd_iommu { | |||
431 | /* MSI number for event interrupt */ | 520 | /* MSI number for event interrupt */ |
432 | u16 evt_msi_num; | 521 | u16 evt_msi_num; |
433 | 522 | ||
523 | /* Base of the PPR log, if present */ | ||
524 | u8 *ppr_log; | ||
525 | |||
434 | /* true if interrupts for this IOMMU are already enabled */ | 526 | /* true if interrupts for this IOMMU are already enabled */ |
435 | bool int_enabled; | 527 | bool int_enabled; |
436 | 528 | ||
@@ -484,7 +576,7 @@ extern struct list_head amd_iommu_pd_list; | |||
484 | * Structure defining one entry in the device table | 576 | * Structure defining one entry in the device table |
485 | */ | 577 | */ |
486 | struct dev_table_entry { | 578 | struct dev_table_entry { |
487 | u32 data[8]; | 579 | u64 data[4]; |
488 | }; | 580 | }; |
489 | 581 | ||
490 | /* | 582 | /* |
@@ -549,6 +641,16 @@ extern unsigned long *amd_iommu_pd_alloc_bitmap; | |||
549 | */ | 641 | */ |
550 | extern bool amd_iommu_unmap_flush; | 642 | extern bool amd_iommu_unmap_flush; |
551 | 643 | ||
644 | /* Smallest number of PASIDs supported by any IOMMU in the system */ | ||
645 | extern u32 amd_iommu_max_pasids; | ||
646 | |||
647 | extern bool amd_iommu_v2_present; | ||
648 | |||
649 | extern bool amd_iommu_force_isolation; | ||
650 | |||
651 | /* Max levels of glxval supported */ | ||
652 | extern int amd_iommu_max_glx_val; | ||
653 | |||
552 | /* takes bus and device/function and returns the device id | 654 | /* takes bus and device/function and returns the device id |
553 | * FIXME: should that be in generic PCI code? */ | 655 | * FIXME: should that be in generic PCI code? */ |
554 | static inline u16 calc_devid(u8 bus, u8 devfn) | 656 | static inline u16 calc_devid(u8 bus, u8 devfn) |
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c new file mode 100644 index 000000000000..fe812e2a0474 --- /dev/null +++ b/drivers/iommu/amd_iommu_v2.c | |||
@@ -0,0 +1,959 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010-2012 Advanced Micro Devices, Inc. | ||
3 | * Author: Joerg Roedel <joerg.roedel@amd.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License version 2 as published | ||
7 | * by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | |||
19 | #include <linux/mmu_notifier.h> | ||
20 | #include <linux/amd-iommu.h> | ||
21 | #include <linux/mm_types.h> | ||
22 | #include <linux/profile.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/iommu.h> | ||
26 | #include <linux/wait.h> | ||
27 | #include <linux/pci.h> | ||
28 | #include <linux/gfp.h> | ||
29 | |||
30 | #include "amd_iommu_types.h" | ||
31 | #include "amd_iommu_proto.h" | ||
32 | |||
33 | MODULE_LICENSE("GPL v2"); | ||
34 | MODULE_AUTHOR("Joerg Roedel <joerg.roedel@amd.com>"); | ||
35 | |||
36 | #define MAX_DEVICES 0x10000 | ||
37 | #define PRI_QUEUE_SIZE 512 | ||
38 | |||
39 | struct pri_queue { | ||
40 | atomic_t inflight; | ||
41 | bool finish; | ||
42 | int status; | ||
43 | }; | ||
44 | |||
45 | struct pasid_state { | ||
46 | struct list_head list; /* For global state-list */ | ||
47 | atomic_t count; /* Reference count */ | ||
48 | struct task_struct *task; /* Task bound to this PASID */ | ||
49 | struct mm_struct *mm; /* mm_struct for the faults */ | ||
50 | struct mmu_notifier mn; /* mmu_otifier handle */ | ||
51 | struct pri_queue pri[PRI_QUEUE_SIZE]; /* PRI tag states */ | ||
52 | struct device_state *device_state; /* Link to our device_state */ | ||
53 | int pasid; /* PASID index */ | ||
54 | spinlock_t lock; /* Protect pri_queues */ | ||
55 | wait_queue_head_t wq; /* To wait for count == 0 */ | ||
56 | }; | ||
57 | |||
58 | struct device_state { | ||
59 | atomic_t count; | ||
60 | struct pci_dev *pdev; | ||
61 | struct pasid_state **states; | ||
62 | struct iommu_domain *domain; | ||
63 | int pasid_levels; | ||
64 | int max_pasids; | ||
65 | amd_iommu_invalid_ppr_cb inv_ppr_cb; | ||
66 | spinlock_t lock; | ||
67 | wait_queue_head_t wq; | ||
68 | }; | ||
69 | |||
70 | struct fault { | ||
71 | struct work_struct work; | ||
72 | struct device_state *dev_state; | ||
73 | struct pasid_state *state; | ||
74 | struct mm_struct *mm; | ||
75 | u64 address; | ||
76 | u16 devid; | ||
77 | u16 pasid; | ||
78 | u16 tag; | ||
79 | u16 finish; | ||
80 | u16 flags; | ||
81 | }; | ||
82 | |||
83 | struct device_state **state_table; | ||
84 | static spinlock_t state_lock; | ||
85 | |||
86 | /* List and lock for all pasid_states */ | ||
87 | static LIST_HEAD(pasid_state_list); | ||
88 | static DEFINE_SPINLOCK(ps_lock); | ||
89 | |||
90 | static struct workqueue_struct *iommu_wq; | ||
91 | |||
92 | /* | ||
93 | * Empty page table - Used between | ||
94 | * mmu_notifier_invalidate_range_start and | ||
95 | * mmu_notifier_invalidate_range_end | ||
96 | */ | ||
97 | static u64 *empty_page_table; | ||
98 | |||
99 | static void free_pasid_states(struct device_state *dev_state); | ||
100 | static void unbind_pasid(struct device_state *dev_state, int pasid); | ||
101 | static int task_exit(struct notifier_block *nb, unsigned long e, void *data); | ||
102 | |||
103 | static u16 device_id(struct pci_dev *pdev) | ||
104 | { | ||
105 | u16 devid; | ||
106 | |||
107 | devid = pdev->bus->number; | ||
108 | devid = (devid << 8) | pdev->devfn; | ||
109 | |||
110 | return devid; | ||
111 | } | ||
112 | |||
113 | static struct device_state *get_device_state(u16 devid) | ||
114 | { | ||
115 | struct device_state *dev_state; | ||
116 | unsigned long flags; | ||
117 | |||
118 | spin_lock_irqsave(&state_lock, flags); | ||
119 | dev_state = state_table[devid]; | ||
120 | if (dev_state != NULL) | ||
121 | atomic_inc(&dev_state->count); | ||
122 | spin_unlock_irqrestore(&state_lock, flags); | ||
123 | |||
124 | return dev_state; | ||
125 | } | ||
126 | |||
127 | static void free_device_state(struct device_state *dev_state) | ||
128 | { | ||
129 | /* | ||
130 | * First detach device from domain - No more PRI requests will arrive | ||
131 | * from that device after it is unbound from the IOMMUv2 domain. | ||
132 | */ | ||
133 | iommu_detach_device(dev_state->domain, &dev_state->pdev->dev); | ||
134 | |||
135 | /* Everything is down now, free the IOMMUv2 domain */ | ||
136 | iommu_domain_free(dev_state->domain); | ||
137 | |||
138 | /* Finally get rid of the device-state */ | ||
139 | kfree(dev_state); | ||
140 | } | ||
141 | |||
142 | static void put_device_state(struct device_state *dev_state) | ||
143 | { | ||
144 | if (atomic_dec_and_test(&dev_state->count)) | ||
145 | wake_up(&dev_state->wq); | ||
146 | } | ||
147 | |||
148 | static void put_device_state_wait(struct device_state *dev_state) | ||
149 | { | ||
150 | DEFINE_WAIT(wait); | ||
151 | |||
152 | prepare_to_wait(&dev_state->wq, &wait, TASK_UNINTERRUPTIBLE); | ||
153 | if (!atomic_dec_and_test(&dev_state->count)) | ||
154 | schedule(); | ||
155 | finish_wait(&dev_state->wq, &wait); | ||
156 | |||
157 | free_device_state(dev_state); | ||
158 | } | ||
159 | |||
160 | static struct notifier_block profile_nb = { | ||
161 | .notifier_call = task_exit, | ||
162 | }; | ||
163 | |||
164 | static void link_pasid_state(struct pasid_state *pasid_state) | ||
165 | { | ||
166 | spin_lock(&ps_lock); | ||
167 | list_add_tail(&pasid_state->list, &pasid_state_list); | ||
168 | spin_unlock(&ps_lock); | ||
169 | } | ||
170 | |||
171 | static void __unlink_pasid_state(struct pasid_state *pasid_state) | ||
172 | { | ||
173 | list_del(&pasid_state->list); | ||
174 | } | ||
175 | |||
176 | static void unlink_pasid_state(struct pasid_state *pasid_state) | ||
177 | { | ||
178 | spin_lock(&ps_lock); | ||
179 | __unlink_pasid_state(pasid_state); | ||
180 | spin_unlock(&ps_lock); | ||
181 | } | ||
182 | |||
183 | /* Must be called under dev_state->lock */ | ||
184 | static struct pasid_state **__get_pasid_state_ptr(struct device_state *dev_state, | ||
185 | int pasid, bool alloc) | ||
186 | { | ||
187 | struct pasid_state **root, **ptr; | ||
188 | int level, index; | ||
189 | |||
190 | level = dev_state->pasid_levels; | ||
191 | root = dev_state->states; | ||
192 | |||
193 | while (true) { | ||
194 | |||
195 | index = (pasid >> (9 * level)) & 0x1ff; | ||
196 | ptr = &root[index]; | ||
197 | |||
198 | if (level == 0) | ||
199 | break; | ||
200 | |||
201 | if (*ptr == NULL) { | ||
202 | if (!alloc) | ||
203 | return NULL; | ||
204 | |||
205 | *ptr = (void *)get_zeroed_page(GFP_ATOMIC); | ||
206 | if (*ptr == NULL) | ||
207 | return NULL; | ||
208 | } | ||
209 | |||
210 | root = (struct pasid_state **)*ptr; | ||
211 | level -= 1; | ||
212 | } | ||
213 | |||
214 | return ptr; | ||
215 | } | ||
216 | |||
217 | static int set_pasid_state(struct device_state *dev_state, | ||
218 | struct pasid_state *pasid_state, | ||
219 | int pasid) | ||
220 | { | ||
221 | struct pasid_state **ptr; | ||
222 | unsigned long flags; | ||
223 | int ret; | ||
224 | |||
225 | spin_lock_irqsave(&dev_state->lock, flags); | ||
226 | ptr = __get_pasid_state_ptr(dev_state, pasid, true); | ||
227 | |||
228 | ret = -ENOMEM; | ||
229 | if (ptr == NULL) | ||
230 | goto out_unlock; | ||
231 | |||
232 | ret = -ENOMEM; | ||
233 | if (*ptr != NULL) | ||
234 | goto out_unlock; | ||
235 | |||
236 | *ptr = pasid_state; | ||
237 | |||
238 | ret = 0; | ||
239 | |||
240 | out_unlock: | ||
241 | spin_unlock_irqrestore(&dev_state->lock, flags); | ||
242 | |||
243 | return ret; | ||
244 | } | ||
245 | |||
246 | static void clear_pasid_state(struct device_state *dev_state, int pasid) | ||
247 | { | ||
248 | struct pasid_state **ptr; | ||
249 | unsigned long flags; | ||
250 | |||
251 | spin_lock_irqsave(&dev_state->lock, flags); | ||
252 | ptr = __get_pasid_state_ptr(dev_state, pasid, true); | ||
253 | |||
254 | if (ptr == NULL) | ||
255 | goto out_unlock; | ||
256 | |||
257 | *ptr = NULL; | ||
258 | |||
259 | out_unlock: | ||
260 | spin_unlock_irqrestore(&dev_state->lock, flags); | ||
261 | } | ||
262 | |||
263 | static struct pasid_state *get_pasid_state(struct device_state *dev_state, | ||
264 | int pasid) | ||
265 | { | ||
266 | struct pasid_state **ptr, *ret = NULL; | ||
267 | unsigned long flags; | ||
268 | |||
269 | spin_lock_irqsave(&dev_state->lock, flags); | ||
270 | ptr = __get_pasid_state_ptr(dev_state, pasid, false); | ||
271 | |||
272 | if (ptr == NULL) | ||
273 | goto out_unlock; | ||
274 | |||
275 | ret = *ptr; | ||
276 | if (ret) | ||
277 | atomic_inc(&ret->count); | ||
278 | |||
279 | out_unlock: | ||
280 | spin_unlock_irqrestore(&dev_state->lock, flags); | ||
281 | |||
282 | return ret; | ||
283 | } | ||
284 | |||
285 | static void free_pasid_state(struct pasid_state *pasid_state) | ||
286 | { | ||
287 | kfree(pasid_state); | ||
288 | } | ||
289 | |||
290 | static void put_pasid_state(struct pasid_state *pasid_state) | ||
291 | { | ||
292 | if (atomic_dec_and_test(&pasid_state->count)) { | ||
293 | put_device_state(pasid_state->device_state); | ||
294 | wake_up(&pasid_state->wq); | ||
295 | } | ||
296 | } | ||
297 | |||
298 | static void put_pasid_state_wait(struct pasid_state *pasid_state) | ||
299 | { | ||
300 | DEFINE_WAIT(wait); | ||
301 | |||
302 | prepare_to_wait(&pasid_state->wq, &wait, TASK_UNINTERRUPTIBLE); | ||
303 | |||
304 | if (atomic_dec_and_test(&pasid_state->count)) | ||
305 | put_device_state(pasid_state->device_state); | ||
306 | else | ||
307 | schedule(); | ||
308 | |||
309 | finish_wait(&pasid_state->wq, &wait); | ||
310 | mmput(pasid_state->mm); | ||
311 | free_pasid_state(pasid_state); | ||
312 | } | ||
313 | |||
314 | static void __unbind_pasid(struct pasid_state *pasid_state) | ||
315 | { | ||
316 | struct iommu_domain *domain; | ||
317 | |||
318 | domain = pasid_state->device_state->domain; | ||
319 | |||
320 | amd_iommu_domain_clear_gcr3(domain, pasid_state->pasid); | ||
321 | clear_pasid_state(pasid_state->device_state, pasid_state->pasid); | ||
322 | |||
323 | /* Make sure no more pending faults are in the queue */ | ||
324 | flush_workqueue(iommu_wq); | ||
325 | |||
326 | mmu_notifier_unregister(&pasid_state->mn, pasid_state->mm); | ||
327 | |||
328 | put_pasid_state(pasid_state); /* Reference taken in bind() function */ | ||
329 | } | ||
330 | |||
331 | static void unbind_pasid(struct device_state *dev_state, int pasid) | ||
332 | { | ||
333 | struct pasid_state *pasid_state; | ||
334 | |||
335 | pasid_state = get_pasid_state(dev_state, pasid); | ||
336 | if (pasid_state == NULL) | ||
337 | return; | ||
338 | |||
339 | unlink_pasid_state(pasid_state); | ||
340 | __unbind_pasid(pasid_state); | ||
341 | put_pasid_state_wait(pasid_state); /* Reference taken in this function */ | ||
342 | } | ||
343 | |||
344 | static void free_pasid_states_level1(struct pasid_state **tbl) | ||
345 | { | ||
346 | int i; | ||
347 | |||
348 | for (i = 0; i < 512; ++i) { | ||
349 | if (tbl[i] == NULL) | ||
350 | continue; | ||
351 | |||
352 | free_page((unsigned long)tbl[i]); | ||
353 | } | ||
354 | } | ||
355 | |||
356 | static void free_pasid_states_level2(struct pasid_state **tbl) | ||
357 | { | ||
358 | struct pasid_state **ptr; | ||
359 | int i; | ||
360 | |||
361 | for (i = 0; i < 512; ++i) { | ||
362 | if (tbl[i] == NULL) | ||
363 | continue; | ||
364 | |||
365 | ptr = (struct pasid_state **)tbl[i]; | ||
366 | free_pasid_states_level1(ptr); | ||
367 | } | ||
368 | } | ||
369 | |||
370 | static void free_pasid_states(struct device_state *dev_state) | ||
371 | { | ||
372 | struct pasid_state *pasid_state; | ||
373 | int i; | ||
374 | |||
375 | for (i = 0; i < dev_state->max_pasids; ++i) { | ||
376 | pasid_state = get_pasid_state(dev_state, i); | ||
377 | if (pasid_state == NULL) | ||
378 | continue; | ||
379 | |||
380 | put_pasid_state(pasid_state); | ||
381 | unbind_pasid(dev_state, i); | ||
382 | } | ||
383 | |||
384 | if (dev_state->pasid_levels == 2) | ||
385 | free_pasid_states_level2(dev_state->states); | ||
386 | else if (dev_state->pasid_levels == 1) | ||
387 | free_pasid_states_level1(dev_state->states); | ||
388 | else if (dev_state->pasid_levels != 0) | ||
389 | BUG(); | ||
390 | |||
391 | free_page((unsigned long)dev_state->states); | ||
392 | } | ||
393 | |||
394 | static struct pasid_state *mn_to_state(struct mmu_notifier *mn) | ||
395 | { | ||
396 | return container_of(mn, struct pasid_state, mn); | ||
397 | } | ||
398 | |||
399 | static void __mn_flush_page(struct mmu_notifier *mn, | ||
400 | unsigned long address) | ||
401 | { | ||
402 | struct pasid_state *pasid_state; | ||
403 | struct device_state *dev_state; | ||
404 | |||
405 | pasid_state = mn_to_state(mn); | ||
406 | dev_state = pasid_state->device_state; | ||
407 | |||
408 | amd_iommu_flush_page(dev_state->domain, pasid_state->pasid, address); | ||
409 | } | ||
410 | |||
411 | static int mn_clear_flush_young(struct mmu_notifier *mn, | ||
412 | struct mm_struct *mm, | ||
413 | unsigned long address) | ||
414 | { | ||
415 | __mn_flush_page(mn, address); | ||
416 | |||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | static void mn_change_pte(struct mmu_notifier *mn, | ||
421 | struct mm_struct *mm, | ||
422 | unsigned long address, | ||
423 | pte_t pte) | ||
424 | { | ||
425 | __mn_flush_page(mn, address); | ||
426 | } | ||
427 | |||
428 | static void mn_invalidate_page(struct mmu_notifier *mn, | ||
429 | struct mm_struct *mm, | ||
430 | unsigned long address) | ||
431 | { | ||
432 | __mn_flush_page(mn, address); | ||
433 | } | ||
434 | |||
435 | static void mn_invalidate_range_start(struct mmu_notifier *mn, | ||
436 | struct mm_struct *mm, | ||
437 | unsigned long start, unsigned long end) | ||
438 | { | ||
439 | struct pasid_state *pasid_state; | ||
440 | struct device_state *dev_state; | ||
441 | |||
442 | pasid_state = mn_to_state(mn); | ||
443 | dev_state = pasid_state->device_state; | ||
444 | |||
445 | amd_iommu_domain_set_gcr3(dev_state->domain, pasid_state->pasid, | ||
446 | __pa(empty_page_table)); | ||
447 | } | ||
448 | |||
449 | static void mn_invalidate_range_end(struct mmu_notifier *mn, | ||
450 | struct mm_struct *mm, | ||
451 | unsigned long start, unsigned long end) | ||
452 | { | ||
453 | struct pasid_state *pasid_state; | ||
454 | struct device_state *dev_state; | ||
455 | |||
456 | pasid_state = mn_to_state(mn); | ||
457 | dev_state = pasid_state->device_state; | ||
458 | |||
459 | amd_iommu_domain_set_gcr3(dev_state->domain, pasid_state->pasid, | ||
460 | __pa(pasid_state->mm->pgd)); | ||
461 | } | ||
462 | |||
463 | static struct mmu_notifier_ops iommu_mn = { | ||
464 | .clear_flush_young = mn_clear_flush_young, | ||
465 | .change_pte = mn_change_pte, | ||
466 | .invalidate_page = mn_invalidate_page, | ||
467 | .invalidate_range_start = mn_invalidate_range_start, | ||
468 | .invalidate_range_end = mn_invalidate_range_end, | ||
469 | }; | ||
470 | |||
471 | static void set_pri_tag_status(struct pasid_state *pasid_state, | ||
472 | u16 tag, int status) | ||
473 | { | ||
474 | unsigned long flags; | ||
475 | |||
476 | spin_lock_irqsave(&pasid_state->lock, flags); | ||
477 | pasid_state->pri[tag].status = status; | ||
478 | spin_unlock_irqrestore(&pasid_state->lock, flags); | ||
479 | } | ||
480 | |||
481 | static void finish_pri_tag(struct device_state *dev_state, | ||
482 | struct pasid_state *pasid_state, | ||
483 | u16 tag) | ||
484 | { | ||
485 | unsigned long flags; | ||
486 | |||
487 | spin_lock_irqsave(&pasid_state->lock, flags); | ||
488 | if (atomic_dec_and_test(&pasid_state->pri[tag].inflight) && | ||
489 | pasid_state->pri[tag].finish) { | ||
490 | amd_iommu_complete_ppr(dev_state->pdev, pasid_state->pasid, | ||
491 | pasid_state->pri[tag].status, tag); | ||
492 | pasid_state->pri[tag].finish = false; | ||
493 | pasid_state->pri[tag].status = PPR_SUCCESS; | ||
494 | } | ||
495 | spin_unlock_irqrestore(&pasid_state->lock, flags); | ||
496 | } | ||
497 | |||
498 | static void do_fault(struct work_struct *work) | ||
499 | { | ||
500 | struct fault *fault = container_of(work, struct fault, work); | ||
501 | int npages, write; | ||
502 | struct page *page; | ||
503 | |||
504 | write = !!(fault->flags & PPR_FAULT_WRITE); | ||
505 | |||
506 | npages = get_user_pages(fault->state->task, fault->state->mm, | ||
507 | fault->address, 1, write, 0, &page, NULL); | ||
508 | |||
509 | if (npages == 1) { | ||
510 | put_page(page); | ||
511 | } else if (fault->dev_state->inv_ppr_cb) { | ||
512 | int status; | ||
513 | |||
514 | status = fault->dev_state->inv_ppr_cb(fault->dev_state->pdev, | ||
515 | fault->pasid, | ||
516 | fault->address, | ||
517 | fault->flags); | ||
518 | switch (status) { | ||
519 | case AMD_IOMMU_INV_PRI_RSP_SUCCESS: | ||
520 | set_pri_tag_status(fault->state, fault->tag, PPR_SUCCESS); | ||
521 | break; | ||
522 | case AMD_IOMMU_INV_PRI_RSP_INVALID: | ||
523 | set_pri_tag_status(fault->state, fault->tag, PPR_INVALID); | ||
524 | break; | ||
525 | case AMD_IOMMU_INV_PRI_RSP_FAIL: | ||
526 | set_pri_tag_status(fault->state, fault->tag, PPR_FAILURE); | ||
527 | break; | ||
528 | default: | ||
529 | BUG(); | ||
530 | } | ||
531 | } else { | ||
532 | set_pri_tag_status(fault->state, fault->tag, PPR_INVALID); | ||
533 | } | ||
534 | |||
535 | finish_pri_tag(fault->dev_state, fault->state, fault->tag); | ||
536 | |||
537 | put_pasid_state(fault->state); | ||
538 | |||
539 | kfree(fault); | ||
540 | } | ||
541 | |||
542 | static int ppr_notifier(struct notifier_block *nb, unsigned long e, void *data) | ||
543 | { | ||
544 | struct amd_iommu_fault *iommu_fault; | ||
545 | struct pasid_state *pasid_state; | ||
546 | struct device_state *dev_state; | ||
547 | unsigned long flags; | ||
548 | struct fault *fault; | ||
549 | bool finish; | ||
550 | u16 tag; | ||
551 | int ret; | ||
552 | |||
553 | iommu_fault = data; | ||
554 | tag = iommu_fault->tag & 0x1ff; | ||
555 | finish = (iommu_fault->tag >> 9) & 1; | ||
556 | |||
557 | ret = NOTIFY_DONE; | ||
558 | dev_state = get_device_state(iommu_fault->device_id); | ||
559 | if (dev_state == NULL) | ||
560 | goto out; | ||
561 | |||
562 | pasid_state = get_pasid_state(dev_state, iommu_fault->pasid); | ||
563 | if (pasid_state == NULL) { | ||
564 | /* We know the device but not the PASID -> send INVALID */ | ||
565 | amd_iommu_complete_ppr(dev_state->pdev, iommu_fault->pasid, | ||
566 | PPR_INVALID, tag); | ||
567 | goto out_drop_state; | ||
568 | } | ||
569 | |||
570 | spin_lock_irqsave(&pasid_state->lock, flags); | ||
571 | atomic_inc(&pasid_state->pri[tag].inflight); | ||
572 | if (finish) | ||
573 | pasid_state->pri[tag].finish = true; | ||
574 | spin_unlock_irqrestore(&pasid_state->lock, flags); | ||
575 | |||
576 | fault = kzalloc(sizeof(*fault), GFP_ATOMIC); | ||
577 | if (fault == NULL) { | ||
578 | /* We are OOM - send success and let the device re-fault */ | ||
579 | finish_pri_tag(dev_state, pasid_state, tag); | ||
580 | goto out_drop_state; | ||
581 | } | ||
582 | |||
583 | fault->dev_state = dev_state; | ||
584 | fault->address = iommu_fault->address; | ||
585 | fault->state = pasid_state; | ||
586 | fault->tag = tag; | ||
587 | fault->finish = finish; | ||
588 | fault->flags = iommu_fault->flags; | ||
589 | INIT_WORK(&fault->work, do_fault); | ||
590 | |||
591 | queue_work(iommu_wq, &fault->work); | ||
592 | |||
593 | ret = NOTIFY_OK; | ||
594 | |||
595 | out_drop_state: | ||
596 | put_device_state(dev_state); | ||
597 | |||
598 | out: | ||
599 | return ret; | ||
600 | } | ||
601 | |||
602 | static struct notifier_block ppr_nb = { | ||
603 | .notifier_call = ppr_notifier, | ||
604 | }; | ||
605 | |||
606 | static int task_exit(struct notifier_block *nb, unsigned long e, void *data) | ||
607 | { | ||
608 | struct pasid_state *pasid_state; | ||
609 | struct task_struct *task; | ||
610 | |||
611 | task = data; | ||
612 | |||
613 | /* | ||
614 | * Using this notifier is a hack - but there is no other choice | ||
615 | * at the moment. What I really want is a sleeping notifier that | ||
616 | * is called when an MM goes down. But such a notifier doesn't | ||
617 | * exist yet. The notifier needs to sleep because it has to make | ||
618 | * sure that the device does not use the PASID and the address | ||
619 | * space anymore before it is destroyed. This includes waiting | ||
620 | * for pending PRI requests to pass the workqueue. The | ||
621 | * MMU-Notifiers would be a good fit, but they use RCU and so | ||
622 | * they are not allowed to sleep. Lets see how we can solve this | ||
623 | * in a more intelligent way in the future. | ||
624 | */ | ||
625 | again: | ||
626 | spin_lock(&ps_lock); | ||
627 | list_for_each_entry(pasid_state, &pasid_state_list, list) { | ||
628 | struct device_state *dev_state; | ||
629 | int pasid; | ||
630 | |||
631 | if (pasid_state->task != task) | ||
632 | continue; | ||
633 | |||
634 | /* Drop Lock and unbind */ | ||
635 | spin_unlock(&ps_lock); | ||
636 | |||
637 | dev_state = pasid_state->device_state; | ||
638 | pasid = pasid_state->pasid; | ||
639 | |||
640 | unbind_pasid(dev_state, pasid); | ||
641 | |||
642 | /* Task may be in the list multiple times */ | ||
643 | goto again; | ||
644 | } | ||
645 | spin_unlock(&ps_lock); | ||
646 | |||
647 | return NOTIFY_OK; | ||
648 | } | ||
649 | |||
650 | int amd_iommu_bind_pasid(struct pci_dev *pdev, int pasid, | ||
651 | struct task_struct *task) | ||
652 | { | ||
653 | struct pasid_state *pasid_state; | ||
654 | struct device_state *dev_state; | ||
655 | u16 devid; | ||
656 | int ret; | ||
657 | |||
658 | might_sleep(); | ||
659 | |||
660 | if (!amd_iommu_v2_supported()) | ||
661 | return -ENODEV; | ||
662 | |||
663 | devid = device_id(pdev); | ||
664 | dev_state = get_device_state(devid); | ||
665 | |||
666 | if (dev_state == NULL) | ||
667 | return -EINVAL; | ||
668 | |||
669 | ret = -EINVAL; | ||
670 | if (pasid < 0 || pasid >= dev_state->max_pasids) | ||
671 | goto out; | ||
672 | |||
673 | ret = -ENOMEM; | ||
674 | pasid_state = kzalloc(sizeof(*pasid_state), GFP_KERNEL); | ||
675 | if (pasid_state == NULL) | ||
676 | goto out; | ||
677 | |||
678 | atomic_set(&pasid_state->count, 1); | ||
679 | init_waitqueue_head(&pasid_state->wq); | ||
680 | pasid_state->task = task; | ||
681 | pasid_state->mm = get_task_mm(task); | ||
682 | pasid_state->device_state = dev_state; | ||
683 | pasid_state->pasid = pasid; | ||
684 | pasid_state->mn.ops = &iommu_mn; | ||
685 | |||
686 | if (pasid_state->mm == NULL) | ||
687 | goto out_free; | ||
688 | |||
689 | mmu_notifier_register(&pasid_state->mn, pasid_state->mm); | ||
690 | |||
691 | ret = set_pasid_state(dev_state, pasid_state, pasid); | ||
692 | if (ret) | ||
693 | goto out_unregister; | ||
694 | |||
695 | ret = amd_iommu_domain_set_gcr3(dev_state->domain, pasid, | ||
696 | __pa(pasid_state->mm->pgd)); | ||
697 | if (ret) | ||
698 | goto out_clear_state; | ||
699 | |||
700 | link_pasid_state(pasid_state); | ||
701 | |||
702 | return 0; | ||
703 | |||
704 | out_clear_state: | ||
705 | clear_pasid_state(dev_state, pasid); | ||
706 | |||
707 | out_unregister: | ||
708 | mmu_notifier_unregister(&pasid_state->mn, pasid_state->mm); | ||
709 | |||
710 | out_free: | ||
711 | free_pasid_state(pasid_state); | ||
712 | |||
713 | out: | ||
714 | put_device_state(dev_state); | ||
715 | |||
716 | return ret; | ||
717 | } | ||
718 | EXPORT_SYMBOL(amd_iommu_bind_pasid); | ||
719 | |||
720 | void amd_iommu_unbind_pasid(struct pci_dev *pdev, int pasid) | ||
721 | { | ||
722 | struct device_state *dev_state; | ||
723 | u16 devid; | ||
724 | |||
725 | might_sleep(); | ||
726 | |||
727 | if (!amd_iommu_v2_supported()) | ||
728 | return; | ||
729 | |||
730 | devid = device_id(pdev); | ||
731 | dev_state = get_device_state(devid); | ||
732 | if (dev_state == NULL) | ||
733 | return; | ||
734 | |||
735 | if (pasid < 0 || pasid >= dev_state->max_pasids) | ||
736 | goto out; | ||
737 | |||
738 | unbind_pasid(dev_state, pasid); | ||
739 | |||
740 | out: | ||
741 | put_device_state(dev_state); | ||
742 | } | ||
743 | EXPORT_SYMBOL(amd_iommu_unbind_pasid); | ||
744 | |||
745 | int amd_iommu_init_device(struct pci_dev *pdev, int pasids) | ||
746 | { | ||
747 | struct device_state *dev_state; | ||
748 | unsigned long flags; | ||
749 | int ret, tmp; | ||
750 | u16 devid; | ||
751 | |||
752 | might_sleep(); | ||
753 | |||
754 | if (!amd_iommu_v2_supported()) | ||
755 | return -ENODEV; | ||
756 | |||
757 | if (pasids <= 0 || pasids > (PASID_MASK + 1)) | ||
758 | return -EINVAL; | ||
759 | |||
760 | devid = device_id(pdev); | ||
761 | |||
762 | dev_state = kzalloc(sizeof(*dev_state), GFP_KERNEL); | ||
763 | if (dev_state == NULL) | ||
764 | return -ENOMEM; | ||
765 | |||
766 | spin_lock_init(&dev_state->lock); | ||
767 | init_waitqueue_head(&dev_state->wq); | ||
768 | dev_state->pdev = pdev; | ||
769 | |||
770 | tmp = pasids; | ||
771 | for (dev_state->pasid_levels = 0; (tmp - 1) & ~0x1ff; tmp >>= 9) | ||
772 | dev_state->pasid_levels += 1; | ||
773 | |||
774 | atomic_set(&dev_state->count, 1); | ||
775 | dev_state->max_pasids = pasids; | ||
776 | |||
777 | ret = -ENOMEM; | ||
778 | dev_state->states = (void *)get_zeroed_page(GFP_KERNEL); | ||
779 | if (dev_state->states == NULL) | ||
780 | goto out_free_dev_state; | ||
781 | |||
782 | dev_state->domain = iommu_domain_alloc(&pci_bus_type); | ||
783 | if (dev_state->domain == NULL) | ||
784 | goto out_free_states; | ||
785 | |||
786 | amd_iommu_domain_direct_map(dev_state->domain); | ||
787 | |||
788 | ret = amd_iommu_domain_enable_v2(dev_state->domain, pasids); | ||
789 | if (ret) | ||
790 | goto out_free_domain; | ||
791 | |||
792 | ret = iommu_attach_device(dev_state->domain, &pdev->dev); | ||
793 | if (ret != 0) | ||
794 | goto out_free_domain; | ||
795 | |||
796 | spin_lock_irqsave(&state_lock, flags); | ||
797 | |||
798 | if (state_table[devid] != NULL) { | ||
799 | spin_unlock_irqrestore(&state_lock, flags); | ||
800 | ret = -EBUSY; | ||
801 | goto out_free_domain; | ||
802 | } | ||
803 | |||
804 | state_table[devid] = dev_state; | ||
805 | |||
806 | spin_unlock_irqrestore(&state_lock, flags); | ||
807 | |||
808 | return 0; | ||
809 | |||
810 | out_free_domain: | ||
811 | iommu_domain_free(dev_state->domain); | ||
812 | |||
813 | out_free_states: | ||
814 | free_page((unsigned long)dev_state->states); | ||
815 | |||
816 | out_free_dev_state: | ||
817 | kfree(dev_state); | ||
818 | |||
819 | return ret; | ||
820 | } | ||
821 | EXPORT_SYMBOL(amd_iommu_init_device); | ||
822 | |||
823 | void amd_iommu_free_device(struct pci_dev *pdev) | ||
824 | { | ||
825 | struct device_state *dev_state; | ||
826 | unsigned long flags; | ||
827 | u16 devid; | ||
828 | |||
829 | if (!amd_iommu_v2_supported()) | ||
830 | return; | ||
831 | |||
832 | devid = device_id(pdev); | ||
833 | |||
834 | spin_lock_irqsave(&state_lock, flags); | ||
835 | |||
836 | dev_state = state_table[devid]; | ||
837 | if (dev_state == NULL) { | ||
838 | spin_unlock_irqrestore(&state_lock, flags); | ||
839 | return; | ||
840 | } | ||
841 | |||
842 | state_table[devid] = NULL; | ||
843 | |||
844 | spin_unlock_irqrestore(&state_lock, flags); | ||
845 | |||
846 | /* Get rid of any remaining pasid states */ | ||
847 | free_pasid_states(dev_state); | ||
848 | |||
849 | put_device_state_wait(dev_state); | ||
850 | } | ||
851 | EXPORT_SYMBOL(amd_iommu_free_device); | ||
852 | |||
853 | int amd_iommu_set_invalid_ppr_cb(struct pci_dev *pdev, | ||
854 | amd_iommu_invalid_ppr_cb cb) | ||
855 | { | ||
856 | struct device_state *dev_state; | ||
857 | unsigned long flags; | ||
858 | u16 devid; | ||
859 | int ret; | ||
860 | |||
861 | if (!amd_iommu_v2_supported()) | ||
862 | return -ENODEV; | ||
863 | |||
864 | devid = device_id(pdev); | ||
865 | |||
866 | spin_lock_irqsave(&state_lock, flags); | ||
867 | |||
868 | ret = -EINVAL; | ||
869 | dev_state = state_table[devid]; | ||
870 | if (dev_state == NULL) | ||
871 | goto out_unlock; | ||
872 | |||
873 | dev_state->inv_ppr_cb = cb; | ||
874 | |||
875 | ret = 0; | ||
876 | |||
877 | out_unlock: | ||
878 | spin_unlock_irqrestore(&state_lock, flags); | ||
879 | |||
880 | return ret; | ||
881 | } | ||
882 | EXPORT_SYMBOL(amd_iommu_set_invalid_ppr_cb); | ||
883 | |||
884 | static int __init amd_iommu_v2_init(void) | ||
885 | { | ||
886 | size_t state_table_size; | ||
887 | int ret; | ||
888 | |||
889 | pr_info("AMD IOMMUv2 driver by Joerg Roedel <joerg.roedel@amd.com>"); | ||
890 | |||
891 | spin_lock_init(&state_lock); | ||
892 | |||
893 | state_table_size = MAX_DEVICES * sizeof(struct device_state *); | ||
894 | state_table = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, | ||
895 | get_order(state_table_size)); | ||
896 | if (state_table == NULL) | ||
897 | return -ENOMEM; | ||
898 | |||
899 | ret = -ENOMEM; | ||
900 | iommu_wq = create_workqueue("amd_iommu_v2"); | ||
901 | if (iommu_wq == NULL) | ||
902 | goto out_free; | ||
903 | |||
904 | ret = -ENOMEM; | ||
905 | empty_page_table = (u64 *)get_zeroed_page(GFP_KERNEL); | ||
906 | if (empty_page_table == NULL) | ||
907 | goto out_destroy_wq; | ||
908 | |||
909 | amd_iommu_register_ppr_notifier(&ppr_nb); | ||
910 | profile_event_register(PROFILE_TASK_EXIT, &profile_nb); | ||
911 | |||
912 | return 0; | ||
913 | |||
914 | out_destroy_wq: | ||
915 | destroy_workqueue(iommu_wq); | ||
916 | |||
917 | out_free: | ||
918 | free_pages((unsigned long)state_table, get_order(state_table_size)); | ||
919 | |||
920 | return ret; | ||
921 | } | ||
922 | |||
923 | static void __exit amd_iommu_v2_exit(void) | ||
924 | { | ||
925 | struct device_state *dev_state; | ||
926 | size_t state_table_size; | ||
927 | int i; | ||
928 | |||
929 | profile_event_unregister(PROFILE_TASK_EXIT, &profile_nb); | ||
930 | amd_iommu_unregister_ppr_notifier(&ppr_nb); | ||
931 | |||
932 | flush_workqueue(iommu_wq); | ||
933 | |||
934 | /* | ||
935 | * The loop below might call flush_workqueue(), so call | ||
936 | * destroy_workqueue() after it | ||
937 | */ | ||
938 | for (i = 0; i < MAX_DEVICES; ++i) { | ||
939 | dev_state = get_device_state(i); | ||
940 | |||
941 | if (dev_state == NULL) | ||
942 | continue; | ||
943 | |||
944 | WARN_ON_ONCE(1); | ||
945 | |||
946 | put_device_state(dev_state); | ||
947 | amd_iommu_free_device(dev_state->pdev); | ||
948 | } | ||
949 | |||
950 | destroy_workqueue(iommu_wq); | ||
951 | |||
952 | state_table_size = MAX_DEVICES * sizeof(struct device_state *); | ||
953 | free_pages((unsigned long)state_table, get_order(state_table_size)); | ||
954 | |||
955 | free_page((unsigned long)empty_page_table); | ||
956 | } | ||
957 | |||
958 | module_init(amd_iommu_v2_init); | ||
959 | module_exit(amd_iommu_v2_exit); | ||
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index c0c7820d4c46..c181883c2f9a 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -78,6 +78,24 @@ | |||
78 | #define LEVEL_STRIDE (9) | 78 | #define LEVEL_STRIDE (9) |
79 | #define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1) | 79 | #define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1) |
80 | 80 | ||
81 | /* | ||
82 | * This bitmap is used to advertise the page sizes our hardware support | ||
83 | * to the IOMMU core, which will then use this information to split | ||
84 | * physically contiguous memory regions it is mapping into page sizes | ||
85 | * that we support. | ||
86 | * | ||
87 | * Traditionally the IOMMU core just handed us the mappings directly, | ||
88 | * after making sure the size is an order of a 4KiB page and that the | ||
89 | * mapping has natural alignment. | ||
90 | * | ||
91 | * To retain this behavior, we currently advertise that we support | ||
92 | * all page sizes that are an order of 4KiB. | ||
93 | * | ||
94 | * If at some point we'd like to utilize the IOMMU core's new behavior, | ||
95 | * we could change this to advertise the real page sizes we support. | ||
96 | */ | ||
97 | #define INTEL_IOMMU_PGSIZES (~0xFFFUL) | ||
98 | |||
81 | static inline int agaw_to_level(int agaw) | 99 | static inline int agaw_to_level(int agaw) |
82 | { | 100 | { |
83 | return agaw + 2; | 101 | return agaw + 2; |
@@ -3524,7 +3542,7 @@ found: | |||
3524 | return 0; | 3542 | return 0; |
3525 | } | 3543 | } |
3526 | 3544 | ||
3527 | int dmar_parse_rmrr_atsr_dev(void) | 3545 | int __init dmar_parse_rmrr_atsr_dev(void) |
3528 | { | 3546 | { |
3529 | struct dmar_rmrr_unit *rmrr, *rmrr_n; | 3547 | struct dmar_rmrr_unit *rmrr, *rmrr_n; |
3530 | struct dmar_atsr_unit *atsr, *atsr_n; | 3548 | struct dmar_atsr_unit *atsr, *atsr_n; |
@@ -3979,12 +3997,11 @@ static void intel_iommu_detach_device(struct iommu_domain *domain, | |||
3979 | 3997 | ||
3980 | static int intel_iommu_map(struct iommu_domain *domain, | 3998 | static int intel_iommu_map(struct iommu_domain *domain, |
3981 | unsigned long iova, phys_addr_t hpa, | 3999 | unsigned long iova, phys_addr_t hpa, |
3982 | int gfp_order, int iommu_prot) | 4000 | size_t size, int iommu_prot) |
3983 | { | 4001 | { |
3984 | struct dmar_domain *dmar_domain = domain->priv; | 4002 | struct dmar_domain *dmar_domain = domain->priv; |
3985 | u64 max_addr; | 4003 | u64 max_addr; |
3986 | int prot = 0; | 4004 | int prot = 0; |
3987 | size_t size; | ||
3988 | int ret; | 4005 | int ret; |
3989 | 4006 | ||
3990 | if (iommu_prot & IOMMU_READ) | 4007 | if (iommu_prot & IOMMU_READ) |
@@ -3994,7 +4011,6 @@ static int intel_iommu_map(struct iommu_domain *domain, | |||
3994 | if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping) | 4011 | if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping) |
3995 | prot |= DMA_PTE_SNP; | 4012 | prot |= DMA_PTE_SNP; |
3996 | 4013 | ||
3997 | size = PAGE_SIZE << gfp_order; | ||
3998 | max_addr = iova + size; | 4014 | max_addr = iova + size; |
3999 | if (dmar_domain->max_addr < max_addr) { | 4015 | if (dmar_domain->max_addr < max_addr) { |
4000 | u64 end; | 4016 | u64 end; |
@@ -4017,11 +4033,10 @@ static int intel_iommu_map(struct iommu_domain *domain, | |||
4017 | return ret; | 4033 | return ret; |
4018 | } | 4034 | } |
4019 | 4035 | ||
4020 | static int intel_iommu_unmap(struct iommu_domain *domain, | 4036 | static size_t intel_iommu_unmap(struct iommu_domain *domain, |
4021 | unsigned long iova, int gfp_order) | 4037 | unsigned long iova, size_t size) |
4022 | { | 4038 | { |
4023 | struct dmar_domain *dmar_domain = domain->priv; | 4039 | struct dmar_domain *dmar_domain = domain->priv; |
4024 | size_t size = PAGE_SIZE << gfp_order; | ||
4025 | int order; | 4040 | int order; |
4026 | 4041 | ||
4027 | order = dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT, | 4042 | order = dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT, |
@@ -4030,7 +4045,7 @@ static int intel_iommu_unmap(struct iommu_domain *domain, | |||
4030 | if (dmar_domain->max_addr == iova + size) | 4045 | if (dmar_domain->max_addr == iova + size) |
4031 | dmar_domain->max_addr = iova; | 4046 | dmar_domain->max_addr = iova; |
4032 | 4047 | ||
4033 | return order; | 4048 | return PAGE_SIZE << order; |
4034 | } | 4049 | } |
4035 | 4050 | ||
4036 | static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, | 4051 | static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, |
@@ -4069,6 +4084,7 @@ static struct iommu_ops intel_iommu_ops = { | |||
4069 | .unmap = intel_iommu_unmap, | 4084 | .unmap = intel_iommu_unmap, |
4070 | .iova_to_phys = intel_iommu_iova_to_phys, | 4085 | .iova_to_phys = intel_iommu_iova_to_phys, |
4071 | .domain_has_cap = intel_iommu_domain_has_cap, | 4086 | .domain_has_cap = intel_iommu_domain_has_cap, |
4087 | .pgsize_bitmap = INTEL_IOMMU_PGSIZES, | ||
4072 | }; | 4088 | }; |
4073 | 4089 | ||
4074 | static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) | 4090 | static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) |
diff --git a/drivers/iommu/intr_remapping.c b/drivers/iommu/intr_remapping.c index 07c9f189f314..6777ca049471 100644 --- a/drivers/iommu/intr_remapping.c +++ b/drivers/iommu/intr_remapping.c | |||
@@ -773,7 +773,7 @@ int __init parse_ioapics_under_ir(void) | |||
773 | return ir_supported; | 773 | return ir_supported; |
774 | } | 774 | } |
775 | 775 | ||
776 | int ir_dev_scope_init(void) | 776 | int __init ir_dev_scope_init(void) |
777 | { | 777 | { |
778 | if (!intr_remapping_enabled) | 778 | if (!intr_remapping_enabled) |
779 | return 0; | 779 | return 0; |
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 2fb2963df553..84cdd8ac81f1 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c | |||
@@ -16,6 +16,8 @@ | |||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #define pr_fmt(fmt) "%s: " fmt, __func__ | ||
20 | |||
19 | #include <linux/device.h> | 21 | #include <linux/device.h> |
20 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
21 | #include <linux/bug.h> | 23 | #include <linux/bug.h> |
@@ -157,32 +159,125 @@ int iommu_domain_has_cap(struct iommu_domain *domain, | |||
157 | EXPORT_SYMBOL_GPL(iommu_domain_has_cap); | 159 | EXPORT_SYMBOL_GPL(iommu_domain_has_cap); |
158 | 160 | ||
159 | int iommu_map(struct iommu_domain *domain, unsigned long iova, | 161 | int iommu_map(struct iommu_domain *domain, unsigned long iova, |
160 | phys_addr_t paddr, int gfp_order, int prot) | 162 | phys_addr_t paddr, size_t size, int prot) |
161 | { | 163 | { |
162 | size_t size; | 164 | unsigned long orig_iova = iova; |
165 | unsigned int min_pagesz; | ||
166 | size_t orig_size = size; | ||
167 | int ret = 0; | ||
163 | 168 | ||
164 | if (unlikely(domain->ops->map == NULL)) | 169 | if (unlikely(domain->ops->map == NULL)) |
165 | return -ENODEV; | 170 | return -ENODEV; |
166 | 171 | ||
167 | size = PAGE_SIZE << gfp_order; | 172 | /* find out the minimum page size supported */ |
173 | min_pagesz = 1 << __ffs(domain->ops->pgsize_bitmap); | ||
174 | |||
175 | /* | ||
176 | * both the virtual address and the physical one, as well as | ||
177 | * the size of the mapping, must be aligned (at least) to the | ||
178 | * size of the smallest page supported by the hardware | ||
179 | */ | ||
180 | if (!IS_ALIGNED(iova | paddr | size, min_pagesz)) { | ||
181 | pr_err("unaligned: iova 0x%lx pa 0x%lx size 0x%lx min_pagesz " | ||
182 | "0x%x\n", iova, (unsigned long)paddr, | ||
183 | (unsigned long)size, min_pagesz); | ||
184 | return -EINVAL; | ||
185 | } | ||
186 | |||
187 | pr_debug("map: iova 0x%lx pa 0x%lx size 0x%lx\n", iova, | ||
188 | (unsigned long)paddr, (unsigned long)size); | ||
189 | |||
190 | while (size) { | ||
191 | unsigned long pgsize, addr_merge = iova | paddr; | ||
192 | unsigned int pgsize_idx; | ||
193 | |||
194 | /* Max page size that still fits into 'size' */ | ||
195 | pgsize_idx = __fls(size); | ||
196 | |||
197 | /* need to consider alignment requirements ? */ | ||
198 | if (likely(addr_merge)) { | ||
199 | /* Max page size allowed by both iova and paddr */ | ||
200 | unsigned int align_pgsize_idx = __ffs(addr_merge); | ||
201 | |||
202 | pgsize_idx = min(pgsize_idx, align_pgsize_idx); | ||
203 | } | ||
204 | |||
205 | /* build a mask of acceptable page sizes */ | ||
206 | pgsize = (1UL << (pgsize_idx + 1)) - 1; | ||
207 | |||
208 | /* throw away page sizes not supported by the hardware */ | ||
209 | pgsize &= domain->ops->pgsize_bitmap; | ||
168 | 210 | ||
169 | BUG_ON(!IS_ALIGNED(iova | paddr, size)); | 211 | /* make sure we're still sane */ |
212 | BUG_ON(!pgsize); | ||
170 | 213 | ||
171 | return domain->ops->map(domain, iova, paddr, gfp_order, prot); | 214 | /* pick the biggest page */ |
215 | pgsize_idx = __fls(pgsize); | ||
216 | pgsize = 1UL << pgsize_idx; | ||
217 | |||
218 | pr_debug("mapping: iova 0x%lx pa 0x%lx pgsize %lu\n", iova, | ||
219 | (unsigned long)paddr, pgsize); | ||
220 | |||
221 | ret = domain->ops->map(domain, iova, paddr, pgsize, prot); | ||
222 | if (ret) | ||
223 | break; | ||
224 | |||
225 | iova += pgsize; | ||
226 | paddr += pgsize; | ||
227 | size -= pgsize; | ||
228 | } | ||
229 | |||
230 | /* unroll mapping in case something went wrong */ | ||
231 | if (ret) | ||
232 | iommu_unmap(domain, orig_iova, orig_size - size); | ||
233 | |||
234 | return ret; | ||
172 | } | 235 | } |
173 | EXPORT_SYMBOL_GPL(iommu_map); | 236 | EXPORT_SYMBOL_GPL(iommu_map); |
174 | 237 | ||
175 | int iommu_unmap(struct iommu_domain *domain, unsigned long iova, int gfp_order) | 238 | size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) |
176 | { | 239 | { |
177 | size_t size; | 240 | size_t unmapped_page, unmapped = 0; |
241 | unsigned int min_pagesz; | ||
178 | 242 | ||
179 | if (unlikely(domain->ops->unmap == NULL)) | 243 | if (unlikely(domain->ops->unmap == NULL)) |
180 | return -ENODEV; | 244 | return -ENODEV; |
181 | 245 | ||
182 | size = PAGE_SIZE << gfp_order; | 246 | /* find out the minimum page size supported */ |
183 | 247 | min_pagesz = 1 << __ffs(domain->ops->pgsize_bitmap); | |
184 | BUG_ON(!IS_ALIGNED(iova, size)); | 248 | |
185 | 249 | /* | |
186 | return domain->ops->unmap(domain, iova, gfp_order); | 250 | * The virtual address, as well as the size of the mapping, must be |
251 | * aligned (at least) to the size of the smallest page supported | ||
252 | * by the hardware | ||
253 | */ | ||
254 | if (!IS_ALIGNED(iova | size, min_pagesz)) { | ||
255 | pr_err("unaligned: iova 0x%lx size 0x%lx min_pagesz 0x%x\n", | ||
256 | iova, (unsigned long)size, min_pagesz); | ||
257 | return -EINVAL; | ||
258 | } | ||
259 | |||
260 | pr_debug("unmap this: iova 0x%lx size 0x%lx\n", iova, | ||
261 | (unsigned long)size); | ||
262 | |||
263 | /* | ||
264 | * Keep iterating until we either unmap 'size' bytes (or more) | ||
265 | * or we hit an area that isn't mapped. | ||
266 | */ | ||
267 | while (unmapped < size) { | ||
268 | size_t left = size - unmapped; | ||
269 | |||
270 | unmapped_page = domain->ops->unmap(domain, iova, left); | ||
271 | if (!unmapped_page) | ||
272 | break; | ||
273 | |||
274 | pr_debug("unmapped: iova 0x%lx size %lx\n", iova, | ||
275 | (unsigned long)unmapped_page); | ||
276 | |||
277 | iova += unmapped_page; | ||
278 | unmapped += unmapped_page; | ||
279 | } | ||
280 | |||
281 | return unmapped; | ||
187 | } | 282 | } |
188 | EXPORT_SYMBOL_GPL(iommu_unmap); | 283 | EXPORT_SYMBOL_GPL(iommu_unmap); |
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c index 5865dd2e28f9..08a90b88e40d 100644 --- a/drivers/iommu/msm_iommu.c +++ b/drivers/iommu/msm_iommu.c | |||
@@ -42,6 +42,9 @@ __asm__ __volatile__ ( \ | |||
42 | #define RCP15_PRRR(reg) MRC(reg, p15, 0, c10, c2, 0) | 42 | #define RCP15_PRRR(reg) MRC(reg, p15, 0, c10, c2, 0) |
43 | #define RCP15_NMRR(reg) MRC(reg, p15, 0, c10, c2, 1) | 43 | #define RCP15_NMRR(reg) MRC(reg, p15, 0, c10, c2, 1) |
44 | 44 | ||
45 | /* bitmap of the page sizes currently supported */ | ||
46 | #define MSM_IOMMU_PGSIZES (SZ_4K | SZ_64K | SZ_1M | SZ_16M) | ||
47 | |||
45 | static int msm_iommu_tex_class[4]; | 48 | static int msm_iommu_tex_class[4]; |
46 | 49 | ||
47 | DEFINE_SPINLOCK(msm_iommu_lock); | 50 | DEFINE_SPINLOCK(msm_iommu_lock); |
@@ -352,7 +355,7 @@ fail: | |||
352 | } | 355 | } |
353 | 356 | ||
354 | static int msm_iommu_map(struct iommu_domain *domain, unsigned long va, | 357 | static int msm_iommu_map(struct iommu_domain *domain, unsigned long va, |
355 | phys_addr_t pa, int order, int prot) | 358 | phys_addr_t pa, size_t len, int prot) |
356 | { | 359 | { |
357 | struct msm_priv *priv; | 360 | struct msm_priv *priv; |
358 | unsigned long flags; | 361 | unsigned long flags; |
@@ -363,7 +366,6 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va, | |||
363 | unsigned long *sl_pte; | 366 | unsigned long *sl_pte; |
364 | unsigned long sl_offset; | 367 | unsigned long sl_offset; |
365 | unsigned int pgprot; | 368 | unsigned int pgprot; |
366 | size_t len = 0x1000UL << order; | ||
367 | int ret = 0, tex, sh; | 369 | int ret = 0, tex, sh; |
368 | 370 | ||
369 | spin_lock_irqsave(&msm_iommu_lock, flags); | 371 | spin_lock_irqsave(&msm_iommu_lock, flags); |
@@ -463,8 +465,8 @@ fail: | |||
463 | return ret; | 465 | return ret; |
464 | } | 466 | } |
465 | 467 | ||
466 | static int msm_iommu_unmap(struct iommu_domain *domain, unsigned long va, | 468 | static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long va, |
467 | int order) | 469 | size_t len) |
468 | { | 470 | { |
469 | struct msm_priv *priv; | 471 | struct msm_priv *priv; |
470 | unsigned long flags; | 472 | unsigned long flags; |
@@ -474,7 +476,6 @@ static int msm_iommu_unmap(struct iommu_domain *domain, unsigned long va, | |||
474 | unsigned long *sl_table; | 476 | unsigned long *sl_table; |
475 | unsigned long *sl_pte; | 477 | unsigned long *sl_pte; |
476 | unsigned long sl_offset; | 478 | unsigned long sl_offset; |
477 | size_t len = 0x1000UL << order; | ||
478 | int i, ret = 0; | 479 | int i, ret = 0; |
479 | 480 | ||
480 | spin_lock_irqsave(&msm_iommu_lock, flags); | 481 | spin_lock_irqsave(&msm_iommu_lock, flags); |
@@ -544,15 +545,12 @@ static int msm_iommu_unmap(struct iommu_domain *domain, unsigned long va, | |||
544 | 545 | ||
545 | ret = __flush_iotlb(domain); | 546 | ret = __flush_iotlb(domain); |
546 | 547 | ||
547 | /* | ||
548 | * the IOMMU API requires us to return the order of the unmapped | ||
549 | * page (on success). | ||
550 | */ | ||
551 | if (!ret) | ||
552 | ret = order; | ||
553 | fail: | 548 | fail: |
554 | spin_unlock_irqrestore(&msm_iommu_lock, flags); | 549 | spin_unlock_irqrestore(&msm_iommu_lock, flags); |
555 | return ret; | 550 | |
551 | /* the IOMMU API requires us to return how many bytes were unmapped */ | ||
552 | len = ret ? 0 : len; | ||
553 | return len; | ||
556 | } | 554 | } |
557 | 555 | ||
558 | static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain, | 556 | static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain, |
@@ -684,7 +682,8 @@ static struct iommu_ops msm_iommu_ops = { | |||
684 | .map = msm_iommu_map, | 682 | .map = msm_iommu_map, |
685 | .unmap = msm_iommu_unmap, | 683 | .unmap = msm_iommu_unmap, |
686 | .iova_to_phys = msm_iommu_iova_to_phys, | 684 | .iova_to_phys = msm_iommu_iova_to_phys, |
687 | .domain_has_cap = msm_iommu_domain_has_cap | 685 | .domain_has_cap = msm_iommu_domain_has_cap, |
686 | .pgsize_bitmap = MSM_IOMMU_PGSIZES, | ||
688 | }; | 687 | }; |
689 | 688 | ||
690 | static int __init get_tex_class(int icp, int ocp, int mt, int nos) | 689 | static int __init get_tex_class(int icp, int ocp, int mt, int nos) |
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 8f32b2bf7587..08cf7ec5b4a5 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c | |||
@@ -33,6 +33,9 @@ | |||
33 | (__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \ | 33 | (__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \ |
34 | __i++) | 34 | __i++) |
35 | 35 | ||
36 | /* bitmap of the page sizes currently supported */ | ||
37 | #define OMAP_IOMMU_PGSIZES (SZ_4K | SZ_64K | SZ_1M | SZ_16M) | ||
38 | |||
36 | /** | 39 | /** |
37 | * struct omap_iommu_domain - omap iommu domain | 40 | * struct omap_iommu_domain - omap iommu domain |
38 | * @pgtable: the page table | 41 | * @pgtable: the page table |
@@ -1019,12 +1022,11 @@ static void iopte_cachep_ctor(void *iopte) | |||
1019 | } | 1022 | } |
1020 | 1023 | ||
1021 | static int omap_iommu_map(struct iommu_domain *domain, unsigned long da, | 1024 | static int omap_iommu_map(struct iommu_domain *domain, unsigned long da, |
1022 | phys_addr_t pa, int order, int prot) | 1025 | phys_addr_t pa, size_t bytes, int prot) |
1023 | { | 1026 | { |
1024 | struct omap_iommu_domain *omap_domain = domain->priv; | 1027 | struct omap_iommu_domain *omap_domain = domain->priv; |
1025 | struct omap_iommu *oiommu = omap_domain->iommu_dev; | 1028 | struct omap_iommu *oiommu = omap_domain->iommu_dev; |
1026 | struct device *dev = oiommu->dev; | 1029 | struct device *dev = oiommu->dev; |
1027 | size_t bytes = PAGE_SIZE << order; | ||
1028 | struct iotlb_entry e; | 1030 | struct iotlb_entry e; |
1029 | int omap_pgsz; | 1031 | int omap_pgsz; |
1030 | u32 ret, flags; | 1032 | u32 ret, flags; |
@@ -1049,19 +1051,16 @@ static int omap_iommu_map(struct iommu_domain *domain, unsigned long da, | |||
1049 | return ret; | 1051 | return ret; |
1050 | } | 1052 | } |
1051 | 1053 | ||
1052 | static int omap_iommu_unmap(struct iommu_domain *domain, unsigned long da, | 1054 | static size_t omap_iommu_unmap(struct iommu_domain *domain, unsigned long da, |
1053 | int order) | 1055 | size_t size) |
1054 | { | 1056 | { |
1055 | struct omap_iommu_domain *omap_domain = domain->priv; | 1057 | struct omap_iommu_domain *omap_domain = domain->priv; |
1056 | struct omap_iommu *oiommu = omap_domain->iommu_dev; | 1058 | struct omap_iommu *oiommu = omap_domain->iommu_dev; |
1057 | struct device *dev = oiommu->dev; | 1059 | struct device *dev = oiommu->dev; |
1058 | size_t unmap_size; | ||
1059 | |||
1060 | dev_dbg(dev, "unmapping da 0x%lx order %d\n", da, order); | ||
1061 | 1060 | ||
1062 | unmap_size = iopgtable_clear_entry(oiommu, da); | 1061 | dev_dbg(dev, "unmapping da 0x%lx size %u\n", da, size); |
1063 | 1062 | ||
1064 | return unmap_size ? get_order(unmap_size) : -EINVAL; | 1063 | return iopgtable_clear_entry(oiommu, da); |
1065 | } | 1064 | } |
1066 | 1065 | ||
1067 | static int | 1066 | static int |
@@ -1211,6 +1210,7 @@ static struct iommu_ops omap_iommu_ops = { | |||
1211 | .unmap = omap_iommu_unmap, | 1210 | .unmap = omap_iommu_unmap, |
1212 | .iova_to_phys = omap_iommu_iova_to_phys, | 1211 | .iova_to_phys = omap_iommu_iova_to_phys, |
1213 | .domain_has_cap = omap_iommu_domain_has_cap, | 1212 | .domain_has_cap = omap_iommu_domain_has_cap, |
1213 | .pgsize_bitmap = OMAP_IOMMU_PGSIZES, | ||
1214 | }; | 1214 | }; |
1215 | 1215 | ||
1216 | static int __init omap_iommu_init(void) | 1216 | static int __init omap_iommu_init(void) |
diff --git a/drivers/iommu/omap-iovmm.c b/drivers/iommu/omap-iovmm.c index 46be456fcc00..6edc4ceba197 100644 --- a/drivers/iommu/omap-iovmm.c +++ b/drivers/iommu/omap-iovmm.c | |||
@@ -410,7 +410,6 @@ static int map_iovm_area(struct iommu_domain *domain, struct iovm_struct *new, | |||
410 | unsigned int i, j; | 410 | unsigned int i, j; |
411 | struct scatterlist *sg; | 411 | struct scatterlist *sg; |
412 | u32 da = new->da_start; | 412 | u32 da = new->da_start; |
413 | int order; | ||
414 | 413 | ||
415 | if (!domain || !sgt) | 414 | if (!domain || !sgt) |
416 | return -EINVAL; | 415 | return -EINVAL; |
@@ -429,12 +428,10 @@ static int map_iovm_area(struct iommu_domain *domain, struct iovm_struct *new, | |||
429 | if (bytes_to_iopgsz(bytes) < 0) | 428 | if (bytes_to_iopgsz(bytes) < 0) |
430 | goto err_out; | 429 | goto err_out; |
431 | 430 | ||
432 | order = get_order(bytes); | ||
433 | |||
434 | pr_debug("%s: [%d] %08x %08x(%x)\n", __func__, | 431 | pr_debug("%s: [%d] %08x %08x(%x)\n", __func__, |
435 | i, da, pa, bytes); | 432 | i, da, pa, bytes); |
436 | 433 | ||
437 | err = iommu_map(domain, da, pa, order, flags); | 434 | err = iommu_map(domain, da, pa, bytes, flags); |
438 | if (err) | 435 | if (err) |
439 | goto err_out; | 436 | goto err_out; |
440 | 437 | ||
@@ -449,10 +446,9 @@ err_out: | |||
449 | size_t bytes; | 446 | size_t bytes; |
450 | 447 | ||
451 | bytes = sg->length + sg->offset; | 448 | bytes = sg->length + sg->offset; |
452 | order = get_order(bytes); | ||
453 | 449 | ||
454 | /* ignore failures.. we're already handling one */ | 450 | /* ignore failures.. we're already handling one */ |
455 | iommu_unmap(domain, da, order); | 451 | iommu_unmap(domain, da, bytes); |
456 | 452 | ||
457 | da += bytes; | 453 | da += bytes; |
458 | } | 454 | } |
@@ -467,7 +463,8 @@ static void unmap_iovm_area(struct iommu_domain *domain, struct omap_iommu *obj, | |||
467 | size_t total = area->da_end - area->da_start; | 463 | size_t total = area->da_end - area->da_start; |
468 | const struct sg_table *sgt = area->sgt; | 464 | const struct sg_table *sgt = area->sgt; |
469 | struct scatterlist *sg; | 465 | struct scatterlist *sg; |
470 | int i, err; | 466 | int i; |
467 | size_t unmapped; | ||
471 | 468 | ||
472 | BUG_ON(!sgtable_ok(sgt)); | 469 | BUG_ON(!sgtable_ok(sgt)); |
473 | BUG_ON((!total) || !IS_ALIGNED(total, PAGE_SIZE)); | 470 | BUG_ON((!total) || !IS_ALIGNED(total, PAGE_SIZE)); |
@@ -475,13 +472,11 @@ static void unmap_iovm_area(struct iommu_domain *domain, struct omap_iommu *obj, | |||
475 | start = area->da_start; | 472 | start = area->da_start; |
476 | for_each_sg(sgt->sgl, sg, sgt->nents, i) { | 473 | for_each_sg(sgt->sgl, sg, sgt->nents, i) { |
477 | size_t bytes; | 474 | size_t bytes; |
478 | int order; | ||
479 | 475 | ||
480 | bytes = sg->length + sg->offset; | 476 | bytes = sg->length + sg->offset; |
481 | order = get_order(bytes); | ||
482 | 477 | ||
483 | err = iommu_unmap(domain, start, order); | 478 | unmapped = iommu_unmap(domain, start, bytes); |
484 | if (err < 0) | 479 | if (unmapped < bytes) |
485 | break; | 480 | break; |
486 | 481 | ||
487 | dev_dbg(obj->dev, "%s: unmap %08x(%x) %08x\n", | 482 | dev_dbg(obj->dev, "%s: unmap %08x(%x) %08x\n", |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 7878712721bf..b6907118283a 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -1106,10 +1106,12 @@ void bitmap_write_all(struct bitmap *bitmap) | |||
1106 | */ | 1106 | */ |
1107 | int i; | 1107 | int i; |
1108 | 1108 | ||
1109 | spin_lock_irq(&bitmap->lock); | ||
1109 | for (i = 0; i < bitmap->file_pages; i++) | 1110 | for (i = 0; i < bitmap->file_pages; i++) |
1110 | set_page_attr(bitmap, bitmap->filemap[i], | 1111 | set_page_attr(bitmap, bitmap->filemap[i], |
1111 | BITMAP_PAGE_NEEDWRITE); | 1112 | BITMAP_PAGE_NEEDWRITE); |
1112 | bitmap->allclean = 0; | 1113 | bitmap->allclean = 0; |
1114 | spin_unlock_irq(&bitmap->lock); | ||
1113 | } | 1115 | } |
1114 | 1116 | ||
1115 | static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc) | 1117 | static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc) |
@@ -1605,7 +1607,9 @@ void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e) | |||
1605 | for (chunk = s; chunk <= e; chunk++) { | 1607 | for (chunk = s; chunk <= e; chunk++) { |
1606 | sector_t sec = (sector_t)chunk << CHUNK_BLOCK_SHIFT(bitmap); | 1608 | sector_t sec = (sector_t)chunk << CHUNK_BLOCK_SHIFT(bitmap); |
1607 | bitmap_set_memory_bits(bitmap, sec, 1); | 1609 | bitmap_set_memory_bits(bitmap, sec, 1); |
1610 | spin_lock_irq(&bitmap->lock); | ||
1608 | bitmap_file_set_bit(bitmap, sec); | 1611 | bitmap_file_set_bit(bitmap, sec); |
1612 | spin_unlock_irq(&bitmap->lock); | ||
1609 | if (sec < bitmap->mddev->recovery_cp) | 1613 | if (sec < bitmap->mddev->recovery_cp) |
1610 | /* We are asserting that the array is dirty, | 1614 | /* We are asserting that the array is dirty, |
1611 | * so move the recovery_cp address back so | 1615 | * so move the recovery_cp address back so |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 84acfe7d10e4..ee981737edfc 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -570,7 +570,7 @@ static void mddev_put(struct mddev *mddev) | |||
570 | mddev->ctime == 0 && !mddev->hold_active) { | 570 | mddev->ctime == 0 && !mddev->hold_active) { |
571 | /* Array is not configured at all, and not held active, | 571 | /* Array is not configured at all, and not held active, |
572 | * so destroy it */ | 572 | * so destroy it */ |
573 | list_del(&mddev->all_mddevs); | 573 | list_del_init(&mddev->all_mddevs); |
574 | bs = mddev->bio_set; | 574 | bs = mddev->bio_set; |
575 | mddev->bio_set = NULL; | 575 | mddev->bio_set = NULL; |
576 | if (mddev->gendisk) { | 576 | if (mddev->gendisk) { |
@@ -2546,7 +2546,8 @@ state_show(struct md_rdev *rdev, char *page) | |||
2546 | sep = ","; | 2546 | sep = ","; |
2547 | } | 2547 | } |
2548 | if (test_bit(Blocked, &rdev->flags) || | 2548 | if (test_bit(Blocked, &rdev->flags) || |
2549 | rdev->badblocks.unacked_exist) { | 2549 | (rdev->badblocks.unacked_exist |
2550 | && !test_bit(Faulty, &rdev->flags))) { | ||
2550 | len += sprintf(page+len, "%sblocked", sep); | 2551 | len += sprintf(page+len, "%sblocked", sep); |
2551 | sep = ","; | 2552 | sep = ","; |
2552 | } | 2553 | } |
@@ -3788,6 +3789,8 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) | |||
3788 | if (err) | 3789 | if (err) |
3789 | return err; | 3790 | return err; |
3790 | else { | 3791 | else { |
3792 | if (mddev->hold_active == UNTIL_IOCTL) | ||
3793 | mddev->hold_active = 0; | ||
3791 | sysfs_notify_dirent_safe(mddev->sysfs_state); | 3794 | sysfs_notify_dirent_safe(mddev->sysfs_state); |
3792 | return len; | 3795 | return len; |
3793 | } | 3796 | } |
@@ -4487,11 +4490,20 @@ md_attr_show(struct kobject *kobj, struct attribute *attr, char *page) | |||
4487 | 4490 | ||
4488 | if (!entry->show) | 4491 | if (!entry->show) |
4489 | return -EIO; | 4492 | return -EIO; |
4493 | spin_lock(&all_mddevs_lock); | ||
4494 | if (list_empty(&mddev->all_mddevs)) { | ||
4495 | spin_unlock(&all_mddevs_lock); | ||
4496 | return -EBUSY; | ||
4497 | } | ||
4498 | mddev_get(mddev); | ||
4499 | spin_unlock(&all_mddevs_lock); | ||
4500 | |||
4490 | rv = mddev_lock(mddev); | 4501 | rv = mddev_lock(mddev); |
4491 | if (!rv) { | 4502 | if (!rv) { |
4492 | rv = entry->show(mddev, page); | 4503 | rv = entry->show(mddev, page); |
4493 | mddev_unlock(mddev); | 4504 | mddev_unlock(mddev); |
4494 | } | 4505 | } |
4506 | mddev_put(mddev); | ||
4495 | return rv; | 4507 | return rv; |
4496 | } | 4508 | } |
4497 | 4509 | ||
@@ -4507,13 +4519,19 @@ md_attr_store(struct kobject *kobj, struct attribute *attr, | |||
4507 | return -EIO; | 4519 | return -EIO; |
4508 | if (!capable(CAP_SYS_ADMIN)) | 4520 | if (!capable(CAP_SYS_ADMIN)) |
4509 | return -EACCES; | 4521 | return -EACCES; |
4522 | spin_lock(&all_mddevs_lock); | ||
4523 | if (list_empty(&mddev->all_mddevs)) { | ||
4524 | spin_unlock(&all_mddevs_lock); | ||
4525 | return -EBUSY; | ||
4526 | } | ||
4527 | mddev_get(mddev); | ||
4528 | spin_unlock(&all_mddevs_lock); | ||
4510 | rv = mddev_lock(mddev); | 4529 | rv = mddev_lock(mddev); |
4511 | if (mddev->hold_active == UNTIL_IOCTL) | ||
4512 | mddev->hold_active = 0; | ||
4513 | if (!rv) { | 4530 | if (!rv) { |
4514 | rv = entry->store(mddev, page, length); | 4531 | rv = entry->store(mddev, page, length); |
4515 | mddev_unlock(mddev); | 4532 | mddev_unlock(mddev); |
4516 | } | 4533 | } |
4534 | mddev_put(mddev); | ||
4517 | return rv; | 4535 | return rv; |
4518 | } | 4536 | } |
4519 | 4537 | ||
@@ -7840,6 +7858,7 @@ int rdev_set_badblocks(struct md_rdev *rdev, sector_t s, int sectors, | |||
7840 | s + rdev->data_offset, sectors, acknowledged); | 7858 | s + rdev->data_offset, sectors, acknowledged); |
7841 | if (rv) { | 7859 | if (rv) { |
7842 | /* Make sure they get written out promptly */ | 7860 | /* Make sure they get written out promptly */ |
7861 | sysfs_notify_dirent_safe(rdev->sysfs_state); | ||
7843 | set_bit(MD_CHANGE_CLEAN, &rdev->mddev->flags); | 7862 | set_bit(MD_CHANGE_CLEAN, &rdev->mddev->flags); |
7844 | md_wakeup_thread(rdev->mddev->thread); | 7863 | md_wakeup_thread(rdev->mddev->thread); |
7845 | } | 7864 | } |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 297e26092178..31670f8d6b65 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -3036,6 +3036,8 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) | |||
3036 | if (dev->written) | 3036 | if (dev->written) |
3037 | s->written++; | 3037 | s->written++; |
3038 | rdev = rcu_dereference(conf->disks[i].rdev); | 3038 | rdev = rcu_dereference(conf->disks[i].rdev); |
3039 | if (rdev && test_bit(Faulty, &rdev->flags)) | ||
3040 | rdev = NULL; | ||
3039 | if (rdev) { | 3041 | if (rdev) { |
3040 | is_bad = is_badblock(rdev, sh->sector, STRIPE_SECTORS, | 3042 | is_bad = is_badblock(rdev, sh->sector, STRIPE_SECTORS, |
3041 | &first_bad, &bad_sectors); | 3043 | &first_bad, &bad_sectors); |
@@ -3063,12 +3065,12 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) | |||
3063 | } | 3065 | } |
3064 | } else if (test_bit(In_sync, &rdev->flags)) | 3066 | } else if (test_bit(In_sync, &rdev->flags)) |
3065 | set_bit(R5_Insync, &dev->flags); | 3067 | set_bit(R5_Insync, &dev->flags); |
3066 | else if (!test_bit(Faulty, &rdev->flags)) { | 3068 | else { |
3067 | /* in sync if before recovery_offset */ | 3069 | /* in sync if before recovery_offset */ |
3068 | if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset) | 3070 | if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset) |
3069 | set_bit(R5_Insync, &dev->flags); | 3071 | set_bit(R5_Insync, &dev->flags); |
3070 | } | 3072 | } |
3071 | if (test_bit(R5_WriteError, &dev->flags)) { | 3073 | if (rdev && test_bit(R5_WriteError, &dev->flags)) { |
3072 | clear_bit(R5_Insync, &dev->flags); | 3074 | clear_bit(R5_Insync, &dev->flags); |
3073 | if (!test_bit(Faulty, &rdev->flags)) { | 3075 | if (!test_bit(Faulty, &rdev->flags)) { |
3074 | s->handle_bad_blocks = 1; | 3076 | s->handle_bad_blocks = 1; |
@@ -3076,7 +3078,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) | |||
3076 | } else | 3078 | } else |
3077 | clear_bit(R5_WriteError, &dev->flags); | 3079 | clear_bit(R5_WriteError, &dev->flags); |
3078 | } | 3080 | } |
3079 | if (test_bit(R5_MadeGood, &dev->flags)) { | 3081 | if (rdev && test_bit(R5_MadeGood, &dev->flags)) { |
3080 | if (!test_bit(Faulty, &rdev->flags)) { | 3082 | if (!test_bit(Faulty, &rdev->flags)) { |
3081 | s->handle_bad_blocks = 1; | 3083 | s->handle_bad_blocks = 1; |
3082 | atomic_inc(&rdev->nr_pending); | 3084 | atomic_inc(&rdev->nr_pending); |
diff --git a/drivers/net/ethernet/pasemi/Makefile b/drivers/net/ethernet/pasemi/Makefile index 05db5434bafc..90497ffb1ac3 100644 --- a/drivers/net/ethernet/pasemi/Makefile +++ b/drivers/net/ethernet/pasemi/Makefile | |||
@@ -2,4 +2,5 @@ | |||
2 | # Makefile for the A Semi network device drivers. | 2 | # Makefile for the A Semi network device drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o pasemi_mac_ethtool.o | 5 | obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o |
6 | pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o | ||
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 6f06aa10f0d7..67bf07819992 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -1183,11 +1183,13 @@ static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr) | |||
1183 | return value; | 1183 | return value; |
1184 | } | 1184 | } |
1185 | 1185 | ||
1186 | static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) | 1186 | static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) |
1187 | { | 1187 | { |
1188 | RTL_W16(IntrMask, 0x0000); | 1188 | void __iomem *ioaddr = tp->mmio_addr; |
1189 | 1189 | ||
1190 | RTL_W16(IntrStatus, 0xffff); | 1190 | RTL_W16(IntrMask, 0x0000); |
1191 | RTL_W16(IntrStatus, tp->intr_event); | ||
1192 | RTL_R8(ChipCmd); | ||
1191 | } | 1193 | } |
1192 | 1194 | ||
1193 | static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) | 1195 | static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) |
@@ -3933,8 +3935,6 @@ static void rtl_hw_reset(struct rtl8169_private *tp) | |||
3933 | break; | 3935 | break; |
3934 | udelay(100); | 3936 | udelay(100); |
3935 | } | 3937 | } |
3936 | |||
3937 | rtl8169_init_ring_indexes(tp); | ||
3938 | } | 3938 | } |
3939 | 3939 | ||
3940 | static int __devinit | 3940 | static int __devinit |
@@ -4339,7 +4339,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) | |||
4339 | void __iomem *ioaddr = tp->mmio_addr; | 4339 | void __iomem *ioaddr = tp->mmio_addr; |
4340 | 4340 | ||
4341 | /* Disable interrupts */ | 4341 | /* Disable interrupts */ |
4342 | rtl8169_irq_mask_and_ack(ioaddr); | 4342 | rtl8169_irq_mask_and_ack(tp); |
4343 | 4343 | ||
4344 | rtl_rx_close(tp); | 4344 | rtl_rx_close(tp); |
4345 | 4345 | ||
@@ -4885,8 +4885,7 @@ static void rtl_hw_start_8168(struct net_device *dev) | |||
4885 | RTL_W16(IntrMitigate, 0x5151); | 4885 | RTL_W16(IntrMitigate, 0x5151); |
4886 | 4886 | ||
4887 | /* Work around for RxFIFO overflow. */ | 4887 | /* Work around for RxFIFO overflow. */ |
4888 | if (tp->mac_version == RTL_GIGA_MAC_VER_11 || | 4888 | if (tp->mac_version == RTL_GIGA_MAC_VER_11) { |
4889 | tp->mac_version == RTL_GIGA_MAC_VER_22) { | ||
4890 | tp->intr_event |= RxFIFOOver | PCSTimeout; | 4889 | tp->intr_event |= RxFIFOOver | PCSTimeout; |
4891 | tp->intr_event &= ~RxOverflow; | 4890 | tp->intr_event &= ~RxOverflow; |
4892 | } | 4891 | } |
@@ -5076,6 +5075,11 @@ static void rtl_hw_start_8101(struct net_device *dev) | |||
5076 | void __iomem *ioaddr = tp->mmio_addr; | 5075 | void __iomem *ioaddr = tp->mmio_addr; |
5077 | struct pci_dev *pdev = tp->pci_dev; | 5076 | struct pci_dev *pdev = tp->pci_dev; |
5078 | 5077 | ||
5078 | if (tp->mac_version >= RTL_GIGA_MAC_VER_30) { | ||
5079 | tp->intr_event &= ~RxFIFOOver; | ||
5080 | tp->napi_event &= ~RxFIFOOver; | ||
5081 | } | ||
5082 | |||
5079 | if (tp->mac_version == RTL_GIGA_MAC_VER_13 || | 5083 | if (tp->mac_version == RTL_GIGA_MAC_VER_13 || |
5080 | tp->mac_version == RTL_GIGA_MAC_VER_16) { | 5084 | tp->mac_version == RTL_GIGA_MAC_VER_16) { |
5081 | int cap = pci_pcie_cap(pdev); | 5085 | int cap = pci_pcie_cap(pdev); |
@@ -5342,7 +5346,7 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev) | |||
5342 | /* Wait for any pending NAPI task to complete */ | 5346 | /* Wait for any pending NAPI task to complete */ |
5343 | napi_disable(&tp->napi); | 5347 | napi_disable(&tp->napi); |
5344 | 5348 | ||
5345 | rtl8169_irq_mask_and_ack(ioaddr); | 5349 | rtl8169_irq_mask_and_ack(tp); |
5346 | 5350 | ||
5347 | tp->intr_mask = 0xffff; | 5351 | tp->intr_mask = 0xffff; |
5348 | RTL_W16(IntrMask, tp->intr_event); | 5352 | RTL_W16(IntrMask, tp->intr_event); |
@@ -5389,14 +5393,16 @@ static void rtl8169_reset_task(struct work_struct *work) | |||
5389 | if (!netif_running(dev)) | 5393 | if (!netif_running(dev)) |
5390 | goto out_unlock; | 5394 | goto out_unlock; |
5391 | 5395 | ||
5396 | rtl8169_hw_reset(tp); | ||
5397 | |||
5392 | rtl8169_wait_for_quiescence(dev); | 5398 | rtl8169_wait_for_quiescence(dev); |
5393 | 5399 | ||
5394 | for (i = 0; i < NUM_RX_DESC; i++) | 5400 | for (i = 0; i < NUM_RX_DESC; i++) |
5395 | rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz); | 5401 | rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz); |
5396 | 5402 | ||
5397 | rtl8169_tx_clear(tp); | 5403 | rtl8169_tx_clear(tp); |
5404 | rtl8169_init_ring_indexes(tp); | ||
5398 | 5405 | ||
5399 | rtl8169_hw_reset(tp); | ||
5400 | rtl_hw_start(dev); | 5406 | rtl_hw_start(dev); |
5401 | netif_wake_queue(dev); | 5407 | netif_wake_queue(dev); |
5402 | rtl8169_check_link_status(dev, tp, tp->mmio_addr); | 5408 | rtl8169_check_link_status(dev, tp, tp->mmio_addr); |
@@ -5407,11 +5413,6 @@ out_unlock: | |||
5407 | 5413 | ||
5408 | static void rtl8169_tx_timeout(struct net_device *dev) | 5414 | static void rtl8169_tx_timeout(struct net_device *dev) |
5409 | { | 5415 | { |
5410 | struct rtl8169_private *tp = netdev_priv(dev); | ||
5411 | |||
5412 | rtl8169_hw_reset(tp); | ||
5413 | |||
5414 | /* Let's wait a bit while any (async) irq lands on */ | ||
5415 | rtl8169_schedule_work(dev, rtl8169_reset_task); | 5416 | rtl8169_schedule_work(dev, rtl8169_reset_task); |
5416 | } | 5417 | } |
5417 | 5418 | ||
@@ -5804,6 +5805,10 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
5804 | */ | 5805 | */ |
5805 | status = RTL_R16(IntrStatus); | 5806 | status = RTL_R16(IntrStatus); |
5806 | while (status && status != 0xffff) { | 5807 | while (status && status != 0xffff) { |
5808 | status &= tp->intr_event; | ||
5809 | if (!status) | ||
5810 | break; | ||
5811 | |||
5807 | handled = 1; | 5812 | handled = 1; |
5808 | 5813 | ||
5809 | /* Handle all of the error cases first. These will reset | 5814 | /* Handle all of the error cases first. These will reset |
@@ -5818,27 +5823,9 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
5818 | switch (tp->mac_version) { | 5823 | switch (tp->mac_version) { |
5819 | /* Work around for rx fifo overflow */ | 5824 | /* Work around for rx fifo overflow */ |
5820 | case RTL_GIGA_MAC_VER_11: | 5825 | case RTL_GIGA_MAC_VER_11: |
5821 | case RTL_GIGA_MAC_VER_22: | ||
5822 | case RTL_GIGA_MAC_VER_26: | ||
5823 | netif_stop_queue(dev); | 5826 | netif_stop_queue(dev); |
5824 | rtl8169_tx_timeout(dev); | 5827 | rtl8169_tx_timeout(dev); |
5825 | goto done; | 5828 | goto done; |
5826 | /* Testers needed. */ | ||
5827 | case RTL_GIGA_MAC_VER_17: | ||
5828 | case RTL_GIGA_MAC_VER_19: | ||
5829 | case RTL_GIGA_MAC_VER_20: | ||
5830 | case RTL_GIGA_MAC_VER_21: | ||
5831 | case RTL_GIGA_MAC_VER_23: | ||
5832 | case RTL_GIGA_MAC_VER_24: | ||
5833 | case RTL_GIGA_MAC_VER_27: | ||
5834 | case RTL_GIGA_MAC_VER_28: | ||
5835 | case RTL_GIGA_MAC_VER_31: | ||
5836 | /* Experimental science. Pktgen proof. */ | ||
5837 | case RTL_GIGA_MAC_VER_12: | ||
5838 | case RTL_GIGA_MAC_VER_25: | ||
5839 | if (status == RxFIFOOver) | ||
5840 | goto done; | ||
5841 | break; | ||
5842 | default: | 5829 | default: |
5843 | break; | 5830 | break; |
5844 | } | 5831 | } |
diff --git a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c index 10826d8a2a2d..1187a1169eb2 100644 --- a/drivers/net/ethernet/tile/tilepro.c +++ b/drivers/net/ethernet/tile/tilepro.c | |||
@@ -926,7 +926,7 @@ static int tile_net_poll(struct napi_struct *napi, int budget) | |||
926 | goto done; | 926 | goto done; |
927 | 927 | ||
928 | /* Re-enable the ingress interrupt. */ | 928 | /* Re-enable the ingress interrupt. */ |
929 | enable_percpu_irq(priv->intr_id); | 929 | enable_percpu_irq(priv->intr_id, 0); |
930 | 930 | ||
931 | /* HACK: Avoid the "rotting packet" problem (see above). */ | 931 | /* HACK: Avoid the "rotting packet" problem (see above). */ |
932 | if (qup->__packet_receive_read != | 932 | if (qup->__packet_receive_read != |
@@ -1296,7 +1296,7 @@ static void tile_net_open_enable(void *dev_ptr) | |||
1296 | info->napi_enabled = true; | 1296 | info->napi_enabled = true; |
1297 | 1297 | ||
1298 | /* Enable the ingress interrupt. */ | 1298 | /* Enable the ingress interrupt. */ |
1299 | enable_percpu_irq(priv->intr_id); | 1299 | enable_percpu_irq(priv->intr_id, 0); |
1300 | } | 1300 | } |
1301 | 1301 | ||
1302 | 1302 | ||
@@ -1697,7 +1697,7 @@ static unsigned int tile_net_tx_frags(lepp_frag_t *frags, | |||
1697 | for (i = 0; i < sh->nr_frags; i++) { | 1697 | for (i = 0; i < sh->nr_frags; i++) { |
1698 | 1698 | ||
1699 | skb_frag_t *f = &sh->frags[i]; | 1699 | skb_frag_t *f = &sh->frags[i]; |
1700 | unsigned long pfn = page_to_pfn(f->page); | 1700 | unsigned long pfn = page_to_pfn(skb_frag_page(f)); |
1701 | 1701 | ||
1702 | /* FIXME: Compute "hash_for_home" properly. */ | 1702 | /* FIXME: Compute "hash_for_home" properly. */ |
1703 | /* ISSUE: The hypervisor checks CHIP_HAS_REV1_DMA_PACKETS(). */ | 1703 | /* ISSUE: The hypervisor checks CHIP_HAS_REV1_DMA_PACKETS(). */ |
@@ -1706,7 +1706,7 @@ static unsigned int tile_net_tx_frags(lepp_frag_t *frags, | |||
1706 | /* FIXME: Hmmm. */ | 1706 | /* FIXME: Hmmm. */ |
1707 | if (!hash_default) { | 1707 | if (!hash_default) { |
1708 | void *va = pfn_to_kaddr(pfn) + f->page_offset; | 1708 | void *va = pfn_to_kaddr(pfn) + f->page_offset; |
1709 | BUG_ON(PageHighMem(f->page)); | 1709 | BUG_ON(PageHighMem(skb_frag_page(f))); |
1710 | finv_buffer_remote(va, f->size, 0); | 1710 | finv_buffer_remote(va, f->size, 0); |
1711 | } | 1711 | } |
1712 | 1712 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index e12b48c2cff6..dd008b0e6417 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -191,6 +191,7 @@ static struct iwl_base_params iwl1000_base_params = { | |||
191 | .chain_noise_scale = 1000, | 191 | .chain_noise_scale = 1000, |
192 | .wd_timeout = IWL_DEF_WD_TIMEOUT, | 192 | .wd_timeout = IWL_DEF_WD_TIMEOUT, |
193 | .max_event_log_size = 128, | 193 | .max_event_log_size = 128, |
194 | .wd_disable = true, | ||
194 | }; | 195 | }; |
195 | static struct iwl_ht_params iwl1000_ht_params = { | 196 | static struct iwl_ht_params iwl1000_ht_params = { |
196 | .ht_greenfield_support = true, | 197 | .ht_greenfield_support = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index c511c98a89a8..f55fb2d1af52 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -364,6 +364,7 @@ static struct iwl_base_params iwl5000_base_params = { | |||
364 | .wd_timeout = IWL_LONG_WD_TIMEOUT, | 364 | .wd_timeout = IWL_LONG_WD_TIMEOUT, |
365 | .max_event_log_size = 512, | 365 | .max_event_log_size = 512, |
366 | .no_idle_support = true, | 366 | .no_idle_support = true, |
367 | .wd_disable = true, | ||
367 | }; | 368 | }; |
368 | static struct iwl_ht_params iwl5000_ht_params = { | 369 | static struct iwl_ht_params iwl5000_ht_params = { |
369 | .ht_greenfield_support = true, | 370 | .ht_greenfield_support = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 58a381c01c89..a7a6def40d05 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -528,6 +528,24 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
528 | return 0; | 528 | return 0; |
529 | } | 529 | } |
530 | 530 | ||
531 | void iwlagn_config_ht40(struct ieee80211_conf *conf, | ||
532 | struct iwl_rxon_context *ctx) | ||
533 | { | ||
534 | if (conf_is_ht40_minus(conf)) { | ||
535 | ctx->ht.extension_chan_offset = | ||
536 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
537 | ctx->ht.is_40mhz = true; | ||
538 | } else if (conf_is_ht40_plus(conf)) { | ||
539 | ctx->ht.extension_chan_offset = | ||
540 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
541 | ctx->ht.is_40mhz = true; | ||
542 | } else { | ||
543 | ctx->ht.extension_chan_offset = | ||
544 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
545 | ctx->ht.is_40mhz = false; | ||
546 | } | ||
547 | } | ||
548 | |||
531 | int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | 549 | int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) |
532 | { | 550 | { |
533 | struct iwl_priv *priv = hw->priv; | 551 | struct iwl_priv *priv = hw->priv; |
@@ -586,19 +604,11 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
586 | ctx->ht.enabled = conf_is_ht(conf); | 604 | ctx->ht.enabled = conf_is_ht(conf); |
587 | 605 | ||
588 | if (ctx->ht.enabled) { | 606 | if (ctx->ht.enabled) { |
589 | if (conf_is_ht40_minus(conf)) { | 607 | /* if HT40 is used, it should not change |
590 | ctx->ht.extension_chan_offset = | 608 | * after associated except channel switch */ |
591 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | 609 | if (iwl_is_associated_ctx(ctx) && |
592 | ctx->ht.is_40mhz = true; | 610 | !ctx->ht.is_40mhz) |
593 | } else if (conf_is_ht40_plus(conf)) { | 611 | iwlagn_config_ht40(conf, ctx); |
594 | ctx->ht.extension_chan_offset = | ||
595 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
596 | ctx->ht.is_40mhz = true; | ||
597 | } else { | ||
598 | ctx->ht.extension_chan_offset = | ||
599 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
600 | ctx->ht.is_40mhz = false; | ||
601 | } | ||
602 | } else | 612 | } else |
603 | ctx->ht.is_40mhz = false; | 613 | ctx->ht.is_40mhz = false; |
604 | 614 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index ed6283623932..4b2aa1da0953 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c | |||
@@ -1268,9 +1268,6 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, | |||
1268 | 1268 | ||
1269 | switch (keyconf->cipher) { | 1269 | switch (keyconf->cipher) { |
1270 | case WLAN_CIPHER_SUITE_TKIP: | 1270 | case WLAN_CIPHER_SUITE_TKIP: |
1271 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
1272 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
1273 | |||
1274 | if (sta) | 1271 | if (sta) |
1275 | addr = sta->addr; | 1272 | addr = sta->addr; |
1276 | else /* station mode case only */ | 1273 | else /* station mode case only */ |
@@ -1283,8 +1280,6 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, | |||
1283 | seq.tkip.iv32, p1k, CMD_SYNC); | 1280 | seq.tkip.iv32, p1k, CMD_SYNC); |
1284 | break; | 1281 | break; |
1285 | case WLAN_CIPHER_SUITE_CCMP: | 1282 | case WLAN_CIPHER_SUITE_CCMP: |
1286 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
1287 | /* fall through */ | ||
1288 | case WLAN_CIPHER_SUITE_WEP40: | 1283 | case WLAN_CIPHER_SUITE_WEP40: |
1289 | case WLAN_CIPHER_SUITE_WEP104: | 1284 | case WLAN_CIPHER_SUITE_WEP104: |
1290 | ret = iwlagn_send_sta_key(priv, keyconf, sta_id, | 1285 | ret = iwlagn_send_sta_key(priv, keyconf, sta_id, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ccba69b7f8a7..bacc06c95e7a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -2316,6 +2316,17 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2316 | return -EOPNOTSUPP; | 2316 | return -EOPNOTSUPP; |
2317 | } | 2317 | } |
2318 | 2318 | ||
2319 | switch (key->cipher) { | ||
2320 | case WLAN_CIPHER_SUITE_TKIP: | ||
2321 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
2322 | /* fall through */ | ||
2323 | case WLAN_CIPHER_SUITE_CCMP: | ||
2324 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
2325 | break; | ||
2326 | default: | ||
2327 | break; | ||
2328 | } | ||
2329 | |||
2319 | /* | 2330 | /* |
2320 | * We could program these keys into the hardware as well, but we | 2331 | * We could program these keys into the hardware as well, but we |
2321 | * don't expect much multicast traffic in IBSS and having keys | 2332 | * don't expect much multicast traffic in IBSS and having keys |
@@ -2599,21 +2610,9 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
2599 | 2610 | ||
2600 | /* Configure HT40 channels */ | 2611 | /* Configure HT40 channels */ |
2601 | ctx->ht.enabled = conf_is_ht(conf); | 2612 | ctx->ht.enabled = conf_is_ht(conf); |
2602 | if (ctx->ht.enabled) { | 2613 | if (ctx->ht.enabled) |
2603 | if (conf_is_ht40_minus(conf)) { | 2614 | iwlagn_config_ht40(conf, ctx); |
2604 | ctx->ht.extension_chan_offset = | 2615 | else |
2605 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
2606 | ctx->ht.is_40mhz = true; | ||
2607 | } else if (conf_is_ht40_plus(conf)) { | ||
2608 | ctx->ht.extension_chan_offset = | ||
2609 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
2610 | ctx->ht.is_40mhz = true; | ||
2611 | } else { | ||
2612 | ctx->ht.extension_chan_offset = | ||
2613 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
2614 | ctx->ht.is_40mhz = false; | ||
2615 | } | ||
2616 | } else | ||
2617 | ctx->ht.is_40mhz = false; | 2616 | ctx->ht.is_40mhz = false; |
2618 | 2617 | ||
2619 | if ((le16_to_cpu(ctx->staging.channel) != ch)) | 2618 | if ((le16_to_cpu(ctx->staging.channel) != ch)) |
@@ -3499,9 +3498,10 @@ MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); | |||
3499 | module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); | 3498 | module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); |
3500 | MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); | 3499 | MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); |
3501 | 3500 | ||
3502 | module_param_named(wd_disable, iwlagn_mod_params.wd_disable, bool, S_IRUGO); | 3501 | module_param_named(wd_disable, iwlagn_mod_params.wd_disable, int, S_IRUGO); |
3503 | MODULE_PARM_DESC(wd_disable, | 3502 | MODULE_PARM_DESC(wd_disable, |
3504 | "Disable stuck queue watchdog timer (default: 0 [enabled])"); | 3503 | "Disable stuck queue watchdog timer 0=system default, " |
3504 | "1=disable, 2=enable (default: 0)"); | ||
3505 | 3505 | ||
3506 | /* | 3506 | /* |
3507 | * set bt_coex_active to true, uCode will do kill/defer | 3507 | * set bt_coex_active to true, uCode will do kill/defer |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 5b936ec1a541..3856abaea507 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -86,6 +86,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
86 | struct ieee80211_vif *vif, | 86 | struct ieee80211_vif *vif, |
87 | struct ieee80211_bss_conf *bss_conf, | 87 | struct ieee80211_bss_conf *bss_conf, |
88 | u32 changes); | 88 | u32 changes); |
89 | void iwlagn_config_ht40(struct ieee80211_conf *conf, | ||
90 | struct iwl_rxon_context *ctx); | ||
89 | 91 | ||
90 | /* uCode */ | 92 | /* uCode */ |
91 | int iwlagn_rx_calib_result(struct iwl_priv *priv, | 93 | int iwlagn_rx_calib_result(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 001fdf140abb..fcf54160e4ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1810,11 +1810,23 @@ void iwl_setup_watchdog(struct iwl_priv *priv) | |||
1810 | { | 1810 | { |
1811 | unsigned int timeout = priv->cfg->base_params->wd_timeout; | 1811 | unsigned int timeout = priv->cfg->base_params->wd_timeout; |
1812 | 1812 | ||
1813 | if (timeout && !iwlagn_mod_params.wd_disable) | 1813 | if (!iwlagn_mod_params.wd_disable) { |
1814 | mod_timer(&priv->watchdog, | 1814 | /* use system default */ |
1815 | jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); | 1815 | if (timeout && !priv->cfg->base_params->wd_disable) |
1816 | else | 1816 | mod_timer(&priv->watchdog, |
1817 | del_timer(&priv->watchdog); | 1817 | jiffies + |
1818 | msecs_to_jiffies(IWL_WD_TICK(timeout))); | ||
1819 | else | ||
1820 | del_timer(&priv->watchdog); | ||
1821 | } else { | ||
1822 | /* module parameter overwrite default configuration */ | ||
1823 | if (timeout && iwlagn_mod_params.wd_disable == 2) | ||
1824 | mod_timer(&priv->watchdog, | ||
1825 | jiffies + | ||
1826 | msecs_to_jiffies(IWL_WD_TICK(timeout))); | ||
1827 | else | ||
1828 | del_timer(&priv->watchdog); | ||
1829 | } | ||
1818 | } | 1830 | } |
1819 | 1831 | ||
1820 | /** | 1832 | /** |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 137da3380704..f2fc288f3dd3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -113,6 +113,7 @@ struct iwl_lib_ops { | |||
113 | * @shadow_reg_enable: HW shadhow register bit | 113 | * @shadow_reg_enable: HW shadhow register bit |
114 | * @no_idle_support: do not support idle mode | 114 | * @no_idle_support: do not support idle mode |
115 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up | 115 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up |
116 | * wd_disable: disable watchdog timer | ||
116 | */ | 117 | */ |
117 | struct iwl_base_params { | 118 | struct iwl_base_params { |
118 | int eeprom_size; | 119 | int eeprom_size; |
@@ -134,6 +135,7 @@ struct iwl_base_params { | |||
134 | const bool shadow_reg_enable; | 135 | const bool shadow_reg_enable; |
135 | const bool no_idle_support; | 136 | const bool no_idle_support; |
136 | const bool hd_v2; | 137 | const bool hd_v2; |
138 | const bool wd_disable; | ||
137 | }; | 139 | }; |
138 | /* | 140 | /* |
139 | * @advanced_bt_coexist: support advanced bt coexist | 141 | * @advanced_bt_coexist: support advanced bt coexist |
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 1f7a93c67c45..14eaf37ce3b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h | |||
@@ -120,7 +120,7 @@ extern struct iwl_mod_params iwlagn_mod_params; | |||
120 | * @restart_fw: restart firmware, default = 1 | 120 | * @restart_fw: restart firmware, default = 1 |
121 | * @plcp_check: enable plcp health check, default = true | 121 | * @plcp_check: enable plcp health check, default = true |
122 | * @ack_check: disable ack health check, default = false | 122 | * @ack_check: disable ack health check, default = false |
123 | * @wd_disable: enable stuck queue check, default = false | 123 | * @wd_disable: enable stuck queue check, default = 0 |
124 | * @bt_coex_active: enable bt coex, default = true | 124 | * @bt_coex_active: enable bt coex, default = true |
125 | * @led_mode: system default, default = 0 | 125 | * @led_mode: system default, default = 0 |
126 | * @no_sleep_autoadjust: disable autoadjust, default = true | 126 | * @no_sleep_autoadjust: disable autoadjust, default = true |
@@ -141,7 +141,7 @@ struct iwl_mod_params { | |||
141 | int restart_fw; | 141 | int restart_fw; |
142 | bool plcp_check; | 142 | bool plcp_check; |
143 | bool ack_check; | 143 | bool ack_check; |
144 | bool wd_disable; | 144 | int wd_disable; |
145 | bool bt_coex_active; | 145 | bool bt_coex_active; |
146 | int led_mode; | 146 | int led_mode; |
147 | bool no_sleep_autoadjust; | 147 | bool no_sleep_autoadjust; |
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 1ae270eed51a..15e332d08c8d 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
@@ -1668,7 +1668,7 @@ static int __init netback_init(void) | |||
1668 | "netback/%u", group); | 1668 | "netback/%u", group); |
1669 | 1669 | ||
1670 | if (IS_ERR(netbk->task)) { | 1670 | if (IS_ERR(netbk->task)) { |
1671 | printk(KERN_ALERT "kthread_run() fails at netback\n"); | 1671 | printk(KERN_ALERT "kthread_create() fails at netback\n"); |
1672 | del_timer(&netbk->net_timer); | 1672 | del_timer(&netbk->net_timer); |
1673 | rc = PTR_ERR(netbk->task); | 1673 | rc = PTR_ERR(netbk->task); |
1674 | goto failed_init; | 1674 | goto failed_init; |
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 19c0115092dd..0f0cfa3bca30 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c | |||
@@ -26,11 +26,6 @@ | |||
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | 28 | ||
29 | /* For archs that don't support NO_IRQ (such as x86), provide a dummy value */ | ||
30 | #ifndef NO_IRQ | ||
31 | #define NO_IRQ 0 | ||
32 | #endif | ||
33 | |||
34 | /** | 29 | /** |
35 | * irq_of_parse_and_map - Parse and map an interrupt into linux virq space | 30 | * irq_of_parse_and_map - Parse and map an interrupt into linux virq space |
36 | * @device: Device node of the device whose interrupt is to be mapped | 31 | * @device: Device node of the device whose interrupt is to be mapped |
@@ -44,7 +39,7 @@ unsigned int irq_of_parse_and_map(struct device_node *dev, int index) | |||
44 | struct of_irq oirq; | 39 | struct of_irq oirq; |
45 | 40 | ||
46 | if (of_irq_map_one(dev, index, &oirq)) | 41 | if (of_irq_map_one(dev, index, &oirq)) |
47 | return NO_IRQ; | 42 | return 0; |
48 | 43 | ||
49 | return irq_create_of_mapping(oirq.controller, oirq.specifier, | 44 | return irq_create_of_mapping(oirq.controller, oirq.specifier, |
50 | oirq.size); | 45 | oirq.size); |
@@ -345,7 +340,7 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) | |||
345 | 340 | ||
346 | /* Only dereference the resource if both the | 341 | /* Only dereference the resource if both the |
347 | * resource and the irq are valid. */ | 342 | * resource and the irq are valid. */ |
348 | if (r && irq != NO_IRQ) { | 343 | if (r && irq) { |
349 | r->start = r->end = irq; | 344 | r->start = r->end = irq; |
350 | r->flags = IORESOURCE_IRQ; | 345 | r->flags = IORESOURCE_IRQ; |
351 | r->name = dev->full_name; | 346 | r->name = dev->full_name; |
@@ -363,7 +358,7 @@ int of_irq_count(struct device_node *dev) | |||
363 | { | 358 | { |
364 | int nr = 0; | 359 | int nr = 0; |
365 | 360 | ||
366 | while (of_irq_to_resource(dev, nr, NULL) != NO_IRQ) | 361 | while (of_irq_to_resource(dev, nr, NULL)) |
367 | nr++; | 362 | nr++; |
368 | 363 | ||
369 | return nr; | 364 | return nr; |
@@ -383,7 +378,7 @@ int of_irq_to_resource_table(struct device_node *dev, struct resource *res, | |||
383 | int i; | 378 | int i; |
384 | 379 | ||
385 | for (i = 0; i < nr_irqs; i++, res++) | 380 | for (i = 0; i < nr_irqs; i++, res++) |
386 | if (of_irq_to_resource(dev, i, res) == NO_IRQ) | 381 | if (!of_irq_to_resource(dev, i, res)) |
387 | break; | 382 | break; |
388 | 383 | ||
389 | return i; | 384 | return i; |
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c index dccd8636095c..f8c752e408a6 100644 --- a/drivers/oprofile/oprof.c +++ b/drivers/oprofile/oprof.c | |||
@@ -239,26 +239,45 @@ int oprofile_set_ulong(unsigned long *addr, unsigned long val) | |||
239 | return err; | 239 | return err; |
240 | } | 240 | } |
241 | 241 | ||
242 | static int timer_mode; | ||
243 | |||
242 | static int __init oprofile_init(void) | 244 | static int __init oprofile_init(void) |
243 | { | 245 | { |
244 | int err; | 246 | int err; |
245 | 247 | ||
248 | /* always init architecture to setup backtrace support */ | ||
246 | err = oprofile_arch_init(&oprofile_ops); | 249 | err = oprofile_arch_init(&oprofile_ops); |
247 | if (err < 0 || timer) { | 250 | |
248 | printk(KERN_INFO "oprofile: using timer interrupt.\n"); | 251 | timer_mode = err || timer; /* fall back to timer mode on errors */ |
252 | if (timer_mode) { | ||
253 | if (!err) | ||
254 | oprofile_arch_exit(); | ||
249 | err = oprofile_timer_init(&oprofile_ops); | 255 | err = oprofile_timer_init(&oprofile_ops); |
250 | if (err) | 256 | if (err) |
251 | return err; | 257 | return err; |
252 | } | 258 | } |
253 | return oprofilefs_register(); | 259 | |
260 | err = oprofilefs_register(); | ||
261 | if (!err) | ||
262 | return 0; | ||
263 | |||
264 | /* failed */ | ||
265 | if (timer_mode) | ||
266 | oprofile_timer_exit(); | ||
267 | else | ||
268 | oprofile_arch_exit(); | ||
269 | |||
270 | return err; | ||
254 | } | 271 | } |
255 | 272 | ||
256 | 273 | ||
257 | static void __exit oprofile_exit(void) | 274 | static void __exit oprofile_exit(void) |
258 | { | 275 | { |
259 | oprofile_timer_exit(); | ||
260 | oprofilefs_unregister(); | 276 | oprofilefs_unregister(); |
261 | oprofile_arch_exit(); | 277 | if (timer_mode) |
278 | oprofile_timer_exit(); | ||
279 | else | ||
280 | oprofile_arch_exit(); | ||
262 | } | 281 | } |
263 | 282 | ||
264 | 283 | ||
diff --git a/drivers/oprofile/timer_int.c b/drivers/oprofile/timer_int.c index 3ef44624f510..878fba126582 100644 --- a/drivers/oprofile/timer_int.c +++ b/drivers/oprofile/timer_int.c | |||
@@ -110,6 +110,7 @@ int oprofile_timer_init(struct oprofile_operations *ops) | |||
110 | ops->start = oprofile_hrtimer_start; | 110 | ops->start = oprofile_hrtimer_start; |
111 | ops->stop = oprofile_hrtimer_stop; | 111 | ops->stop = oprofile_hrtimer_stop; |
112 | ops->cpu_type = "timer"; | 112 | ops->cpu_type = "timer"; |
113 | printk(KERN_INFO "oprofile: using timer interrupt.\n"); | ||
113 | return 0; | 114 | return 0; |
114 | } | 115 | } |
115 | 116 | ||
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 13ef8c37471d..dcdc1f4a4624 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -121,6 +121,7 @@ struct toshiba_acpi_dev { | |||
121 | int illumination_supported:1; | 121 | int illumination_supported:1; |
122 | int video_supported:1; | 122 | int video_supported:1; |
123 | int fan_supported:1; | 123 | int fan_supported:1; |
124 | int system_event_supported:1; | ||
124 | 125 | ||
125 | struct mutex mutex; | 126 | struct mutex mutex; |
126 | }; | 127 | }; |
@@ -724,7 +725,7 @@ static int keys_proc_show(struct seq_file *m, void *v) | |||
724 | u32 hci_result; | 725 | u32 hci_result; |
725 | u32 value; | 726 | u32 value; |
726 | 727 | ||
727 | if (!dev->key_event_valid) { | 728 | if (!dev->key_event_valid && dev->system_event_supported) { |
728 | hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); | 729 | hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); |
729 | if (hci_result == HCI_SUCCESS) { | 730 | if (hci_result == HCI_SUCCESS) { |
730 | dev->key_event_valid = 1; | 731 | dev->key_event_valid = 1; |
@@ -964,6 +965,8 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
964 | 965 | ||
965 | /* enable event fifo */ | 966 | /* enable event fifo */ |
966 | hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); | 967 | hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); |
968 | if (hci_result == HCI_SUCCESS) | ||
969 | dev->system_event_supported = 1; | ||
967 | 970 | ||
968 | props.type = BACKLIGHT_PLATFORM; | 971 | props.type = BACKLIGHT_PLATFORM; |
969 | props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; | 972 | props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; |
@@ -1032,12 +1035,15 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) | |||
1032 | { | 1035 | { |
1033 | struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); | 1036 | struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); |
1034 | u32 hci_result, value; | 1037 | u32 hci_result, value; |
1038 | int retries = 3; | ||
1035 | 1039 | ||
1036 | if (event != 0x80) | 1040 | if (!dev->system_event_supported || event != 0x80) |
1037 | return; | 1041 | return; |
1042 | |||
1038 | do { | 1043 | do { |
1039 | hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); | 1044 | hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); |
1040 | if (hci_result == HCI_SUCCESS) { | 1045 | switch (hci_result) { |
1046 | case HCI_SUCCESS: | ||
1041 | if (value == 0x100) | 1047 | if (value == 0x100) |
1042 | continue; | 1048 | continue; |
1043 | /* act on key press; ignore key release */ | 1049 | /* act on key press; ignore key release */ |
@@ -1049,14 +1055,19 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) | |||
1049 | pr_info("Unknown key %x\n", | 1055 | pr_info("Unknown key %x\n", |
1050 | value); | 1056 | value); |
1051 | } | 1057 | } |
1052 | } else if (hci_result == HCI_NOT_SUPPORTED) { | 1058 | break; |
1059 | case HCI_NOT_SUPPORTED: | ||
1053 | /* This is a workaround for an unresolved issue on | 1060 | /* This is a workaround for an unresolved issue on |
1054 | * some machines where system events sporadically | 1061 | * some machines where system events sporadically |
1055 | * become disabled. */ | 1062 | * become disabled. */ |
1056 | hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); | 1063 | hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); |
1057 | pr_notice("Re-enabled hotkeys\n"); | 1064 | pr_notice("Re-enabled hotkeys\n"); |
1065 | /* fall through */ | ||
1066 | default: | ||
1067 | retries--; | ||
1068 | break; | ||
1058 | } | 1069 | } |
1059 | } while (hci_result != HCI_EMPTY); | 1070 | } while (retries && hci_result != HCI_EMPTY); |
1060 | } | 1071 | } |
1061 | 1072 | ||
1062 | 1073 | ||
diff --git a/drivers/power/intel_mid_battery.c b/drivers/power/intel_mid_battery.c index cffcb7c00b00..01fa671ec97f 100644 --- a/drivers/power/intel_mid_battery.c +++ b/drivers/power/intel_mid_battery.c | |||
@@ -61,7 +61,8 @@ MODULE_PARM_DESC(debug, "Flag to enable PMIC Battery debug messages."); | |||
61 | #define PMIC_BATT_CHR_SBATDET_MASK (1 << 5) | 61 | #define PMIC_BATT_CHR_SBATDET_MASK (1 << 5) |
62 | #define PMIC_BATT_CHR_SDCLMT_MASK (1 << 6) | 62 | #define PMIC_BATT_CHR_SDCLMT_MASK (1 << 6) |
63 | #define PMIC_BATT_CHR_SUSBOVP_MASK (1 << 7) | 63 | #define PMIC_BATT_CHR_SUSBOVP_MASK (1 << 7) |
64 | #define PMIC_BATT_CHR_EXCPT_MASK 0xC6 | 64 | #define PMIC_BATT_CHR_EXCPT_MASK 0x86 |
65 | |||
65 | #define PMIC_BATT_ADC_ACCCHRG_MASK (1 << 31) | 66 | #define PMIC_BATT_ADC_ACCCHRG_MASK (1 << 31) |
66 | #define PMIC_BATT_ADC_ACCCHRGVAL_MASK 0x7FFFFFFF | 67 | #define PMIC_BATT_ADC_ACCCHRGVAL_MASK 0x7FFFFFFF |
67 | 68 | ||
@@ -304,11 +305,6 @@ static void pmic_battery_read_status(struct pmic_power_module_info *pbi) | |||
304 | pbi->batt_status = POWER_SUPPLY_STATUS_NOT_CHARGING; | 305 | pbi->batt_status = POWER_SUPPLY_STATUS_NOT_CHARGING; |
305 | pmic_battery_log_event(BATT_EVENT_BATOVP_EXCPT); | 306 | pmic_battery_log_event(BATT_EVENT_BATOVP_EXCPT); |
306 | batt_exception = 1; | 307 | batt_exception = 1; |
307 | } else if (r8 & PMIC_BATT_CHR_SDCLMT_MASK) { | ||
308 | pbi->batt_health = POWER_SUPPLY_HEALTH_OVERVOLTAGE; | ||
309 | pbi->batt_status = POWER_SUPPLY_STATUS_NOT_CHARGING; | ||
310 | pmic_battery_log_event(BATT_EVENT_DCLMT_EXCPT); | ||
311 | batt_exception = 1; | ||
312 | } else if (r8 & PMIC_BATT_CHR_STEMP_MASK) { | 308 | } else if (r8 & PMIC_BATT_CHR_STEMP_MASK) { |
313 | pbi->batt_health = POWER_SUPPLY_HEALTH_OVERHEAT; | 309 | pbi->batt_health = POWER_SUPPLY_HEALTH_OVERHEAT; |
314 | pbi->batt_status = POWER_SUPPLY_STATUS_NOT_CHARGING; | 310 | pbi->batt_status = POWER_SUPPLY_STATUS_NOT_CHARGING; |
@@ -316,6 +312,10 @@ static void pmic_battery_read_status(struct pmic_power_module_info *pbi) | |||
316 | batt_exception = 1; | 312 | batt_exception = 1; |
317 | } else { | 313 | } else { |
318 | pbi->batt_health = POWER_SUPPLY_HEALTH_GOOD; | 314 | pbi->batt_health = POWER_SUPPLY_HEALTH_GOOD; |
315 | if (r8 & PMIC_BATT_CHR_SDCLMT_MASK) { | ||
316 | /* PMIC will change charging current automatically */ | ||
317 | pmic_battery_log_event(BATT_EVENT_DCLMT_EXCPT); | ||
318 | } | ||
319 | } | 319 | } |
320 | } | 320 | } |
321 | 321 | ||
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index cf3f9997546d..10451a15e828 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c | |||
@@ -101,7 +101,9 @@ static s32 scaled_ppm_to_ppb(long ppm) | |||
101 | 101 | ||
102 | static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp) | 102 | static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp) |
103 | { | 103 | { |
104 | return 1; /* always round timer functions to one nanosecond */ | 104 | tp->tv_sec = 0; |
105 | tp->tv_nsec = 1; | ||
106 | return 0; | ||
105 | } | 107 | } |
106 | 108 | ||
107 | static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp) | 109 | static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp) |
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 5225930a10cd..691b1ab1a3d0 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c | |||
@@ -851,14 +851,12 @@ static int tsi721_doorbell_init(struct tsi721_device *priv) | |||
851 | INIT_WORK(&priv->idb_work, tsi721_db_dpc); | 851 | INIT_WORK(&priv->idb_work, tsi721_db_dpc); |
852 | 852 | ||
853 | /* Allocate buffer for inbound doorbells queue */ | 853 | /* Allocate buffer for inbound doorbells queue */ |
854 | priv->idb_base = dma_alloc_coherent(&priv->pdev->dev, | 854 | priv->idb_base = dma_zalloc_coherent(&priv->pdev->dev, |
855 | IDB_QSIZE * TSI721_IDB_ENTRY_SIZE, | 855 | IDB_QSIZE * TSI721_IDB_ENTRY_SIZE, |
856 | &priv->idb_dma, GFP_KERNEL); | 856 | &priv->idb_dma, GFP_KERNEL); |
857 | if (!priv->idb_base) | 857 | if (!priv->idb_base) |
858 | return -ENOMEM; | 858 | return -ENOMEM; |
859 | 859 | ||
860 | memset(priv->idb_base, 0, IDB_QSIZE * TSI721_IDB_ENTRY_SIZE); | ||
861 | |||
862 | dev_dbg(&priv->pdev->dev, "Allocated IDB buffer @ %p (phys = %llx)\n", | 860 | dev_dbg(&priv->pdev->dev, "Allocated IDB buffer @ %p (phys = %llx)\n", |
863 | priv->idb_base, (unsigned long long)priv->idb_dma); | 861 | priv->idb_base, (unsigned long long)priv->idb_dma); |
864 | 862 | ||
@@ -904,7 +902,7 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) | |||
904 | */ | 902 | */ |
905 | 903 | ||
906 | /* Allocate space for DMA descriptors */ | 904 | /* Allocate space for DMA descriptors */ |
907 | bd_ptr = dma_alloc_coherent(&priv->pdev->dev, | 905 | bd_ptr = dma_zalloc_coherent(&priv->pdev->dev, |
908 | bd_num * sizeof(struct tsi721_dma_desc), | 906 | bd_num * sizeof(struct tsi721_dma_desc), |
909 | &bd_phys, GFP_KERNEL); | 907 | &bd_phys, GFP_KERNEL); |
910 | if (!bd_ptr) | 908 | if (!bd_ptr) |
@@ -913,8 +911,6 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) | |||
913 | priv->bdma[chnum].bd_phys = bd_phys; | 911 | priv->bdma[chnum].bd_phys = bd_phys; |
914 | priv->bdma[chnum].bd_base = bd_ptr; | 912 | priv->bdma[chnum].bd_base = bd_ptr; |
915 | 913 | ||
916 | memset(bd_ptr, 0, bd_num * sizeof(struct tsi721_dma_desc)); | ||
917 | |||
918 | dev_dbg(&priv->pdev->dev, "DMA descriptors @ %p (phys = %llx)\n", | 914 | dev_dbg(&priv->pdev->dev, "DMA descriptors @ %p (phys = %llx)\n", |
919 | bd_ptr, (unsigned long long)bd_phys); | 915 | bd_ptr, (unsigned long long)bd_phys); |
920 | 916 | ||
@@ -922,7 +918,7 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) | |||
922 | sts_size = (bd_num >= TSI721_DMA_MINSTSSZ) ? | 918 | sts_size = (bd_num >= TSI721_DMA_MINSTSSZ) ? |
923 | bd_num : TSI721_DMA_MINSTSSZ; | 919 | bd_num : TSI721_DMA_MINSTSSZ; |
924 | sts_size = roundup_pow_of_two(sts_size); | 920 | sts_size = roundup_pow_of_two(sts_size); |
925 | sts_ptr = dma_alloc_coherent(&priv->pdev->dev, | 921 | sts_ptr = dma_zalloc_coherent(&priv->pdev->dev, |
926 | sts_size * sizeof(struct tsi721_dma_sts), | 922 | sts_size * sizeof(struct tsi721_dma_sts), |
927 | &sts_phys, GFP_KERNEL); | 923 | &sts_phys, GFP_KERNEL); |
928 | if (!sts_ptr) { | 924 | if (!sts_ptr) { |
@@ -938,8 +934,6 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) | |||
938 | priv->bdma[chnum].sts_base = sts_ptr; | 934 | priv->bdma[chnum].sts_base = sts_ptr; |
939 | priv->bdma[chnum].sts_size = sts_size; | 935 | priv->bdma[chnum].sts_size = sts_size; |
940 | 936 | ||
941 | memset(sts_ptr, 0, sts_size); | ||
942 | |||
943 | dev_dbg(&priv->pdev->dev, | 937 | dev_dbg(&priv->pdev->dev, |
944 | "desc status FIFO @ %p (phys = %llx) size=0x%x\n", | 938 | "desc status FIFO @ %p (phys = %llx) size=0x%x\n", |
945 | sts_ptr, (unsigned long long)sts_phys, sts_size); | 939 | sts_ptr, (unsigned long long)sts_phys, sts_size); |
@@ -1400,7 +1394,7 @@ static int tsi721_open_outb_mbox(struct rio_mport *mport, void *dev_id, | |||
1400 | 1394 | ||
1401 | /* Outbound message descriptor status FIFO allocation */ | 1395 | /* Outbound message descriptor status FIFO allocation */ |
1402 | priv->omsg_ring[mbox].sts_size = roundup_pow_of_two(entries + 1); | 1396 | priv->omsg_ring[mbox].sts_size = roundup_pow_of_two(entries + 1); |
1403 | priv->omsg_ring[mbox].sts_base = dma_alloc_coherent(&priv->pdev->dev, | 1397 | priv->omsg_ring[mbox].sts_base = dma_zalloc_coherent(&priv->pdev->dev, |
1404 | priv->omsg_ring[mbox].sts_size * | 1398 | priv->omsg_ring[mbox].sts_size * |
1405 | sizeof(struct tsi721_dma_sts), | 1399 | sizeof(struct tsi721_dma_sts), |
1406 | &priv->omsg_ring[mbox].sts_phys, GFP_KERNEL); | 1400 | &priv->omsg_ring[mbox].sts_phys, GFP_KERNEL); |
@@ -1412,9 +1406,6 @@ static int tsi721_open_outb_mbox(struct rio_mport *mport, void *dev_id, | |||
1412 | goto out_desc; | 1406 | goto out_desc; |
1413 | } | 1407 | } |
1414 | 1408 | ||
1415 | memset(priv->omsg_ring[mbox].sts_base, 0, | ||
1416 | entries * sizeof(struct tsi721_dma_sts)); | ||
1417 | |||
1418 | /* | 1409 | /* |
1419 | * Configure Outbound Messaging Engine | 1410 | * Configure Outbound Messaging Engine |
1420 | */ | 1411 | */ |
@@ -2116,8 +2107,8 @@ static int __devinit tsi721_setup_mport(struct tsi721_device *priv) | |||
2116 | INIT_LIST_HEAD(&mport->dbells); | 2107 | INIT_LIST_HEAD(&mport->dbells); |
2117 | 2108 | ||
2118 | rio_init_dbell_res(&mport->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); | 2109 | rio_init_dbell_res(&mport->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); |
2119 | rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 0); | 2110 | rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 3); |
2120 | rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0); | 2111 | rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 3); |
2121 | strcpy(mport->name, "Tsi721 mport"); | 2112 | strcpy(mport->name, "Tsi721 mport"); |
2122 | 2113 | ||
2123 | /* Hook up interrupt handler */ | 2114 | /* Hook up interrupt handler */ |
@@ -2163,7 +2154,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, | |||
2163 | const struct pci_device_id *id) | 2154 | const struct pci_device_id *id) |
2164 | { | 2155 | { |
2165 | struct tsi721_device *priv; | 2156 | struct tsi721_device *priv; |
2166 | int i; | 2157 | int i, cap; |
2167 | int err; | 2158 | int err; |
2168 | u32 regval; | 2159 | u32 regval; |
2169 | 2160 | ||
@@ -2271,10 +2262,20 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, | |||
2271 | dev_info(&pdev->dev, "Unable to set consistent DMA mask\n"); | 2262 | dev_info(&pdev->dev, "Unable to set consistent DMA mask\n"); |
2272 | } | 2263 | } |
2273 | 2264 | ||
2274 | /* Clear "no snoop" and "relaxed ordering" bits. */ | 2265 | cap = pci_pcie_cap(pdev); |
2275 | pci_read_config_dword(pdev, 0x40 + PCI_EXP_DEVCTL, ®val); | 2266 | BUG_ON(cap == 0); |
2276 | regval &= ~(PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN); | 2267 | |
2277 | pci_write_config_dword(pdev, 0x40 + PCI_EXP_DEVCTL, regval); | 2268 | /* Clear "no snoop" and "relaxed ordering" bits, use default MRRS. */ |
2269 | pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL, ®val); | ||
2270 | regval &= ~(PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN | | ||
2271 | PCI_EXP_DEVCTL_NOSNOOP_EN); | ||
2272 | regval |= 0x2 << MAX_READ_REQUEST_SZ_SHIFT; | ||
2273 | pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL, regval); | ||
2274 | |||
2275 | /* Adjust PCIe completion timeout. */ | ||
2276 | pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL2, ®val); | ||
2277 | regval &= ~(0x0f); | ||
2278 | pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL2, regval | 0x2); | ||
2278 | 2279 | ||
2279 | /* | 2280 | /* |
2280 | * FIXUP: correct offsets of MSI-X tables in the MSI-X Capability Block | 2281 | * FIXUP: correct offsets of MSI-X tables in the MSI-X Capability Block |
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h index 58be4deb1402..822e54c394d5 100644 --- a/drivers/rapidio/devices/tsi721.h +++ b/drivers/rapidio/devices/tsi721.h | |||
@@ -72,6 +72,8 @@ | |||
72 | #define TSI721_MSIXPBA_OFFSET 0x2a000 | 72 | #define TSI721_MSIXPBA_OFFSET 0x2a000 |
73 | #define TSI721_PCIECFG_EPCTL 0x400 | 73 | #define TSI721_PCIECFG_EPCTL 0x400 |
74 | 74 | ||
75 | #define MAX_READ_REQUEST_SZ_SHIFT 12 | ||
76 | |||
75 | /* | 77 | /* |
76 | * Event Management Registers | 78 | * Event Management Registers |
77 | */ | 79 | */ |
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index e8326f26fa2f..dc4c2748bbc3 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -63,7 +63,7 @@ static int rtc_suspend(struct device *dev, pm_message_t mesg) | |||
63 | */ | 63 | */ |
64 | delta = timespec_sub(old_system, old_rtc); | 64 | delta = timespec_sub(old_system, old_rtc); |
65 | delta_delta = timespec_sub(delta, old_delta); | 65 | delta_delta = timespec_sub(delta, old_delta); |
66 | if (abs(delta_delta.tv_sec) >= 2) { | 66 | if (delta_delta.tv_sec < -2 || delta_delta.tv_sec >= 2) { |
67 | /* | 67 | /* |
68 | * if delta_delta is too large, assume time correction | 68 | * if delta_delta is too large, assume time correction |
69 | * has occured and set old_delta to the current delta. | 69 | * has occured and set old_delta to the current delta. |
@@ -97,9 +97,8 @@ static int rtc_resume(struct device *dev) | |||
97 | rtc_tm_to_time(&tm, &new_rtc.tv_sec); | 97 | rtc_tm_to_time(&tm, &new_rtc.tv_sec); |
98 | new_rtc.tv_nsec = 0; | 98 | new_rtc.tv_nsec = 0; |
99 | 99 | ||
100 | if (new_rtc.tv_sec <= old_rtc.tv_sec) { | 100 | if (new_rtc.tv_sec < old_rtc.tv_sec) { |
101 | if (new_rtc.tv_sec < old_rtc.tv_sec) | 101 | pr_debug("%s: time travel!\n", dev_name(&rtc->dev)); |
102 | pr_debug("%s: time travel!\n", dev_name(&rtc->dev)); | ||
103 | return 0; | 102 | return 0; |
104 | } | 103 | } |
105 | 104 | ||
@@ -116,7 +115,8 @@ static int rtc_resume(struct device *dev) | |||
116 | sleep_time = timespec_sub(sleep_time, | 115 | sleep_time = timespec_sub(sleep_time, |
117 | timespec_sub(new_system, old_system)); | 116 | timespec_sub(new_system, old_system)); |
118 | 117 | ||
119 | timekeeping_inject_sleeptime(&sleep_time); | 118 | if (sleep_time.tv_sec >= 0) |
119 | timekeeping_inject_sleeptime(&sleep_time); | ||
120 | return 0; | 120 | return 0; |
121 | } | 121 | } |
122 | 122 | ||
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 8e286259a007..fa4d9f324189 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -319,6 +319,20 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
319 | } | 319 | } |
320 | EXPORT_SYMBOL_GPL(rtc_read_alarm); | 320 | EXPORT_SYMBOL_GPL(rtc_read_alarm); |
321 | 321 | ||
322 | static int ___rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | ||
323 | { | ||
324 | int err; | ||
325 | |||
326 | if (!rtc->ops) | ||
327 | err = -ENODEV; | ||
328 | else if (!rtc->ops->set_alarm) | ||
329 | err = -EINVAL; | ||
330 | else | ||
331 | err = rtc->ops->set_alarm(rtc->dev.parent, alarm); | ||
332 | |||
333 | return err; | ||
334 | } | ||
335 | |||
322 | static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | 336 | static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) |
323 | { | 337 | { |
324 | struct rtc_time tm; | 338 | struct rtc_time tm; |
@@ -342,14 +356,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
342 | * over right here, before we set the alarm. | 356 | * over right here, before we set the alarm. |
343 | */ | 357 | */ |
344 | 358 | ||
345 | if (!rtc->ops) | 359 | return ___rtc_set_alarm(rtc, alarm); |
346 | err = -ENODEV; | ||
347 | else if (!rtc->ops->set_alarm) | ||
348 | err = -EINVAL; | ||
349 | else | ||
350 | err = rtc->ops->set_alarm(rtc->dev.parent, alarm); | ||
351 | |||
352 | return err; | ||
353 | } | 360 | } |
354 | 361 | ||
355 | int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | 362 | int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) |
@@ -763,6 +770,20 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) | |||
763 | return 0; | 770 | return 0; |
764 | } | 771 | } |
765 | 772 | ||
773 | static void rtc_alarm_disable(struct rtc_device *rtc) | ||
774 | { | ||
775 | struct rtc_wkalrm alarm; | ||
776 | struct rtc_time tm; | ||
777 | |||
778 | __rtc_read_time(rtc, &tm); | ||
779 | |||
780 | alarm.time = rtc_ktime_to_tm(ktime_add(rtc_tm_to_ktime(tm), | ||
781 | ktime_set(300, 0))); | ||
782 | alarm.enabled = 0; | ||
783 | |||
784 | ___rtc_set_alarm(rtc, &alarm); | ||
785 | } | ||
786 | |||
766 | /** | 787 | /** |
767 | * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue | 788 | * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue |
768 | * @rtc rtc device | 789 | * @rtc rtc device |
@@ -784,8 +805,10 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer) | |||
784 | struct rtc_wkalrm alarm; | 805 | struct rtc_wkalrm alarm; |
785 | int err; | 806 | int err; |
786 | next = timerqueue_getnext(&rtc->timerqueue); | 807 | next = timerqueue_getnext(&rtc->timerqueue); |
787 | if (!next) | 808 | if (!next) { |
809 | rtc_alarm_disable(rtc); | ||
788 | return; | 810 | return; |
811 | } | ||
789 | alarm.time = rtc_ktime_to_tm(next->expires); | 812 | alarm.time = rtc_ktime_to_tm(next->expires); |
790 | alarm.enabled = 1; | 813 | alarm.enabled = 1; |
791 | err = __rtc_set_alarm(rtc, &alarm); | 814 | err = __rtc_set_alarm(rtc, &alarm); |
@@ -847,7 +870,8 @@ again: | |||
847 | err = __rtc_set_alarm(rtc, &alarm); | 870 | err = __rtc_set_alarm(rtc, &alarm); |
848 | if (err == -ETIME) | 871 | if (err == -ETIME) |
849 | goto again; | 872 | goto again; |
850 | } | 873 | } else |
874 | rtc_alarm_disable(rtc); | ||
851 | 875 | ||
852 | mutex_unlock(&rtc->ops_lock); | 876 | mutex_unlock(&rtc->ops_lock); |
853 | } | 877 | } |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 7639ab906f02..5b979d9cc332 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -202,7 +202,6 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
202 | void __iomem *base = s3c_rtc_base; | 202 | void __iomem *base = s3c_rtc_base; |
203 | int year = tm->tm_year - 100; | 203 | int year = tm->tm_year - 100; |
204 | 204 | ||
205 | clk_enable(rtc_clk); | ||
206 | pr_debug("set time %04d.%02d.%02d %02d:%02d:%02d\n", | 205 | pr_debug("set time %04d.%02d.%02d %02d:%02d:%02d\n", |
207 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 206 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
208 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 207 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
@@ -214,6 +213,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
214 | return -EINVAL; | 213 | return -EINVAL; |
215 | } | 214 | } |
216 | 215 | ||
216 | clk_enable(rtc_clk); | ||
217 | writeb(bin2bcd(tm->tm_sec), base + S3C2410_RTCSEC); | 217 | writeb(bin2bcd(tm->tm_sec), base + S3C2410_RTCSEC); |
218 | writeb(bin2bcd(tm->tm_min), base + S3C2410_RTCMIN); | 218 | writeb(bin2bcd(tm->tm_min), base + S3C2410_RTCMIN); |
219 | writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR); | 219 | writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR); |
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 75c3f1f8fd43..a84631a7391d 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -529,10 +529,7 @@ __s390_vary_chpid_on(struct subchannel_id schid, void *data) | |||
529 | int chsc_chp_vary(struct chp_id chpid, int on) | 529 | int chsc_chp_vary(struct chp_id chpid, int on) |
530 | { | 530 | { |
531 | struct channel_path *chp = chpid_to_chp(chpid); | 531 | struct channel_path *chp = chpid_to_chp(chpid); |
532 | struct chp_link link; | ||
533 | 532 | ||
534 | memset(&link, 0, sizeof(struct chp_link)); | ||
535 | link.chpid = chpid; | ||
536 | /* Wait until previous actions have settled. */ | 533 | /* Wait until previous actions have settled. */ |
537 | css_wait_for_slow_path(); | 534 | css_wait_for_slow_path(); |
538 | /* | 535 | /* |
@@ -542,10 +539,10 @@ int chsc_chp_vary(struct chp_id chpid, int on) | |||
542 | /* Try to update the channel path descritor. */ | 539 | /* Try to update the channel path descritor. */ |
543 | chsc_determine_base_channel_path_desc(chpid, &chp->desc); | 540 | chsc_determine_base_channel_path_desc(chpid, &chp->desc); |
544 | for_each_subchannel_staged(s390_subchannel_vary_chpid_on, | 541 | for_each_subchannel_staged(s390_subchannel_vary_chpid_on, |
545 | __s390_vary_chpid_on, &link); | 542 | __s390_vary_chpid_on, &chpid); |
546 | } else | 543 | } else |
547 | for_each_subchannel_staged(s390_subchannel_vary_chpid_off, | 544 | for_each_subchannel_staged(s390_subchannel_vary_chpid_off, |
548 | NULL, &link); | 545 | NULL, &chpid); |
549 | 546 | ||
550 | return 0; | 547 | return 0; |
551 | } | 548 | } |
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index 155a82bcb9e5..4a1ff5c2eb88 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h | |||
@@ -68,8 +68,13 @@ struct schib { | |||
68 | __u8 mda[4]; /* model dependent area */ | 68 | __u8 mda[4]; /* model dependent area */ |
69 | } __attribute__ ((packed,aligned(4))); | 69 | } __attribute__ ((packed,aligned(4))); |
70 | 70 | ||
71 | /* | ||
72 | * When rescheduled, todo's with higher values will overwrite those | ||
73 | * with lower values. | ||
74 | */ | ||
71 | enum sch_todo { | 75 | enum sch_todo { |
72 | SCH_TODO_NOTHING, | 76 | SCH_TODO_NOTHING, |
77 | SCH_TODO_EVAL, | ||
73 | SCH_TODO_UNREG, | 78 | SCH_TODO_UNREG, |
74 | }; | 79 | }; |
75 | 80 | ||
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 92d7324acb1c..21908e67bf67 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -195,51 +195,6 @@ void css_sch_device_unregister(struct subchannel *sch) | |||
195 | } | 195 | } |
196 | EXPORT_SYMBOL_GPL(css_sch_device_unregister); | 196 | EXPORT_SYMBOL_GPL(css_sch_device_unregister); |
197 | 197 | ||
198 | static void css_sch_todo(struct work_struct *work) | ||
199 | { | ||
200 | struct subchannel *sch; | ||
201 | enum sch_todo todo; | ||
202 | |||
203 | sch = container_of(work, struct subchannel, todo_work); | ||
204 | /* Find out todo. */ | ||
205 | spin_lock_irq(sch->lock); | ||
206 | todo = sch->todo; | ||
207 | CIO_MSG_EVENT(4, "sch_todo: sch=0.%x.%04x, todo=%d\n", sch->schid.ssid, | ||
208 | sch->schid.sch_no, todo); | ||
209 | sch->todo = SCH_TODO_NOTHING; | ||
210 | spin_unlock_irq(sch->lock); | ||
211 | /* Perform todo. */ | ||
212 | if (todo == SCH_TODO_UNREG) | ||
213 | css_sch_device_unregister(sch); | ||
214 | /* Release workqueue ref. */ | ||
215 | put_device(&sch->dev); | ||
216 | } | ||
217 | |||
218 | /** | ||
219 | * css_sched_sch_todo - schedule a subchannel operation | ||
220 | * @sch: subchannel | ||
221 | * @todo: todo | ||
222 | * | ||
223 | * Schedule the operation identified by @todo to be performed on the slow path | ||
224 | * workqueue. Do nothing if another operation with higher priority is already | ||
225 | * scheduled. Needs to be called with subchannel lock held. | ||
226 | */ | ||
227 | void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo) | ||
228 | { | ||
229 | CIO_MSG_EVENT(4, "sch_todo: sched sch=0.%x.%04x todo=%d\n", | ||
230 | sch->schid.ssid, sch->schid.sch_no, todo); | ||
231 | if (sch->todo >= todo) | ||
232 | return; | ||
233 | /* Get workqueue ref. */ | ||
234 | if (!get_device(&sch->dev)) | ||
235 | return; | ||
236 | sch->todo = todo; | ||
237 | if (!queue_work(cio_work_q, &sch->todo_work)) { | ||
238 | /* Already queued, release workqueue ref. */ | ||
239 | put_device(&sch->dev); | ||
240 | } | ||
241 | } | ||
242 | |||
243 | static void ssd_from_pmcw(struct chsc_ssd_info *ssd, struct pmcw *pmcw) | 198 | static void ssd_from_pmcw(struct chsc_ssd_info *ssd, struct pmcw *pmcw) |
244 | { | 199 | { |
245 | int i; | 200 | int i; |
@@ -466,6 +421,65 @@ static void css_evaluate_subchannel(struct subchannel_id schid, int slow) | |||
466 | css_schedule_eval(schid); | 421 | css_schedule_eval(schid); |
467 | } | 422 | } |
468 | 423 | ||
424 | /** | ||
425 | * css_sched_sch_todo - schedule a subchannel operation | ||
426 | * @sch: subchannel | ||
427 | * @todo: todo | ||
428 | * | ||
429 | * Schedule the operation identified by @todo to be performed on the slow path | ||
430 | * workqueue. Do nothing if another operation with higher priority is already | ||
431 | * scheduled. Needs to be called with subchannel lock held. | ||
432 | */ | ||
433 | void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo) | ||
434 | { | ||
435 | CIO_MSG_EVENT(4, "sch_todo: sched sch=0.%x.%04x todo=%d\n", | ||
436 | sch->schid.ssid, sch->schid.sch_no, todo); | ||
437 | if (sch->todo >= todo) | ||
438 | return; | ||
439 | /* Get workqueue ref. */ | ||
440 | if (!get_device(&sch->dev)) | ||
441 | return; | ||
442 | sch->todo = todo; | ||
443 | if (!queue_work(cio_work_q, &sch->todo_work)) { | ||
444 | /* Already queued, release workqueue ref. */ | ||
445 | put_device(&sch->dev); | ||
446 | } | ||
447 | } | ||
448 | |||
449 | static void css_sch_todo(struct work_struct *work) | ||
450 | { | ||
451 | struct subchannel *sch; | ||
452 | enum sch_todo todo; | ||
453 | int ret; | ||
454 | |||
455 | sch = container_of(work, struct subchannel, todo_work); | ||
456 | /* Find out todo. */ | ||
457 | spin_lock_irq(sch->lock); | ||
458 | todo = sch->todo; | ||
459 | CIO_MSG_EVENT(4, "sch_todo: sch=0.%x.%04x, todo=%d\n", sch->schid.ssid, | ||
460 | sch->schid.sch_no, todo); | ||
461 | sch->todo = SCH_TODO_NOTHING; | ||
462 | spin_unlock_irq(sch->lock); | ||
463 | /* Perform todo. */ | ||
464 | switch (todo) { | ||
465 | case SCH_TODO_NOTHING: | ||
466 | break; | ||
467 | case SCH_TODO_EVAL: | ||
468 | ret = css_evaluate_known_subchannel(sch, 1); | ||
469 | if (ret == -EAGAIN) { | ||
470 | spin_lock_irq(sch->lock); | ||
471 | css_sched_sch_todo(sch, todo); | ||
472 | spin_unlock_irq(sch->lock); | ||
473 | } | ||
474 | break; | ||
475 | case SCH_TODO_UNREG: | ||
476 | css_sch_device_unregister(sch); | ||
477 | break; | ||
478 | } | ||
479 | /* Release workqueue ref. */ | ||
480 | put_device(&sch->dev); | ||
481 | } | ||
482 | |||
469 | static struct idset *slow_subchannel_set; | 483 | static struct idset *slow_subchannel_set; |
470 | static spinlock_t slow_subchannel_lock; | 484 | static spinlock_t slow_subchannel_lock; |
471 | static wait_queue_head_t css_eval_wq; | 485 | static wait_queue_head_t css_eval_wq; |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index d734f4a0ecac..47269858ecb6 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -1868,9 +1868,9 @@ static void __ccw_device_pm_restore(struct ccw_device *cdev) | |||
1868 | */ | 1868 | */ |
1869 | cdev->private->flags.resuming = 1; | 1869 | cdev->private->flags.resuming = 1; |
1870 | cdev->private->path_new_mask = LPM_ANYPATH; | 1870 | cdev->private->path_new_mask = LPM_ANYPATH; |
1871 | css_schedule_eval(sch->schid); | 1871 | css_sched_sch_todo(sch, SCH_TODO_EVAL); |
1872 | spin_unlock_irq(sch->lock); | 1872 | spin_unlock_irq(sch->lock); |
1873 | css_complete_work(); | 1873 | css_wait_for_slow_path(); |
1874 | 1874 | ||
1875 | /* cdev may have been moved to a different subchannel. */ | 1875 | /* cdev may have been moved to a different subchannel. */ |
1876 | sch = to_subchannel(cdev->dev.parent); | 1876 | sch = to_subchannel(cdev->dev.parent); |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 52c233fa2b12..1b853513c891 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -496,8 +496,26 @@ static void ccw_device_reset_path_events(struct ccw_device *cdev) | |||
496 | cdev->private->pgid_reset_mask = 0; | 496 | cdev->private->pgid_reset_mask = 0; |
497 | } | 497 | } |
498 | 498 | ||
499 | void | 499 | static void create_fake_irb(struct irb *irb, int type) |
500 | ccw_device_verify_done(struct ccw_device *cdev, int err) | 500 | { |
501 | memset(irb, 0, sizeof(*irb)); | ||
502 | if (type == FAKE_CMD_IRB) { | ||
503 | struct cmd_scsw *scsw = &irb->scsw.cmd; | ||
504 | scsw->cc = 1; | ||
505 | scsw->fctl = SCSW_FCTL_START_FUNC; | ||
506 | scsw->actl = SCSW_ACTL_START_PEND; | ||
507 | scsw->stctl = SCSW_STCTL_STATUS_PEND; | ||
508 | } else if (type == FAKE_TM_IRB) { | ||
509 | struct tm_scsw *scsw = &irb->scsw.tm; | ||
510 | scsw->x = 1; | ||
511 | scsw->cc = 1; | ||
512 | scsw->fctl = SCSW_FCTL_START_FUNC; | ||
513 | scsw->actl = SCSW_ACTL_START_PEND; | ||
514 | scsw->stctl = SCSW_STCTL_STATUS_PEND; | ||
515 | } | ||
516 | } | ||
517 | |||
518 | void ccw_device_verify_done(struct ccw_device *cdev, int err) | ||
501 | { | 519 | { |
502 | struct subchannel *sch; | 520 | struct subchannel *sch; |
503 | 521 | ||
@@ -520,12 +538,8 @@ callback: | |||
520 | ccw_device_done(cdev, DEV_STATE_ONLINE); | 538 | ccw_device_done(cdev, DEV_STATE_ONLINE); |
521 | /* Deliver fake irb to device driver, if needed. */ | 539 | /* Deliver fake irb to device driver, if needed. */ |
522 | if (cdev->private->flags.fake_irb) { | 540 | if (cdev->private->flags.fake_irb) { |
523 | memset(&cdev->private->irb, 0, sizeof(struct irb)); | 541 | create_fake_irb(&cdev->private->irb, |
524 | cdev->private->irb.scsw.cmd.cc = 1; | 542 | cdev->private->flags.fake_irb); |
525 | cdev->private->irb.scsw.cmd.fctl = SCSW_FCTL_START_FUNC; | ||
526 | cdev->private->irb.scsw.cmd.actl = SCSW_ACTL_START_PEND; | ||
527 | cdev->private->irb.scsw.cmd.stctl = | ||
528 | SCSW_STCTL_STATUS_PEND; | ||
529 | cdev->private->flags.fake_irb = 0; | 543 | cdev->private->flags.fake_irb = 0; |
530 | if (cdev->handler) | 544 | if (cdev->handler) |
531 | cdev->handler(cdev, cdev->private->intparm, | 545 | cdev->handler(cdev, cdev->private->intparm, |
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index f98698d5735e..ec7fb6d3b479 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c | |||
@@ -198,7 +198,7 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa, | |||
198 | if (cdev->private->state == DEV_STATE_VERIFY) { | 198 | if (cdev->private->state == DEV_STATE_VERIFY) { |
199 | /* Remember to fake irb when finished. */ | 199 | /* Remember to fake irb when finished. */ |
200 | if (!cdev->private->flags.fake_irb) { | 200 | if (!cdev->private->flags.fake_irb) { |
201 | cdev->private->flags.fake_irb = 1; | 201 | cdev->private->flags.fake_irb = FAKE_CMD_IRB; |
202 | cdev->private->intparm = intparm; | 202 | cdev->private->intparm = intparm; |
203 | return 0; | 203 | return 0; |
204 | } else | 204 | } else |
@@ -213,9 +213,9 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa, | |||
213 | ret = cio_set_options (sch, flags); | 213 | ret = cio_set_options (sch, flags); |
214 | if (ret) | 214 | if (ret) |
215 | return ret; | 215 | return ret; |
216 | /* Adjust requested path mask to excluded varied off paths. */ | 216 | /* Adjust requested path mask to exclude unusable paths. */ |
217 | if (lpm) { | 217 | if (lpm) { |
218 | lpm &= sch->opm; | 218 | lpm &= sch->lpm; |
219 | if (lpm == 0) | 219 | if (lpm == 0) |
220 | return -EACCES; | 220 | return -EACCES; |
221 | } | 221 | } |
@@ -605,11 +605,21 @@ int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw, | |||
605 | sch = to_subchannel(cdev->dev.parent); | 605 | sch = to_subchannel(cdev->dev.parent); |
606 | if (!sch->schib.pmcw.ena) | 606 | if (!sch->schib.pmcw.ena) |
607 | return -EINVAL; | 607 | return -EINVAL; |
608 | if (cdev->private->state == DEV_STATE_VERIFY) { | ||
609 | /* Remember to fake irb when finished. */ | ||
610 | if (!cdev->private->flags.fake_irb) { | ||
611 | cdev->private->flags.fake_irb = FAKE_TM_IRB; | ||
612 | cdev->private->intparm = intparm; | ||
613 | return 0; | ||
614 | } else | ||
615 | /* There's already a fake I/O around. */ | ||
616 | return -EBUSY; | ||
617 | } | ||
608 | if (cdev->private->state != DEV_STATE_ONLINE) | 618 | if (cdev->private->state != DEV_STATE_ONLINE) |
609 | return -EIO; | 619 | return -EIO; |
610 | /* Adjust requested path mask to excluded varied off paths. */ | 620 | /* Adjust requested path mask to exclude unusable paths. */ |
611 | if (lpm) { | 621 | if (lpm) { |
612 | lpm &= sch->opm; | 622 | lpm &= sch->lpm; |
613 | if (lpm == 0) | 623 | if (lpm == 0) |
614 | return -EACCES; | 624 | return -EACCES; |
615 | } | 625 | } |
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index 2ebb492a5c17..76253dfcc1be 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h | |||
@@ -111,6 +111,9 @@ enum cdev_todo { | |||
111 | CDEV_TODO_UNREG_EVAL, | 111 | CDEV_TODO_UNREG_EVAL, |
112 | }; | 112 | }; |
113 | 113 | ||
114 | #define FAKE_CMD_IRB 1 | ||
115 | #define FAKE_TM_IRB 2 | ||
116 | |||
114 | struct ccw_device_private { | 117 | struct ccw_device_private { |
115 | struct ccw_device *cdev; | 118 | struct ccw_device *cdev; |
116 | struct subchannel *sch; | 119 | struct subchannel *sch; |
@@ -138,7 +141,7 @@ struct ccw_device_private { | |||
138 | unsigned int doverify:1; /* delayed path verification */ | 141 | unsigned int doverify:1; /* delayed path verification */ |
139 | unsigned int donotify:1; /* call notify function */ | 142 | unsigned int donotify:1; /* call notify function */ |
140 | unsigned int recog_done:1; /* dev. recog. complete */ | 143 | unsigned int recog_done:1; /* dev. recog. complete */ |
141 | unsigned int fake_irb:1; /* deliver faked irb */ | 144 | unsigned int fake_irb:2; /* deliver faked irb */ |
142 | unsigned int resuming:1; /* recognition while resume */ | 145 | unsigned int resuming:1; /* recognition while resume */ |
143 | unsigned int pgroup:1; /* pathgroup is set up */ | 146 | unsigned int pgroup:1; /* pathgroup is set up */ |
144 | unsigned int mpath:1; /* multipathing is set up */ | 147 | unsigned int mpath:1; /* multipathing is set up */ |
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index ec94f049e995..96bbe9d12a79 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
@@ -1552,6 +1552,8 @@ static void ap_reset(struct ap_device *ap_dev) | |||
1552 | rc = ap_init_queue(ap_dev->qid); | 1552 | rc = ap_init_queue(ap_dev->qid); |
1553 | if (rc == -ENODEV) | 1553 | if (rc == -ENODEV) |
1554 | ap_dev->unregistered = 1; | 1554 | ap_dev->unregistered = 1; |
1555 | else | ||
1556 | __ap_schedule_poll_timer(); | ||
1555 | } | 1557 | } |
1556 | 1558 | ||
1557 | static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags) | 1559 | static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags) |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index a1fd73df5416..8ba4510a9519 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -199,7 +199,7 @@ config SPI_FSL_LIB | |||
199 | depends on FSL_SOC | 199 | depends on FSL_SOC |
200 | 200 | ||
201 | config SPI_FSL_SPI | 201 | config SPI_FSL_SPI |
202 | tristate "Freescale SPI controller" | 202 | bool "Freescale SPI controller" |
203 | depends on FSL_SOC | 203 | depends on FSL_SOC |
204 | select SPI_FSL_LIB | 204 | select SPI_FSL_LIB |
205 | help | 205 | help |
@@ -208,7 +208,7 @@ config SPI_FSL_SPI | |||
208 | MPC8569 uses the controller in QE mode, MPC8610 in cpu mode. | 208 | MPC8569 uses the controller in QE mode, MPC8610 in cpu mode. |
209 | 209 | ||
210 | config SPI_FSL_ESPI | 210 | config SPI_FSL_ESPI |
211 | tristate "Freescale eSPI controller" | 211 | bool "Freescale eSPI controller" |
212 | depends on FSL_SOC | 212 | depends on FSL_SOC |
213 | select SPI_FSL_LIB | 213 | select SPI_FSL_LIB |
214 | help | 214 | help |
diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index 024b48aed5ca..acc88b4d2869 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c | |||
@@ -13,6 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | ||
16 | #include <linux/init.h> | 17 | #include <linux/init.h> |
17 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
18 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index e093d3ec41ba..0094c645ff0d 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c | |||
@@ -256,7 +256,7 @@ static void spi_gpio_cleanup(struct spi_device *spi) | |||
256 | spi_bitbang_cleanup(spi); | 256 | spi_bitbang_cleanup(spi); |
257 | } | 257 | } |
258 | 258 | ||
259 | static int __init spi_gpio_alloc(unsigned pin, const char *label, bool is_in) | 259 | static int __devinit spi_gpio_alloc(unsigned pin, const char *label, bool is_in) |
260 | { | 260 | { |
261 | int value; | 261 | int value; |
262 | 262 | ||
@@ -270,7 +270,7 @@ static int __init spi_gpio_alloc(unsigned pin, const char *label, bool is_in) | |||
270 | return value; | 270 | return value; |
271 | } | 271 | } |
272 | 272 | ||
273 | static int __init | 273 | static int __devinit |
274 | spi_gpio_request(struct spi_gpio_platform_data *pdata, const char *label, | 274 | spi_gpio_request(struct spi_gpio_platform_data *pdata, const char *label, |
275 | u16 *res_flags) | 275 | u16 *res_flags) |
276 | { | 276 | { |
diff --git a/drivers/spi/spi-nuc900.c b/drivers/spi/spi-nuc900.c index 21c70b2b8311..182e9c873822 100644 --- a/drivers/spi/spi-nuc900.c +++ b/drivers/spi/spi-nuc900.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/module.h> | ||
11 | #include <linux/init.h> | 12 | #include <linux/init.h> |
12 | #include <linux/spinlock.h> | 13 | #include <linux/spinlock.h> |
13 | #include <linux/workqueue.h> | 14 | #include <linux/workqueue.h> |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 0fd96c10271d..8599545cdf9e 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -614,13 +614,12 @@ int iscsit_add_reject( | |||
614 | hdr = (struct iscsi_reject *) cmd->pdu; | 614 | hdr = (struct iscsi_reject *) cmd->pdu; |
615 | hdr->reason = reason; | 615 | hdr->reason = reason; |
616 | 616 | ||
617 | cmd->buf_ptr = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL); | 617 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); |
618 | if (!cmd->buf_ptr) { | 618 | if (!cmd->buf_ptr) { |
619 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); | 619 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); |
620 | iscsit_release_cmd(cmd); | 620 | iscsit_release_cmd(cmd); |
621 | return -1; | 621 | return -1; |
622 | } | 622 | } |
623 | memcpy(cmd->buf_ptr, buf, ISCSI_HDR_LEN); | ||
624 | 623 | ||
625 | spin_lock_bh(&conn->cmd_lock); | 624 | spin_lock_bh(&conn->cmd_lock); |
626 | list_add_tail(&cmd->i_list, &conn->conn_cmd_list); | 625 | list_add_tail(&cmd->i_list, &conn->conn_cmd_list); |
@@ -661,13 +660,12 @@ int iscsit_add_reject_from_cmd( | |||
661 | hdr = (struct iscsi_reject *) cmd->pdu; | 660 | hdr = (struct iscsi_reject *) cmd->pdu; |
662 | hdr->reason = reason; | 661 | hdr->reason = reason; |
663 | 662 | ||
664 | cmd->buf_ptr = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL); | 663 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); |
665 | if (!cmd->buf_ptr) { | 664 | if (!cmd->buf_ptr) { |
666 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); | 665 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); |
667 | iscsit_release_cmd(cmd); | 666 | iscsit_release_cmd(cmd); |
668 | return -1; | 667 | return -1; |
669 | } | 668 | } |
670 | memcpy(cmd->buf_ptr, buf, ISCSI_HDR_LEN); | ||
671 | 669 | ||
672 | if (add_to_conn) { | 670 | if (add_to_conn) { |
673 | spin_lock_bh(&conn->cmd_lock); | 671 | spin_lock_bh(&conn->cmd_lock); |
@@ -1017,11 +1015,6 @@ done: | |||
1017 | " non-existent or non-exported iSCSI LUN:" | 1015 | " non-existent or non-exported iSCSI LUN:" |
1018 | " 0x%016Lx\n", get_unaligned_le64(&hdr->lun)); | 1016 | " 0x%016Lx\n", get_unaligned_le64(&hdr->lun)); |
1019 | } | 1017 | } |
1020 | if (ret == PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES) | ||
1021 | return iscsit_add_reject_from_cmd( | ||
1022 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | ||
1023 | 1, 1, buf, cmd); | ||
1024 | |||
1025 | send_check_condition = 1; | 1018 | send_check_condition = 1; |
1026 | goto attach_cmd; | 1019 | goto attach_cmd; |
1027 | } | 1020 | } |
@@ -1044,6 +1037,8 @@ done: | |||
1044 | */ | 1037 | */ |
1045 | send_check_condition = 1; | 1038 | send_check_condition = 1; |
1046 | } else { | 1039 | } else { |
1040 | cmd->data_length = cmd->se_cmd.data_length; | ||
1041 | |||
1047 | if (iscsit_decide_list_to_build(cmd, payload_length) < 0) | 1042 | if (iscsit_decide_list_to_build(cmd, payload_length) < 0) |
1048 | return iscsit_add_reject_from_cmd( | 1043 | return iscsit_add_reject_from_cmd( |
1049 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1044 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
@@ -1123,7 +1118,7 @@ attach_cmd: | |||
1123 | * the backend memory allocation. | 1118 | * the backend memory allocation. |
1124 | */ | 1119 | */ |
1125 | ret = transport_generic_new_cmd(&cmd->se_cmd); | 1120 | ret = transport_generic_new_cmd(&cmd->se_cmd); |
1126 | if ((ret < 0) || (cmd->se_cmd.se_cmd_flags & SCF_SE_CMD_FAILED)) { | 1121 | if (ret < 0) { |
1127 | immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; | 1122 | immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; |
1128 | dump_immediate_data = 1; | 1123 | dump_immediate_data = 1; |
1129 | goto after_immediate_data; | 1124 | goto after_immediate_data; |
@@ -1341,7 +1336,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) | |||
1341 | 1336 | ||
1342 | spin_lock_irqsave(&se_cmd->t_state_lock, flags); | 1337 | spin_lock_irqsave(&se_cmd->t_state_lock, flags); |
1343 | if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) || | 1338 | if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) || |
1344 | (se_cmd->se_cmd_flags & SCF_SE_CMD_FAILED)) | 1339 | (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION)) |
1345 | dump_unsolicited_data = 1; | 1340 | dump_unsolicited_data = 1; |
1346 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); | 1341 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); |
1347 | 1342 | ||
@@ -2513,10 +2508,10 @@ static int iscsit_send_data_in( | |||
2513 | if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { | 2508 | if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { |
2514 | if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { | 2509 | if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { |
2515 | hdr->flags |= ISCSI_FLAG_DATA_OVERFLOW; | 2510 | hdr->flags |= ISCSI_FLAG_DATA_OVERFLOW; |
2516 | hdr->residual_count = cpu_to_be32(cmd->residual_count); | 2511 | hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); |
2517 | } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { | 2512 | } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { |
2518 | hdr->flags |= ISCSI_FLAG_DATA_UNDERFLOW; | 2513 | hdr->flags |= ISCSI_FLAG_DATA_UNDERFLOW; |
2519 | hdr->residual_count = cpu_to_be32(cmd->residual_count); | 2514 | hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); |
2520 | } | 2515 | } |
2521 | } | 2516 | } |
2522 | hton24(hdr->dlength, datain.length); | 2517 | hton24(hdr->dlength, datain.length); |
@@ -3018,10 +3013,10 @@ static int iscsit_send_status( | |||
3018 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; | 3013 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; |
3019 | if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { | 3014 | if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { |
3020 | hdr->flags |= ISCSI_FLAG_CMD_OVERFLOW; | 3015 | hdr->flags |= ISCSI_FLAG_CMD_OVERFLOW; |
3021 | hdr->residual_count = cpu_to_be32(cmd->residual_count); | 3016 | hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); |
3022 | } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { | 3017 | } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { |
3023 | hdr->flags |= ISCSI_FLAG_CMD_UNDERFLOW; | 3018 | hdr->flags |= ISCSI_FLAG_CMD_UNDERFLOW; |
3024 | hdr->residual_count = cpu_to_be32(cmd->residual_count); | 3019 | hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); |
3025 | } | 3020 | } |
3026 | hdr->response = cmd->iscsi_response; | 3021 | hdr->response = cmd->iscsi_response; |
3027 | hdr->cmd_status = cmd->se_cmd.scsi_status; | 3022 | hdr->cmd_status = cmd->se_cmd.scsi_status; |
@@ -3133,6 +3128,7 @@ static int iscsit_send_task_mgt_rsp( | |||
3133 | hdr = (struct iscsi_tm_rsp *) cmd->pdu; | 3128 | hdr = (struct iscsi_tm_rsp *) cmd->pdu; |
3134 | memset(hdr, 0, ISCSI_HDR_LEN); | 3129 | memset(hdr, 0, ISCSI_HDR_LEN); |
3135 | hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP; | 3130 | hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP; |
3131 | hdr->flags = ISCSI_FLAG_CMD_FINAL; | ||
3136 | hdr->response = iscsit_convert_tcm_tmr_rsp(se_tmr); | 3132 | hdr->response = iscsit_convert_tcm_tmr_rsp(se_tmr); |
3137 | hdr->itt = cpu_to_be32(cmd->init_task_tag); | 3133 | hdr->itt = cpu_to_be32(cmd->init_task_tag); |
3138 | cmd->stat_sn = conn->stat_sn++; | 3134 | cmd->stat_sn = conn->stat_sn++; |
diff --git a/drivers/target/iscsi/iscsi_target_auth.c b/drivers/target/iscsi/iscsi_target_auth.c index beb39469e7f1..1cd6ce373b83 100644 --- a/drivers/target/iscsi/iscsi_target_auth.c +++ b/drivers/target/iscsi/iscsi_target_auth.c | |||
@@ -30,9 +30,11 @@ | |||
30 | 30 | ||
31 | static int chap_string_to_hex(unsigned char *dst, unsigned char *src, int len) | 31 | static int chap_string_to_hex(unsigned char *dst, unsigned char *src, int len) |
32 | { | 32 | { |
33 | int j = DIV_ROUND_UP(len, 2); | 33 | int j = DIV_ROUND_UP(len, 2), rc; |
34 | 34 | ||
35 | hex2bin(dst, src, j); | 35 | rc = hex2bin(dst, src, j); |
36 | if (rc < 0) | ||
37 | pr_debug("CHAP string contains non hex digit symbols\n"); | ||
36 | 38 | ||
37 | dst[j] = '\0'; | 39 | dst[j] = '\0'; |
38 | return j; | 40 | return j; |
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 3723d90d5ae5..f1a02dad05a0 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h | |||
@@ -398,7 +398,6 @@ struct iscsi_cmd { | |||
398 | u32 pdu_send_order; | 398 | u32 pdu_send_order; |
399 | /* Current struct iscsi_pdu in struct iscsi_cmd->pdu_list */ | 399 | /* Current struct iscsi_pdu in struct iscsi_cmd->pdu_list */ |
400 | u32 pdu_start; | 400 | u32 pdu_start; |
401 | u32 residual_count; | ||
402 | /* Next struct iscsi_seq to send in struct iscsi_cmd->seq_list */ | 401 | /* Next struct iscsi_seq to send in struct iscsi_cmd->seq_list */ |
403 | u32 seq_send_order; | 402 | u32 seq_send_order; |
404 | /* Number of struct iscsi_seq in struct iscsi_cmd->seq_list */ | 403 | /* Number of struct iscsi_seq in struct iscsi_cmd->seq_list */ |
@@ -535,7 +534,6 @@ struct iscsi_conn { | |||
535 | atomic_t connection_exit; | 534 | atomic_t connection_exit; |
536 | atomic_t connection_recovery; | 535 | atomic_t connection_recovery; |
537 | atomic_t connection_reinstatement; | 536 | atomic_t connection_reinstatement; |
538 | atomic_t connection_wait; | ||
539 | atomic_t connection_wait_rcfr; | 537 | atomic_t connection_wait_rcfr; |
540 | atomic_t sleep_on_conn_wait_comp; | 538 | atomic_t sleep_on_conn_wait_comp; |
541 | atomic_t transport_failed; | 539 | atomic_t transport_failed; |
@@ -643,7 +641,6 @@ struct iscsi_session { | |||
643 | atomic_t session_reinstatement; | 641 | atomic_t session_reinstatement; |
644 | atomic_t session_stop_active; | 642 | atomic_t session_stop_active; |
645 | atomic_t sleep_on_sess_wait_comp; | 643 | atomic_t sleep_on_sess_wait_comp; |
646 | atomic_t transport_wait_cmds; | ||
647 | /* connection list */ | 644 | /* connection list */ |
648 | struct list_head sess_conn_list; | 645 | struct list_head sess_conn_list; |
649 | struct list_head cr_active_list; | 646 | struct list_head cr_active_list; |
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c index c4c68da3e500..101b1beb3bca 100644 --- a/drivers/target/iscsi/iscsi_target_erl1.c +++ b/drivers/target/iscsi/iscsi_target_erl1.c | |||
@@ -938,8 +938,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) | |||
938 | * handle the SCF_SCSI_RESERVATION_CONFLICT case here as well. | 938 | * handle the SCF_SCSI_RESERVATION_CONFLICT case here as well. |
939 | */ | 939 | */ |
940 | if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) { | 940 | if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) { |
941 | if (se_cmd->se_cmd_flags & | 941 | if (se_cmd->scsi_sense_reason == TCM_RESERVATION_CONFLICT) { |
942 | SCF_SCSI_RESERVATION_CONFLICT) { | ||
943 | cmd->i_state = ISTATE_SEND_STATUS; | 942 | cmd->i_state = ISTATE_SEND_STATUS; |
944 | spin_unlock_bh(&cmd->istate_lock); | 943 | spin_unlock_bh(&cmd->istate_lock); |
945 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, | 944 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index daad362a93ce..d734bdec24f9 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
@@ -224,7 +224,7 @@ static int iscsi_login_zero_tsih_s1( | |||
224 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | 224 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, |
225 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | 225 | ISCSI_LOGIN_STATUS_NO_RESOURCES); |
226 | pr_err("Could not allocate memory for session\n"); | 226 | pr_err("Could not allocate memory for session\n"); |
227 | return -1; | 227 | return -ENOMEM; |
228 | } | 228 | } |
229 | 229 | ||
230 | iscsi_login_set_conn_values(sess, conn, pdu->cid); | 230 | iscsi_login_set_conn_values(sess, conn, pdu->cid); |
@@ -250,7 +250,8 @@ static int iscsi_login_zero_tsih_s1( | |||
250 | pr_err("idr_pre_get() for sess_idr failed\n"); | 250 | pr_err("idr_pre_get() for sess_idr failed\n"); |
251 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | 251 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, |
252 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | 252 | ISCSI_LOGIN_STATUS_NO_RESOURCES); |
253 | return -1; | 253 | kfree(sess); |
254 | return -ENOMEM; | ||
254 | } | 255 | } |
255 | spin_lock(&sess_idr_lock); | 256 | spin_lock(&sess_idr_lock); |
256 | idr_get_new(&sess_idr, NULL, &sess->session_index); | 257 | idr_get_new(&sess_idr, NULL, &sess->session_index); |
@@ -270,14 +271,16 @@ static int iscsi_login_zero_tsih_s1( | |||
270 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | 271 | ISCSI_LOGIN_STATUS_NO_RESOURCES); |
271 | pr_err("Unable to allocate memory for" | 272 | pr_err("Unable to allocate memory for" |
272 | " struct iscsi_sess_ops.\n"); | 273 | " struct iscsi_sess_ops.\n"); |
273 | return -1; | 274 | kfree(sess); |
275 | return -ENOMEM; | ||
274 | } | 276 | } |
275 | 277 | ||
276 | sess->se_sess = transport_init_session(); | 278 | sess->se_sess = transport_init_session(); |
277 | if (!sess->se_sess) { | 279 | if (IS_ERR(sess->se_sess)) { |
278 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | 280 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, |
279 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | 281 | ISCSI_LOGIN_STATUS_NO_RESOURCES); |
280 | return -1; | 282 | kfree(sess); |
283 | return -ENOMEM; | ||
281 | } | 284 | } |
282 | 285 | ||
283 | return 0; | 286 | return 0; |
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index 426cd4bf6a9a..98936cb7c294 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c | |||
@@ -981,14 +981,13 @@ struct iscsi_login *iscsi_target_init_negotiation( | |||
981 | return NULL; | 981 | return NULL; |
982 | } | 982 | } |
983 | 983 | ||
984 | login->req = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL); | 984 | login->req = kmemdup(login_pdu, ISCSI_HDR_LEN, GFP_KERNEL); |
985 | if (!login->req) { | 985 | if (!login->req) { |
986 | pr_err("Unable to allocate memory for Login Request.\n"); | 986 | pr_err("Unable to allocate memory for Login Request.\n"); |
987 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | 987 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, |
988 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | 988 | ISCSI_LOGIN_STATUS_NO_RESOURCES); |
989 | goto out; | 989 | goto out; |
990 | } | 990 | } |
991 | memcpy(login->req, login_pdu, ISCSI_HDR_LEN); | ||
992 | 991 | ||
993 | login->req_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL); | 992 | login->req_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL); |
994 | if (!login->req_buf) { | 993 | if (!login->req_buf) { |
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 3df1c9b8ae6b..81d5832fbbd5 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c | |||
@@ -113,11 +113,9 @@ static struct se_cmd *tcm_loop_allocate_core_cmd( | |||
113 | scsi_bufflen(sc), sc->sc_data_direction, sam_task_attr, | 113 | scsi_bufflen(sc), sc->sc_data_direction, sam_task_attr, |
114 | &tl_cmd->tl_sense_buf[0]); | 114 | &tl_cmd->tl_sense_buf[0]); |
115 | 115 | ||
116 | /* | ||
117 | * Signal BIDI usage with T_TASK(cmd)->t_tasks_bidi | ||
118 | */ | ||
119 | if (scsi_bidi_cmnd(sc)) | 116 | if (scsi_bidi_cmnd(sc)) |
120 | se_cmd->t_tasks_bidi = 1; | 117 | se_cmd->se_cmd_flags |= SCF_BIDI; |
118 | |||
121 | /* | 119 | /* |
122 | * Locate the struct se_lun pointer and attach it to struct se_cmd | 120 | * Locate the struct se_lun pointer and attach it to struct se_cmd |
123 | */ | 121 | */ |
@@ -148,27 +146,13 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd) | |||
148 | * Allocate the necessary tasks to complete the received CDB+data | 146 | * Allocate the necessary tasks to complete the received CDB+data |
149 | */ | 147 | */ |
150 | ret = transport_generic_allocate_tasks(se_cmd, sc->cmnd); | 148 | ret = transport_generic_allocate_tasks(se_cmd, sc->cmnd); |
151 | if (ret == -ENOMEM) { | 149 | if (ret != 0) |
152 | /* Out of Resources */ | 150 | return ret; |
153 | return PYX_TRANSPORT_LU_COMM_FAILURE; | ||
154 | } else if (ret == -EINVAL) { | ||
155 | /* | ||
156 | * Handle case for SAM_STAT_RESERVATION_CONFLICT | ||
157 | */ | ||
158 | if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) | ||
159 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | ||
160 | /* | ||
161 | * Otherwise, return SAM_STAT_CHECK_CONDITION and return | ||
162 | * sense data. | ||
163 | */ | ||
164 | return PYX_TRANSPORT_USE_SENSE_REASON; | ||
165 | } | ||
166 | |||
167 | /* | 151 | /* |
168 | * For BIDI commands, pass in the extra READ buffer | 152 | * For BIDI commands, pass in the extra READ buffer |
169 | * to transport_generic_map_mem_to_cmd() below.. | 153 | * to transport_generic_map_mem_to_cmd() below.. |
170 | */ | 154 | */ |
171 | if (se_cmd->t_tasks_bidi) { | 155 | if (se_cmd->se_cmd_flags & SCF_BIDI) { |
172 | struct scsi_data_buffer *sdb = scsi_in(sc); | 156 | struct scsi_data_buffer *sdb = scsi_in(sc); |
173 | 157 | ||
174 | sgl_bidi = sdb->table.sgl; | 158 | sgl_bidi = sdb->table.sgl; |
@@ -194,12 +178,8 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd) | |||
194 | } | 178 | } |
195 | 179 | ||
196 | /* Tell the core about our preallocated memory */ | 180 | /* Tell the core about our preallocated memory */ |
197 | ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc), | 181 | return transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc), |
198 | scsi_sg_count(sc), sgl_bidi, sgl_bidi_count); | 182 | scsi_sg_count(sc), sgl_bidi, sgl_bidi_count); |
199 | if (ret < 0) | ||
200 | return PYX_TRANSPORT_LU_COMM_FAILURE; | ||
201 | |||
202 | return 0; | ||
203 | } | 183 | } |
204 | 184 | ||
205 | /* | 185 | /* |
@@ -1360,17 +1340,16 @@ void tcm_loop_drop_scsi_hba( | |||
1360 | { | 1340 | { |
1361 | struct tcm_loop_hba *tl_hba = container_of(wwn, | 1341 | struct tcm_loop_hba *tl_hba = container_of(wwn, |
1362 | struct tcm_loop_hba, tl_hba_wwn); | 1342 | struct tcm_loop_hba, tl_hba_wwn); |
1363 | int host_no = tl_hba->sh->host_no; | 1343 | |
1344 | pr_debug("TCM_Loop_ConfigFS: Deallocating emulated Target" | ||
1345 | " SAS Address: %s at Linux/SCSI Host ID: %d\n", | ||
1346 | tl_hba->tl_wwn_address, tl_hba->sh->host_no); | ||
1364 | /* | 1347 | /* |
1365 | * Call device_unregister() on the original tl_hba->dev. | 1348 | * Call device_unregister() on the original tl_hba->dev. |
1366 | * tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will | 1349 | * tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will |
1367 | * release *tl_hba; | 1350 | * release *tl_hba; |
1368 | */ | 1351 | */ |
1369 | device_unregister(&tl_hba->dev); | 1352 | device_unregister(&tl_hba->dev); |
1370 | |||
1371 | pr_debug("TCM_Loop_ConfigFS: Deallocated emulated Target" | ||
1372 | " SAS Address: %s at Linux/SCSI Host ID: %d\n", | ||
1373 | config_item_name(&wwn->wwn_group.cg_item), host_no); | ||
1374 | } | 1353 | } |
1375 | 1354 | ||
1376 | /* Start items for tcm_loop_cit */ | 1355 | /* Start items for tcm_loop_cit */ |
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 88f2ad43ec8b..1dcbef499d6a 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
@@ -191,9 +191,10 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
191 | int alua_access_state, primary = 0, rc; | 191 | int alua_access_state, primary = 0, rc; |
192 | u16 tg_pt_id, rtpi; | 192 | u16 tg_pt_id, rtpi; |
193 | 193 | ||
194 | if (!l_port) | 194 | if (!l_port) { |
195 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 195 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
196 | 196 | return -EINVAL; | |
197 | } | ||
197 | buf = transport_kmap_first_data_page(cmd); | 198 | buf = transport_kmap_first_data_page(cmd); |
198 | 199 | ||
199 | /* | 200 | /* |
@@ -203,7 +204,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
203 | l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem; | 204 | l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem; |
204 | if (!l_tg_pt_gp_mem) { | 205 | if (!l_tg_pt_gp_mem) { |
205 | pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n"); | 206 | pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n"); |
206 | rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 207 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
208 | rc = -EINVAL; | ||
207 | goto out; | 209 | goto out; |
208 | } | 210 | } |
209 | spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); | 211 | spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); |
@@ -211,7 +213,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
211 | if (!l_tg_pt_gp) { | 213 | if (!l_tg_pt_gp) { |
212 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); | 214 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); |
213 | pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n"); | 215 | pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n"); |
214 | rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 216 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
217 | rc = -EINVAL; | ||
215 | goto out; | 218 | goto out; |
216 | } | 219 | } |
217 | rc = (l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA); | 220 | rc = (l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA); |
@@ -220,7 +223,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
220 | if (!rc) { | 223 | if (!rc) { |
221 | pr_debug("Unable to process SET_TARGET_PORT_GROUPS" | 224 | pr_debug("Unable to process SET_TARGET_PORT_GROUPS" |
222 | " while TPGS_EXPLICT_ALUA is disabled\n"); | 225 | " while TPGS_EXPLICT_ALUA is disabled\n"); |
223 | rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 226 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
227 | rc = -EINVAL; | ||
224 | goto out; | 228 | goto out; |
225 | } | 229 | } |
226 | 230 | ||
@@ -245,7 +249,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
245 | * REQUEST, and the additional sense code set to INVALID | 249 | * REQUEST, and the additional sense code set to INVALID |
246 | * FIELD IN PARAMETER LIST. | 250 | * FIELD IN PARAMETER LIST. |
247 | */ | 251 | */ |
248 | rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 252 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
253 | rc = -EINVAL; | ||
249 | goto out; | 254 | goto out; |
250 | } | 255 | } |
251 | rc = -1; | 256 | rc = -1; |
@@ -298,7 +303,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
298 | * throw an exception with ASCQ: INVALID_PARAMETER_LIST | 303 | * throw an exception with ASCQ: INVALID_PARAMETER_LIST |
299 | */ | 304 | */ |
300 | if (rc != 0) { | 305 | if (rc != 0) { |
301 | rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 306 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
307 | rc = -EINVAL; | ||
302 | goto out; | 308 | goto out; |
303 | } | 309 | } |
304 | } else { | 310 | } else { |
@@ -335,7 +341,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
335 | * INVALID_PARAMETER_LIST | 341 | * INVALID_PARAMETER_LIST |
336 | */ | 342 | */ |
337 | if (rc != 0) { | 343 | if (rc != 0) { |
338 | rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 344 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
345 | rc = -EINVAL; | ||
339 | goto out; | 346 | goto out; |
340 | } | 347 | } |
341 | } | 348 | } |
@@ -1184,7 +1191,6 @@ void core_alua_free_lu_gp(struct t10_alua_lu_gp *lu_gp) | |||
1184 | * struct t10_alua_lu_gp. | 1191 | * struct t10_alua_lu_gp. |
1185 | */ | 1192 | */ |
1186 | spin_lock(&lu_gps_lock); | 1193 | spin_lock(&lu_gps_lock); |
1187 | atomic_set(&lu_gp->lu_gp_shutdown, 1); | ||
1188 | list_del(&lu_gp->lu_gp_node); | 1194 | list_del(&lu_gp->lu_gp_node); |
1189 | alua_lu_gps_count--; | 1195 | alua_lu_gps_count--; |
1190 | spin_unlock(&lu_gps_lock); | 1196 | spin_unlock(&lu_gps_lock); |
@@ -1438,7 +1444,6 @@ struct t10_alua_tg_pt_gp_member *core_alua_allocate_tg_pt_gp_mem( | |||
1438 | 1444 | ||
1439 | tg_pt_gp_mem->tg_pt = port; | 1445 | tg_pt_gp_mem->tg_pt = port; |
1440 | port->sep_alua_tg_pt_gp_mem = tg_pt_gp_mem; | 1446 | port->sep_alua_tg_pt_gp_mem = tg_pt_gp_mem; |
1441 | atomic_set(&port->sep_tg_pt_gp_active, 1); | ||
1442 | 1447 | ||
1443 | return tg_pt_gp_mem; | 1448 | return tg_pt_gp_mem; |
1444 | } | 1449 | } |
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index 683ba02b8247..831468b3163d 100644 --- a/drivers/target/target_core_cdb.c +++ b/drivers/target/target_core_cdb.c | |||
@@ -478,7 +478,7 @@ target_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) | |||
478 | if (cmd->data_length < 60) | 478 | if (cmd->data_length < 60) |
479 | return 0; | 479 | return 0; |
480 | 480 | ||
481 | buf[2] = 0x3c; | 481 | buf[3] = 0x3c; |
482 | /* Set HEADSUP, ORDSUP, SIMPSUP */ | 482 | /* Set HEADSUP, ORDSUP, SIMPSUP */ |
483 | buf[5] = 0x07; | 483 | buf[5] = 0x07; |
484 | 484 | ||
@@ -703,6 +703,7 @@ int target_emulate_inquiry(struct se_task *task) | |||
703 | if (cmd->data_length < 4) { | 703 | if (cmd->data_length < 4) { |
704 | pr_err("SCSI Inquiry payload length: %u" | 704 | pr_err("SCSI Inquiry payload length: %u" |
705 | " too small for EVPD=1\n", cmd->data_length); | 705 | " too small for EVPD=1\n", cmd->data_length); |
706 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
706 | return -EINVAL; | 707 | return -EINVAL; |
707 | } | 708 | } |
708 | 709 | ||
@@ -719,6 +720,7 @@ int target_emulate_inquiry(struct se_task *task) | |||
719 | } | 720 | } |
720 | 721 | ||
721 | pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); | 722 | pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); |
723 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | ||
722 | ret = -EINVAL; | 724 | ret = -EINVAL; |
723 | 725 | ||
724 | out_unmap: | 726 | out_unmap: |
@@ -969,7 +971,8 @@ int target_emulate_modesense(struct se_task *task) | |||
969 | default: | 971 | default: |
970 | pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", | 972 | pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", |
971 | cdb[2] & 0x3f, cdb[3]); | 973 | cdb[2] & 0x3f, cdb[3]); |
972 | return PYX_TRANSPORT_UNKNOWN_MODE_PAGE; | 974 | cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE; |
975 | return -EINVAL; | ||
973 | } | 976 | } |
974 | offset += length; | 977 | offset += length; |
975 | 978 | ||
@@ -1027,7 +1030,8 @@ int target_emulate_request_sense(struct se_task *task) | |||
1027 | if (cdb[1] & 0x01) { | 1030 | if (cdb[1] & 0x01) { |
1028 | pr_err("REQUEST_SENSE description emulation not" | 1031 | pr_err("REQUEST_SENSE description emulation not" |
1029 | " supported\n"); | 1032 | " supported\n"); |
1030 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 1033 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
1034 | return -ENOSYS; | ||
1031 | } | 1035 | } |
1032 | 1036 | ||
1033 | buf = transport_kmap_first_data_page(cmd); | 1037 | buf = transport_kmap_first_data_page(cmd); |
@@ -1100,7 +1104,8 @@ int target_emulate_unmap(struct se_task *task) | |||
1100 | if (!dev->transport->do_discard) { | 1104 | if (!dev->transport->do_discard) { |
1101 | pr_err("UNMAP emulation not supported for: %s\n", | 1105 | pr_err("UNMAP emulation not supported for: %s\n", |
1102 | dev->transport->name); | 1106 | dev->transport->name); |
1103 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 1107 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
1108 | return -ENOSYS; | ||
1104 | } | 1109 | } |
1105 | 1110 | ||
1106 | /* First UNMAP block descriptor starts at 8 byte offset */ | 1111 | /* First UNMAP block descriptor starts at 8 byte offset */ |
@@ -1157,7 +1162,8 @@ int target_emulate_write_same(struct se_task *task) | |||
1157 | if (!dev->transport->do_discard) { | 1162 | if (!dev->transport->do_discard) { |
1158 | pr_err("WRITE_SAME emulation not supported" | 1163 | pr_err("WRITE_SAME emulation not supported" |
1159 | " for: %s\n", dev->transport->name); | 1164 | " for: %s\n", dev->transport->name); |
1160 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 1165 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
1166 | return -ENOSYS; | ||
1161 | } | 1167 | } |
1162 | 1168 | ||
1163 | if (cmd->t_task_cdb[0] == WRITE_SAME) | 1169 | if (cmd->t_task_cdb[0] == WRITE_SAME) |
@@ -1193,11 +1199,13 @@ int target_emulate_write_same(struct se_task *task) | |||
1193 | int target_emulate_synchronize_cache(struct se_task *task) | 1199 | int target_emulate_synchronize_cache(struct se_task *task) |
1194 | { | 1200 | { |
1195 | struct se_device *dev = task->task_se_cmd->se_dev; | 1201 | struct se_device *dev = task->task_se_cmd->se_dev; |
1202 | struct se_cmd *cmd = task->task_se_cmd; | ||
1196 | 1203 | ||
1197 | if (!dev->transport->do_sync_cache) { | 1204 | if (!dev->transport->do_sync_cache) { |
1198 | pr_err("SYNCHRONIZE_CACHE emulation not supported" | 1205 | pr_err("SYNCHRONIZE_CACHE emulation not supported" |
1199 | " for: %s\n", dev->transport->name); | 1206 | " for: %s\n", dev->transport->name); |
1200 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 1207 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
1208 | return -ENOSYS; | ||
1201 | } | 1209 | } |
1202 | 1210 | ||
1203 | dev->transport->do_sync_cache(task); | 1211 | dev->transport->do_sync_cache(task); |
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index e0c1e8a8dd4e..93d4f6a1b798 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
@@ -67,9 +67,6 @@ static struct config_group target_core_hbagroup; | |||
67 | static struct config_group alua_group; | 67 | static struct config_group alua_group; |
68 | static struct config_group alua_lu_gps_group; | 68 | static struct config_group alua_lu_gps_group; |
69 | 69 | ||
70 | static DEFINE_SPINLOCK(se_device_lock); | ||
71 | static LIST_HEAD(se_dev_list); | ||
72 | |||
73 | static inline struct se_hba * | 70 | static inline struct se_hba * |
74 | item_to_hba(struct config_item *item) | 71 | item_to_hba(struct config_item *item) |
75 | { | 72 | { |
@@ -2741,7 +2738,6 @@ static struct config_group *target_core_make_subdev( | |||
2741 | " struct se_subsystem_dev\n"); | 2738 | " struct se_subsystem_dev\n"); |
2742 | goto unlock; | 2739 | goto unlock; |
2743 | } | 2740 | } |
2744 | INIT_LIST_HEAD(&se_dev->se_dev_node); | ||
2745 | INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list); | 2741 | INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list); |
2746 | spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock); | 2742 | spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock); |
2747 | INIT_LIST_HEAD(&se_dev->t10_pr.registration_list); | 2743 | INIT_LIST_HEAD(&se_dev->t10_pr.registration_list); |
@@ -2777,9 +2773,6 @@ static struct config_group *target_core_make_subdev( | |||
2777 | " from allocate_virtdevice()\n"); | 2773 | " from allocate_virtdevice()\n"); |
2778 | goto out; | 2774 | goto out; |
2779 | } | 2775 | } |
2780 | spin_lock(&se_device_lock); | ||
2781 | list_add_tail(&se_dev->se_dev_node, &se_dev_list); | ||
2782 | spin_unlock(&se_device_lock); | ||
2783 | 2776 | ||
2784 | config_group_init_type_name(&se_dev->se_dev_group, name, | 2777 | config_group_init_type_name(&se_dev->se_dev_group, name, |
2785 | &target_core_dev_cit); | 2778 | &target_core_dev_cit); |
@@ -2874,10 +2867,6 @@ static void target_core_drop_subdev( | |||
2874 | mutex_lock(&hba->hba_access_mutex); | 2867 | mutex_lock(&hba->hba_access_mutex); |
2875 | t = hba->transport; | 2868 | t = hba->transport; |
2876 | 2869 | ||
2877 | spin_lock(&se_device_lock); | ||
2878 | list_del(&se_dev->se_dev_node); | ||
2879 | spin_unlock(&se_device_lock); | ||
2880 | |||
2881 | dev_stat_grp = &se_dev->dev_stat_grps.stat_group; | 2870 | dev_stat_grp = &se_dev->dev_stat_grps.stat_group; |
2882 | for (i = 0; dev_stat_grp->default_groups[i]; i++) { | 2871 | for (i = 0; dev_stat_grp->default_groups[i]; i++) { |
2883 | df_item = &dev_stat_grp->default_groups[i]->cg_item; | 2872 | df_item = &dev_stat_grp->default_groups[i]->cg_item; |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index ba5edec2c5f8..9b8639425472 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -104,7 +104,6 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | |||
104 | se_cmd->se_lun = deve->se_lun; | 104 | se_cmd->se_lun = deve->se_lun; |
105 | se_cmd->pr_res_key = deve->pr_res_key; | 105 | se_cmd->pr_res_key = deve->pr_res_key; |
106 | se_cmd->orig_fe_lun = unpacked_lun; | 106 | se_cmd->orig_fe_lun = unpacked_lun; |
107 | se_cmd->se_orig_obj_ptr = se_cmd->se_lun->lun_se_dev; | ||
108 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; | 107 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; |
109 | } | 108 | } |
110 | spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); | 109 | spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); |
@@ -137,7 +136,6 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | |||
137 | se_lun = &se_sess->se_tpg->tpg_virt_lun0; | 136 | se_lun = &se_sess->se_tpg->tpg_virt_lun0; |
138 | se_cmd->se_lun = &se_sess->se_tpg->tpg_virt_lun0; | 137 | se_cmd->se_lun = &se_sess->se_tpg->tpg_virt_lun0; |
139 | se_cmd->orig_fe_lun = 0; | 138 | se_cmd->orig_fe_lun = 0; |
140 | se_cmd->se_orig_obj_ptr = se_cmd->se_lun->lun_se_dev; | ||
141 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; | 139 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; |
142 | } | 140 | } |
143 | /* | 141 | /* |
@@ -200,7 +198,6 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | |||
200 | se_lun = deve->se_lun; | 198 | se_lun = deve->se_lun; |
201 | se_cmd->pr_res_key = deve->pr_res_key; | 199 | se_cmd->pr_res_key = deve->pr_res_key; |
202 | se_cmd->orig_fe_lun = unpacked_lun; | 200 | se_cmd->orig_fe_lun = unpacked_lun; |
203 | se_cmd->se_orig_obj_ptr = se_cmd->se_dev; | ||
204 | } | 201 | } |
205 | spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); | 202 | spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); |
206 | 203 | ||
@@ -708,7 +705,7 @@ done: | |||
708 | 705 | ||
709 | se_task->task_scsi_status = GOOD; | 706 | se_task->task_scsi_status = GOOD; |
710 | transport_complete_task(se_task, 1); | 707 | transport_complete_task(se_task, 1); |
711 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 708 | return 0; |
712 | } | 709 | } |
713 | 710 | ||
714 | /* se_release_device_for_hba(): | 711 | /* se_release_device_for_hba(): |
@@ -957,8 +954,12 @@ int se_dev_set_emulate_dpo(struct se_device *dev, int flag) | |||
957 | return -EINVAL; | 954 | return -EINVAL; |
958 | } | 955 | } |
959 | 956 | ||
960 | pr_err("dpo_emulated not supported\n"); | 957 | if (flag) { |
961 | return -EINVAL; | 958 | pr_err("dpo_emulated not supported\n"); |
959 | return -EINVAL; | ||
960 | } | ||
961 | |||
962 | return 0; | ||
962 | } | 963 | } |
963 | 964 | ||
964 | int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) | 965 | int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) |
@@ -968,7 +969,7 @@ int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) | |||
968 | return -EINVAL; | 969 | return -EINVAL; |
969 | } | 970 | } |
970 | 971 | ||
971 | if (dev->transport->fua_write_emulated == 0) { | 972 | if (flag && dev->transport->fua_write_emulated == 0) { |
972 | pr_err("fua_write_emulated not supported\n"); | 973 | pr_err("fua_write_emulated not supported\n"); |
973 | return -EINVAL; | 974 | return -EINVAL; |
974 | } | 975 | } |
@@ -985,8 +986,12 @@ int se_dev_set_emulate_fua_read(struct se_device *dev, int flag) | |||
985 | return -EINVAL; | 986 | return -EINVAL; |
986 | } | 987 | } |
987 | 988 | ||
988 | pr_err("ua read emulated not supported\n"); | 989 | if (flag) { |
989 | return -EINVAL; | 990 | pr_err("ua read emulated not supported\n"); |
991 | return -EINVAL; | ||
992 | } | ||
993 | |||
994 | return 0; | ||
990 | } | 995 | } |
991 | 996 | ||
992 | int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) | 997 | int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) |
@@ -995,7 +1000,7 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) | |||
995 | pr_err("Illegal value %d\n", flag); | 1000 | pr_err("Illegal value %d\n", flag); |
996 | return -EINVAL; | 1001 | return -EINVAL; |
997 | } | 1002 | } |
998 | if (dev->transport->write_cache_emulated == 0) { | 1003 | if (flag && dev->transport->write_cache_emulated == 0) { |
999 | pr_err("write_cache_emulated not supported\n"); | 1004 | pr_err("write_cache_emulated not supported\n"); |
1000 | return -EINVAL; | 1005 | return -EINVAL; |
1001 | } | 1006 | } |
@@ -1056,7 +1061,7 @@ int se_dev_set_emulate_tpu(struct se_device *dev, int flag) | |||
1056 | * We expect this value to be non-zero when generic Block Layer | 1061 | * We expect this value to be non-zero when generic Block Layer |
1057 | * Discard supported is detected iblock_create_virtdevice(). | 1062 | * Discard supported is detected iblock_create_virtdevice(). |
1058 | */ | 1063 | */ |
1059 | if (!dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { | 1064 | if (flag && !dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { |
1060 | pr_err("Generic Block Discard not supported\n"); | 1065 | pr_err("Generic Block Discard not supported\n"); |
1061 | return -ENOSYS; | 1066 | return -ENOSYS; |
1062 | } | 1067 | } |
@@ -1077,7 +1082,7 @@ int se_dev_set_emulate_tpws(struct se_device *dev, int flag) | |||
1077 | * We expect this value to be non-zero when generic Block Layer | 1082 | * We expect this value to be non-zero when generic Block Layer |
1078 | * Discard supported is detected iblock_create_virtdevice(). | 1083 | * Discard supported is detected iblock_create_virtdevice(). |
1079 | */ | 1084 | */ |
1080 | if (!dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { | 1085 | if (flag && !dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { |
1081 | pr_err("Generic Block Discard not supported\n"); | 1086 | pr_err("Generic Block Discard not supported\n"); |
1082 | return -ENOSYS; | 1087 | return -ENOSYS; |
1083 | } | 1088 | } |
@@ -1587,7 +1592,6 @@ int core_dev_setup_virtual_lun0(void) | |||
1587 | ret = -ENOMEM; | 1592 | ret = -ENOMEM; |
1588 | goto out; | 1593 | goto out; |
1589 | } | 1594 | } |
1590 | INIT_LIST_HEAD(&se_dev->se_dev_node); | ||
1591 | INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list); | 1595 | INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list); |
1592 | spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock); | 1596 | spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock); |
1593 | INIT_LIST_HEAD(&se_dev->t10_pr.registration_list); | 1597 | INIT_LIST_HEAD(&se_dev->t10_pr.registration_list); |
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 67cd6fe05bfa..b4864fba4ef0 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c | |||
@@ -289,9 +289,9 @@ static int fd_do_readv(struct se_task *task) | |||
289 | return -ENOMEM; | 289 | return -ENOMEM; |
290 | } | 290 | } |
291 | 291 | ||
292 | for (i = 0; i < task->task_sg_nents; i++) { | 292 | for_each_sg(task->task_sg, sg, task->task_sg_nents, i) { |
293 | iov[i].iov_len = sg[i].length; | 293 | iov[i].iov_len = sg->length; |
294 | iov[i].iov_base = sg_virt(&sg[i]); | 294 | iov[i].iov_base = sg_virt(sg); |
295 | } | 295 | } |
296 | 296 | ||
297 | old_fs = get_fs(); | 297 | old_fs = get_fs(); |
@@ -342,9 +342,9 @@ static int fd_do_writev(struct se_task *task) | |||
342 | return -ENOMEM; | 342 | return -ENOMEM; |
343 | } | 343 | } |
344 | 344 | ||
345 | for (i = 0; i < task->task_sg_nents; i++) { | 345 | for_each_sg(task->task_sg, sg, task->task_sg_nents, i) { |
346 | iov[i].iov_len = sg[i].length; | 346 | iov[i].iov_len = sg->length; |
347 | iov[i].iov_base = sg_virt(&sg[i]); | 347 | iov[i].iov_base = sg_virt(sg); |
348 | } | 348 | } |
349 | 349 | ||
350 | old_fs = get_fs(); | 350 | old_fs = get_fs(); |
@@ -438,7 +438,7 @@ static int fd_do_task(struct se_task *task) | |||
438 | if (ret > 0 && | 438 | if (ret > 0 && |
439 | dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0 && | 439 | dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0 && |
440 | dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 && | 440 | dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 && |
441 | cmd->t_tasks_fua) { | 441 | (cmd->se_cmd_flags & SCF_FUA)) { |
442 | /* | 442 | /* |
443 | * We might need to be a bit smarter here | 443 | * We might need to be a bit smarter here |
444 | * and return some sense data to let the initiator | 444 | * and return some sense data to let the initiator |
@@ -449,13 +449,15 @@ static int fd_do_task(struct se_task *task) | |||
449 | 449 | ||
450 | } | 450 | } |
451 | 451 | ||
452 | if (ret < 0) | 452 | if (ret < 0) { |
453 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
453 | return ret; | 454 | return ret; |
455 | } | ||
454 | if (ret) { | 456 | if (ret) { |
455 | task->task_scsi_status = GOOD; | 457 | task->task_scsi_status = GOOD; |
456 | transport_complete_task(task, 1); | 458 | transport_complete_task(task, 1); |
457 | } | 459 | } |
458 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 460 | return 0; |
459 | } | 461 | } |
460 | 462 | ||
461 | /* fd_free_task(): (Part of se_subsystem_api_t template) | 463 | /* fd_free_task(): (Part of se_subsystem_api_t template) |
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 7698efe29262..4aa992204438 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
@@ -531,7 +531,7 @@ static int iblock_do_task(struct se_task *task) | |||
531 | */ | 531 | */ |
532 | if (dev->se_sub_dev->se_dev_attrib.emulate_write_cache == 0 || | 532 | if (dev->se_sub_dev->se_dev_attrib.emulate_write_cache == 0 || |
533 | (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 && | 533 | (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 && |
534 | task->task_se_cmd->t_tasks_fua)) | 534 | (cmd->se_cmd_flags & SCF_FUA))) |
535 | rw = WRITE_FUA; | 535 | rw = WRITE_FUA; |
536 | else | 536 | else |
537 | rw = WRITE; | 537 | rw = WRITE; |
@@ -554,12 +554,15 @@ static int iblock_do_task(struct se_task *task) | |||
554 | else { | 554 | else { |
555 | pr_err("Unsupported SCSI -> BLOCK LBA conversion:" | 555 | pr_err("Unsupported SCSI -> BLOCK LBA conversion:" |
556 | " %u\n", dev->se_sub_dev->se_dev_attrib.block_size); | 556 | " %u\n", dev->se_sub_dev->se_dev_attrib.block_size); |
557 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 557 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
558 | return -ENOSYS; | ||
558 | } | 559 | } |
559 | 560 | ||
560 | bio = iblock_get_bio(task, block_lba, sg_num); | 561 | bio = iblock_get_bio(task, block_lba, sg_num); |
561 | if (!bio) | 562 | if (!bio) { |
562 | return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; | 563 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
564 | return -ENOMEM; | ||
565 | } | ||
563 | 566 | ||
564 | bio_list_init(&list); | 567 | bio_list_init(&list); |
565 | bio_list_add(&list, bio); | 568 | bio_list_add(&list, bio); |
@@ -588,12 +591,13 @@ static int iblock_do_task(struct se_task *task) | |||
588 | submit_bio(rw, bio); | 591 | submit_bio(rw, bio); |
589 | blk_finish_plug(&plug); | 592 | blk_finish_plug(&plug); |
590 | 593 | ||
591 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 594 | return 0; |
592 | 595 | ||
593 | fail: | 596 | fail: |
594 | while ((bio = bio_list_pop(&list))) | 597 | while ((bio = bio_list_pop(&list))) |
595 | bio_put(bio); | 598 | bio_put(bio); |
596 | return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; | 599 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
600 | return -ENOMEM; | ||
597 | } | 601 | } |
598 | 602 | ||
599 | static u32 iblock_get_device_rev(struct se_device *dev) | 603 | static u32 iblock_get_device_rev(struct se_device *dev) |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 5a4ebfc3a54f..95dee7074aeb 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -191,7 +191,7 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) | |||
191 | pr_err("Received legacy SPC-2 RESERVE/RELEASE" | 191 | pr_err("Received legacy SPC-2 RESERVE/RELEASE" |
192 | " while active SPC-3 registrations exist," | 192 | " while active SPC-3 registrations exist," |
193 | " returning RESERVATION_CONFLICT\n"); | 193 | " returning RESERVATION_CONFLICT\n"); |
194 | *ret = PYX_TRANSPORT_RESERVATION_CONFLICT; | 194 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
195 | return true; | 195 | return true; |
196 | } | 196 | } |
197 | 197 | ||
@@ -252,7 +252,8 @@ int target_scsi2_reservation_reserve(struct se_task *task) | |||
252 | (cmd->t_task_cdb[1] & 0x02)) { | 252 | (cmd->t_task_cdb[1] & 0x02)) { |
253 | pr_err("LongIO and Obselete Bits set, returning" | 253 | pr_err("LongIO and Obselete Bits set, returning" |
254 | " ILLEGAL_REQUEST\n"); | 254 | " ILLEGAL_REQUEST\n"); |
255 | ret = PYX_TRANSPORT_ILLEGAL_REQUEST; | 255 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
256 | ret = -EINVAL; | ||
256 | goto out; | 257 | goto out; |
257 | } | 258 | } |
258 | /* | 259 | /* |
@@ -277,7 +278,8 @@ int target_scsi2_reservation_reserve(struct se_task *task) | |||
277 | " from %s \n", cmd->se_lun->unpacked_lun, | 278 | " from %s \n", cmd->se_lun->unpacked_lun, |
278 | cmd->se_deve->mapped_lun, | 279 | cmd->se_deve->mapped_lun, |
279 | sess->se_node_acl->initiatorname); | 280 | sess->se_node_acl->initiatorname); |
280 | ret = PYX_TRANSPORT_RESERVATION_CONFLICT; | 281 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
282 | ret = -EINVAL; | ||
281 | goto out_unlock; | 283 | goto out_unlock; |
282 | } | 284 | } |
283 | 285 | ||
@@ -1510,7 +1512,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1510 | tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL); | 1512 | tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL); |
1511 | if (!tidh_new) { | 1513 | if (!tidh_new) { |
1512 | pr_err("Unable to allocate tidh_new\n"); | 1514 | pr_err("Unable to allocate tidh_new\n"); |
1513 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 1515 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1516 | return -EINVAL; | ||
1514 | } | 1517 | } |
1515 | INIT_LIST_HEAD(&tidh_new->dest_list); | 1518 | INIT_LIST_HEAD(&tidh_new->dest_list); |
1516 | tidh_new->dest_tpg = tpg; | 1519 | tidh_new->dest_tpg = tpg; |
@@ -1522,7 +1525,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1522 | sa_res_key, all_tg_pt, aptpl); | 1525 | sa_res_key, all_tg_pt, aptpl); |
1523 | if (!local_pr_reg) { | 1526 | if (!local_pr_reg) { |
1524 | kfree(tidh_new); | 1527 | kfree(tidh_new); |
1525 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 1528 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1529 | return -ENOMEM; | ||
1526 | } | 1530 | } |
1527 | tidh_new->dest_pr_reg = local_pr_reg; | 1531 | tidh_new->dest_pr_reg = local_pr_reg; |
1528 | /* | 1532 | /* |
@@ -1548,7 +1552,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1548 | pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header" | 1552 | pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header" |
1549 | " does not equal CDB data_length: %u\n", tpdl, | 1553 | " does not equal CDB data_length: %u\n", tpdl, |
1550 | cmd->data_length); | 1554 | cmd->data_length); |
1551 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 1555 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
1556 | ret = -EINVAL; | ||
1552 | goto out; | 1557 | goto out; |
1553 | } | 1558 | } |
1554 | /* | 1559 | /* |
@@ -1598,7 +1603,9 @@ static int core_scsi3_decode_spec_i_port( | |||
1598 | " for tmp_tpg\n"); | 1603 | " for tmp_tpg\n"); |
1599 | atomic_dec(&tmp_tpg->tpg_pr_ref_count); | 1604 | atomic_dec(&tmp_tpg->tpg_pr_ref_count); |
1600 | smp_mb__after_atomic_dec(); | 1605 | smp_mb__after_atomic_dec(); |
1601 | ret = PYX_TRANSPORT_LU_COMM_FAILURE; | 1606 | cmd->scsi_sense_reason = |
1607 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1608 | ret = -EINVAL; | ||
1602 | goto out; | 1609 | goto out; |
1603 | } | 1610 | } |
1604 | /* | 1611 | /* |
@@ -1628,7 +1635,9 @@ static int core_scsi3_decode_spec_i_port( | |||
1628 | atomic_dec(&dest_node_acl->acl_pr_ref_count); | 1635 | atomic_dec(&dest_node_acl->acl_pr_ref_count); |
1629 | smp_mb__after_atomic_dec(); | 1636 | smp_mb__after_atomic_dec(); |
1630 | core_scsi3_tpg_undepend_item(tmp_tpg); | 1637 | core_scsi3_tpg_undepend_item(tmp_tpg); |
1631 | ret = PYX_TRANSPORT_LU_COMM_FAILURE; | 1638 | cmd->scsi_sense_reason = |
1639 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1640 | ret = -EINVAL; | ||
1632 | goto out; | 1641 | goto out; |
1633 | } | 1642 | } |
1634 | 1643 | ||
@@ -1646,7 +1655,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1646 | if (!dest_tpg) { | 1655 | if (!dest_tpg) { |
1647 | pr_err("SPC-3 PR SPEC_I_PT: Unable to locate" | 1656 | pr_err("SPC-3 PR SPEC_I_PT: Unable to locate" |
1648 | " dest_tpg\n"); | 1657 | " dest_tpg\n"); |
1649 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 1658 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
1659 | ret = -EINVAL; | ||
1650 | goto out; | 1660 | goto out; |
1651 | } | 1661 | } |
1652 | #if 0 | 1662 | #if 0 |
@@ -1660,7 +1670,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1660 | " %u for Transport ID: %s\n", tid_len, ptr); | 1670 | " %u for Transport ID: %s\n", tid_len, ptr); |
1661 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1671 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1662 | core_scsi3_tpg_undepend_item(dest_tpg); | 1672 | core_scsi3_tpg_undepend_item(dest_tpg); |
1663 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 1673 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
1674 | ret = -EINVAL; | ||
1664 | goto out; | 1675 | goto out; |
1665 | } | 1676 | } |
1666 | /* | 1677 | /* |
@@ -1678,7 +1689,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1678 | 1689 | ||
1679 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1690 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1680 | core_scsi3_tpg_undepend_item(dest_tpg); | 1691 | core_scsi3_tpg_undepend_item(dest_tpg); |
1681 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 1692 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
1693 | ret = -EINVAL; | ||
1682 | goto out; | 1694 | goto out; |
1683 | } | 1695 | } |
1684 | 1696 | ||
@@ -1690,7 +1702,9 @@ static int core_scsi3_decode_spec_i_port( | |||
1690 | smp_mb__after_atomic_dec(); | 1702 | smp_mb__after_atomic_dec(); |
1691 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1703 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1692 | core_scsi3_tpg_undepend_item(dest_tpg); | 1704 | core_scsi3_tpg_undepend_item(dest_tpg); |
1693 | ret = PYX_TRANSPORT_LU_COMM_FAILURE; | 1705 | cmd->scsi_sense_reason = |
1706 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1707 | ret = -EINVAL; | ||
1694 | goto out; | 1708 | goto out; |
1695 | } | 1709 | } |
1696 | #if 0 | 1710 | #if 0 |
@@ -1727,7 +1741,9 @@ static int core_scsi3_decode_spec_i_port( | |||
1727 | core_scsi3_lunacl_undepend_item(dest_se_deve); | 1741 | core_scsi3_lunacl_undepend_item(dest_se_deve); |
1728 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1742 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1729 | core_scsi3_tpg_undepend_item(dest_tpg); | 1743 | core_scsi3_tpg_undepend_item(dest_tpg); |
1730 | ret = PYX_TRANSPORT_LU_COMM_FAILURE; | 1744 | cmd->scsi_sense_reason = |
1745 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1746 | ret = -ENOMEM; | ||
1731 | goto out; | 1747 | goto out; |
1732 | } | 1748 | } |
1733 | INIT_LIST_HEAD(&tidh_new->dest_list); | 1749 | INIT_LIST_HEAD(&tidh_new->dest_list); |
@@ -1759,7 +1775,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1759 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1775 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1760 | core_scsi3_tpg_undepend_item(dest_tpg); | 1776 | core_scsi3_tpg_undepend_item(dest_tpg); |
1761 | kfree(tidh_new); | 1777 | kfree(tidh_new); |
1762 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 1778 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
1779 | ret = -EINVAL; | ||
1763 | goto out; | 1780 | goto out; |
1764 | } | 1781 | } |
1765 | tidh_new->dest_pr_reg = dest_pr_reg; | 1782 | tidh_new->dest_pr_reg = dest_pr_reg; |
@@ -2098,7 +2115,8 @@ static int core_scsi3_emulate_pro_register( | |||
2098 | 2115 | ||
2099 | if (!se_sess || !se_lun) { | 2116 | if (!se_sess || !se_lun) { |
2100 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 2117 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
2101 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 2118 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2119 | return -EINVAL; | ||
2102 | } | 2120 | } |
2103 | se_tpg = se_sess->se_tpg; | 2121 | se_tpg = se_sess->se_tpg; |
2104 | se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; | 2122 | se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; |
@@ -2117,13 +2135,14 @@ static int core_scsi3_emulate_pro_register( | |||
2117 | if (res_key) { | 2135 | if (res_key) { |
2118 | pr_warn("SPC-3 PR: Reservation Key non-zero" | 2136 | pr_warn("SPC-3 PR: Reservation Key non-zero" |
2119 | " for SA REGISTER, returning CONFLICT\n"); | 2137 | " for SA REGISTER, returning CONFLICT\n"); |
2120 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2138 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2139 | return -EINVAL; | ||
2121 | } | 2140 | } |
2122 | /* | 2141 | /* |
2123 | * Do nothing but return GOOD status. | 2142 | * Do nothing but return GOOD status. |
2124 | */ | 2143 | */ |
2125 | if (!sa_res_key) | 2144 | if (!sa_res_key) |
2126 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 2145 | return 0; |
2127 | 2146 | ||
2128 | if (!spec_i_pt) { | 2147 | if (!spec_i_pt) { |
2129 | /* | 2148 | /* |
@@ -2138,7 +2157,8 @@ static int core_scsi3_emulate_pro_register( | |||
2138 | if (ret != 0) { | 2157 | if (ret != 0) { |
2139 | pr_err("Unable to allocate" | 2158 | pr_err("Unable to allocate" |
2140 | " struct t10_pr_registration\n"); | 2159 | " struct t10_pr_registration\n"); |
2141 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 2160 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
2161 | return -EINVAL; | ||
2142 | } | 2162 | } |
2143 | } else { | 2163 | } else { |
2144 | /* | 2164 | /* |
@@ -2197,14 +2217,16 @@ static int core_scsi3_emulate_pro_register( | |||
2197 | " 0x%016Lx\n", res_key, | 2217 | " 0x%016Lx\n", res_key, |
2198 | pr_reg->pr_res_key); | 2218 | pr_reg->pr_res_key); |
2199 | core_scsi3_put_pr_reg(pr_reg); | 2219 | core_scsi3_put_pr_reg(pr_reg); |
2200 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2220 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2221 | return -EINVAL; | ||
2201 | } | 2222 | } |
2202 | } | 2223 | } |
2203 | if (spec_i_pt) { | 2224 | if (spec_i_pt) { |
2204 | pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT" | 2225 | pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT" |
2205 | " set while sa_res_key=0\n"); | 2226 | " set while sa_res_key=0\n"); |
2206 | core_scsi3_put_pr_reg(pr_reg); | 2227 | core_scsi3_put_pr_reg(pr_reg); |
2207 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 2228 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
2229 | return -EINVAL; | ||
2208 | } | 2230 | } |
2209 | /* | 2231 | /* |
2210 | * An existing ALL_TG_PT=1 registration being released | 2232 | * An existing ALL_TG_PT=1 registration being released |
@@ -2215,7 +2237,8 @@ static int core_scsi3_emulate_pro_register( | |||
2215 | " registration exists, but ALL_TG_PT=1 bit not" | 2237 | " registration exists, but ALL_TG_PT=1 bit not" |
2216 | " present in received PROUT\n"); | 2238 | " present in received PROUT\n"); |
2217 | core_scsi3_put_pr_reg(pr_reg); | 2239 | core_scsi3_put_pr_reg(pr_reg); |
2218 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 2240 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
2241 | return -EINVAL; | ||
2219 | } | 2242 | } |
2220 | /* | 2243 | /* |
2221 | * Allocate APTPL metadata buffer used for UNREGISTER ops | 2244 | * Allocate APTPL metadata buffer used for UNREGISTER ops |
@@ -2227,7 +2250,9 @@ static int core_scsi3_emulate_pro_register( | |||
2227 | pr_err("Unable to allocate" | 2250 | pr_err("Unable to allocate" |
2228 | " pr_aptpl_buf\n"); | 2251 | " pr_aptpl_buf\n"); |
2229 | core_scsi3_put_pr_reg(pr_reg); | 2252 | core_scsi3_put_pr_reg(pr_reg); |
2230 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 2253 | cmd->scsi_sense_reason = |
2254 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2255 | return -EINVAL; | ||
2231 | } | 2256 | } |
2232 | } | 2257 | } |
2233 | /* | 2258 | /* |
@@ -2241,7 +2266,8 @@ static int core_scsi3_emulate_pro_register( | |||
2241 | if (pr_holder < 0) { | 2266 | if (pr_holder < 0) { |
2242 | kfree(pr_aptpl_buf); | 2267 | kfree(pr_aptpl_buf); |
2243 | core_scsi3_put_pr_reg(pr_reg); | 2268 | core_scsi3_put_pr_reg(pr_reg); |
2244 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2269 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2270 | return -EINVAL; | ||
2245 | } | 2271 | } |
2246 | 2272 | ||
2247 | spin_lock(&pr_tmpl->registration_lock); | 2273 | spin_lock(&pr_tmpl->registration_lock); |
@@ -2405,7 +2431,8 @@ static int core_scsi3_pro_reserve( | |||
2405 | 2431 | ||
2406 | if (!se_sess || !se_lun) { | 2432 | if (!se_sess || !se_lun) { |
2407 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 2433 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
2408 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 2434 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2435 | return -EINVAL; | ||
2409 | } | 2436 | } |
2410 | se_tpg = se_sess->se_tpg; | 2437 | se_tpg = se_sess->se_tpg; |
2411 | se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; | 2438 | se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; |
@@ -2417,7 +2444,8 @@ static int core_scsi3_pro_reserve( | |||
2417 | if (!pr_reg) { | 2444 | if (!pr_reg) { |
2418 | pr_err("SPC-3 PR: Unable to locate" | 2445 | pr_err("SPC-3 PR: Unable to locate" |
2419 | " PR_REGISTERED *pr_reg for RESERVE\n"); | 2446 | " PR_REGISTERED *pr_reg for RESERVE\n"); |
2420 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 2447 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2448 | return -EINVAL; | ||
2421 | } | 2449 | } |
2422 | /* | 2450 | /* |
2423 | * From spc4r17 Section 5.7.9: Reserving: | 2451 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2433,7 +2461,8 @@ static int core_scsi3_pro_reserve( | |||
2433 | " does not match existing SA REGISTER res_key:" | 2461 | " does not match existing SA REGISTER res_key:" |
2434 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); | 2462 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); |
2435 | core_scsi3_put_pr_reg(pr_reg); | 2463 | core_scsi3_put_pr_reg(pr_reg); |
2436 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2464 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2465 | return -EINVAL; | ||
2437 | } | 2466 | } |
2438 | /* | 2467 | /* |
2439 | * From spc4r17 Section 5.7.9: Reserving: | 2468 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2448,7 +2477,8 @@ static int core_scsi3_pro_reserve( | |||
2448 | if (scope != PR_SCOPE_LU_SCOPE) { | 2477 | if (scope != PR_SCOPE_LU_SCOPE) { |
2449 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); | 2478 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); |
2450 | core_scsi3_put_pr_reg(pr_reg); | 2479 | core_scsi3_put_pr_reg(pr_reg); |
2451 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 2480 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
2481 | return -EINVAL; | ||
2452 | } | 2482 | } |
2453 | /* | 2483 | /* |
2454 | * See if we have an existing PR reservation holder pointer at | 2484 | * See if we have an existing PR reservation holder pointer at |
@@ -2480,7 +2510,8 @@ static int core_scsi3_pro_reserve( | |||
2480 | 2510 | ||
2481 | spin_unlock(&dev->dev_reservation_lock); | 2511 | spin_unlock(&dev->dev_reservation_lock); |
2482 | core_scsi3_put_pr_reg(pr_reg); | 2512 | core_scsi3_put_pr_reg(pr_reg); |
2483 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2513 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2514 | return -EINVAL; | ||
2484 | } | 2515 | } |
2485 | /* | 2516 | /* |
2486 | * From spc4r17 Section 5.7.9: Reserving: | 2517 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2503,7 +2534,8 @@ static int core_scsi3_pro_reserve( | |||
2503 | 2534 | ||
2504 | spin_unlock(&dev->dev_reservation_lock); | 2535 | spin_unlock(&dev->dev_reservation_lock); |
2505 | core_scsi3_put_pr_reg(pr_reg); | 2536 | core_scsi3_put_pr_reg(pr_reg); |
2506 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2537 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2538 | return -EINVAL; | ||
2507 | } | 2539 | } |
2508 | /* | 2540 | /* |
2509 | * From spc4r17 Section 5.7.9: Reserving: | 2541 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2517,7 +2549,7 @@ static int core_scsi3_pro_reserve( | |||
2517 | */ | 2549 | */ |
2518 | spin_unlock(&dev->dev_reservation_lock); | 2550 | spin_unlock(&dev->dev_reservation_lock); |
2519 | core_scsi3_put_pr_reg(pr_reg); | 2551 | core_scsi3_put_pr_reg(pr_reg); |
2520 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 2552 | return 0; |
2521 | } | 2553 | } |
2522 | /* | 2554 | /* |
2523 | * Otherwise, our *pr_reg becomes the PR reservation holder for said | 2555 | * Otherwise, our *pr_reg becomes the PR reservation holder for said |
@@ -2574,7 +2606,8 @@ static int core_scsi3_emulate_pro_reserve( | |||
2574 | default: | 2606 | default: |
2575 | pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:" | 2607 | pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:" |
2576 | " 0x%02x\n", type); | 2608 | " 0x%02x\n", type); |
2577 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 2609 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
2610 | return -EINVAL; | ||
2578 | } | 2611 | } |
2579 | 2612 | ||
2580 | return ret; | 2613 | return ret; |
@@ -2630,7 +2663,8 @@ static int core_scsi3_emulate_pro_release( | |||
2630 | 2663 | ||
2631 | if (!se_sess || !se_lun) { | 2664 | if (!se_sess || !se_lun) { |
2632 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 2665 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
2633 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 2666 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2667 | return -EINVAL; | ||
2634 | } | 2668 | } |
2635 | /* | 2669 | /* |
2636 | * Locate the existing *pr_reg via struct se_node_acl pointers | 2670 | * Locate the existing *pr_reg via struct se_node_acl pointers |
@@ -2639,7 +2673,8 @@ static int core_scsi3_emulate_pro_release( | |||
2639 | if (!pr_reg) { | 2673 | if (!pr_reg) { |
2640 | pr_err("SPC-3 PR: Unable to locate" | 2674 | pr_err("SPC-3 PR: Unable to locate" |
2641 | " PR_REGISTERED *pr_reg for RELEASE\n"); | 2675 | " PR_REGISTERED *pr_reg for RELEASE\n"); |
2642 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 2676 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2677 | return -EINVAL; | ||
2643 | } | 2678 | } |
2644 | /* | 2679 | /* |
2645 | * From spc4r17 Section 5.7.11.2 Releasing: | 2680 | * From spc4r17 Section 5.7.11.2 Releasing: |
@@ -2661,7 +2696,7 @@ static int core_scsi3_emulate_pro_release( | |||
2661 | */ | 2696 | */ |
2662 | spin_unlock(&dev->dev_reservation_lock); | 2697 | spin_unlock(&dev->dev_reservation_lock); |
2663 | core_scsi3_put_pr_reg(pr_reg); | 2698 | core_scsi3_put_pr_reg(pr_reg); |
2664 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 2699 | return 0; |
2665 | } | 2700 | } |
2666 | if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || | 2701 | if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || |
2667 | (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) | 2702 | (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) |
@@ -2675,7 +2710,7 @@ static int core_scsi3_emulate_pro_release( | |||
2675 | */ | 2710 | */ |
2676 | spin_unlock(&dev->dev_reservation_lock); | 2711 | spin_unlock(&dev->dev_reservation_lock); |
2677 | core_scsi3_put_pr_reg(pr_reg); | 2712 | core_scsi3_put_pr_reg(pr_reg); |
2678 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 2713 | return 0; |
2679 | } | 2714 | } |
2680 | /* | 2715 | /* |
2681 | * From spc4r17 Section 5.7.11.2 Releasing: | 2716 | * From spc4r17 Section 5.7.11.2 Releasing: |
@@ -2697,7 +2732,8 @@ static int core_scsi3_emulate_pro_release( | |||
2697 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); | 2732 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); |
2698 | spin_unlock(&dev->dev_reservation_lock); | 2733 | spin_unlock(&dev->dev_reservation_lock); |
2699 | core_scsi3_put_pr_reg(pr_reg); | 2734 | core_scsi3_put_pr_reg(pr_reg); |
2700 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2735 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2736 | return -EINVAL; | ||
2701 | } | 2737 | } |
2702 | /* | 2738 | /* |
2703 | * From spc4r17 Section 5.7.11.2 Releasing and above: | 2739 | * From spc4r17 Section 5.7.11.2 Releasing and above: |
@@ -2719,7 +2755,8 @@ static int core_scsi3_emulate_pro_release( | |||
2719 | 2755 | ||
2720 | spin_unlock(&dev->dev_reservation_lock); | 2756 | spin_unlock(&dev->dev_reservation_lock); |
2721 | core_scsi3_put_pr_reg(pr_reg); | 2757 | core_scsi3_put_pr_reg(pr_reg); |
2722 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2758 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2759 | return -EINVAL; | ||
2723 | } | 2760 | } |
2724 | /* | 2761 | /* |
2725 | * In response to a persistent reservation release request from the | 2762 | * In response to a persistent reservation release request from the |
@@ -2802,7 +2839,8 @@ static int core_scsi3_emulate_pro_clear( | |||
2802 | if (!pr_reg_n) { | 2839 | if (!pr_reg_n) { |
2803 | pr_err("SPC-3 PR: Unable to locate" | 2840 | pr_err("SPC-3 PR: Unable to locate" |
2804 | " PR_REGISTERED *pr_reg for CLEAR\n"); | 2841 | " PR_REGISTERED *pr_reg for CLEAR\n"); |
2805 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 2842 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2843 | return -EINVAL; | ||
2806 | } | 2844 | } |
2807 | /* | 2845 | /* |
2808 | * From spc4r17 section 5.7.11.6, Clearing: | 2846 | * From spc4r17 section 5.7.11.6, Clearing: |
@@ -2821,7 +2859,8 @@ static int core_scsi3_emulate_pro_clear( | |||
2821 | " existing SA REGISTER res_key:" | 2859 | " existing SA REGISTER res_key:" |
2822 | " 0x%016Lx\n", res_key, pr_reg_n->pr_res_key); | 2860 | " 0x%016Lx\n", res_key, pr_reg_n->pr_res_key); |
2823 | core_scsi3_put_pr_reg(pr_reg_n); | 2861 | core_scsi3_put_pr_reg(pr_reg_n); |
2824 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2862 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2863 | return -EINVAL; | ||
2825 | } | 2864 | } |
2826 | /* | 2865 | /* |
2827 | * a) Release the persistent reservation, if any; | 2866 | * a) Release the persistent reservation, if any; |
@@ -2979,8 +3018,10 @@ static int core_scsi3_pro_preempt( | |||
2979 | int all_reg = 0, calling_it_nexus = 0, released_regs = 0; | 3018 | int all_reg = 0, calling_it_nexus = 0, released_regs = 0; |
2980 | int prh_type = 0, prh_scope = 0, ret; | 3019 | int prh_type = 0, prh_scope = 0, ret; |
2981 | 3020 | ||
2982 | if (!se_sess) | 3021 | if (!se_sess) { |
2983 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 3022 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3023 | return -EINVAL; | ||
3024 | } | ||
2984 | 3025 | ||
2985 | se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; | 3026 | se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; |
2986 | pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, | 3027 | pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, |
@@ -2989,16 +3030,19 @@ static int core_scsi3_pro_preempt( | |||
2989 | pr_err("SPC-3 PR: Unable to locate" | 3030 | pr_err("SPC-3 PR: Unable to locate" |
2990 | " PR_REGISTERED *pr_reg for PREEMPT%s\n", | 3031 | " PR_REGISTERED *pr_reg for PREEMPT%s\n", |
2991 | (abort) ? "_AND_ABORT" : ""); | 3032 | (abort) ? "_AND_ABORT" : ""); |
2992 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 3033 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
3034 | return -EINVAL; | ||
2993 | } | 3035 | } |
2994 | if (pr_reg_n->pr_res_key != res_key) { | 3036 | if (pr_reg_n->pr_res_key != res_key) { |
2995 | core_scsi3_put_pr_reg(pr_reg_n); | 3037 | core_scsi3_put_pr_reg(pr_reg_n); |
2996 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 3038 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
3039 | return -EINVAL; | ||
2997 | } | 3040 | } |
2998 | if (scope != PR_SCOPE_LU_SCOPE) { | 3041 | if (scope != PR_SCOPE_LU_SCOPE) { |
2999 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); | 3042 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); |
3000 | core_scsi3_put_pr_reg(pr_reg_n); | 3043 | core_scsi3_put_pr_reg(pr_reg_n); |
3001 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3044 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3045 | return -EINVAL; | ||
3002 | } | 3046 | } |
3003 | INIT_LIST_HEAD(&preempt_and_abort_list); | 3047 | INIT_LIST_HEAD(&preempt_and_abort_list); |
3004 | 3048 | ||
@@ -3012,7 +3056,8 @@ static int core_scsi3_pro_preempt( | |||
3012 | if (!all_reg && !sa_res_key) { | 3056 | if (!all_reg && !sa_res_key) { |
3013 | spin_unlock(&dev->dev_reservation_lock); | 3057 | spin_unlock(&dev->dev_reservation_lock); |
3014 | core_scsi3_put_pr_reg(pr_reg_n); | 3058 | core_scsi3_put_pr_reg(pr_reg_n); |
3015 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3059 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3060 | return -EINVAL; | ||
3016 | } | 3061 | } |
3017 | /* | 3062 | /* |
3018 | * From spc4r17, section 5.7.11.4.4 Removing Registrations: | 3063 | * From spc4r17, section 5.7.11.4.4 Removing Registrations: |
@@ -3106,7 +3151,8 @@ static int core_scsi3_pro_preempt( | |||
3106 | if (!released_regs) { | 3151 | if (!released_regs) { |
3107 | spin_unlock(&dev->dev_reservation_lock); | 3152 | spin_unlock(&dev->dev_reservation_lock); |
3108 | core_scsi3_put_pr_reg(pr_reg_n); | 3153 | core_scsi3_put_pr_reg(pr_reg_n); |
3109 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 3154 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
3155 | return -EINVAL; | ||
3110 | } | 3156 | } |
3111 | /* | 3157 | /* |
3112 | * For an existing all registrants type reservation | 3158 | * For an existing all registrants type reservation |
@@ -3297,7 +3343,8 @@ static int core_scsi3_emulate_pro_preempt( | |||
3297 | default: | 3343 | default: |
3298 | pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s" | 3344 | pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s" |
3299 | " Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type); | 3345 | " Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type); |
3300 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 3346 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
3347 | return -EINVAL; | ||
3301 | } | 3348 | } |
3302 | 3349 | ||
3303 | return ret; | 3350 | return ret; |
@@ -3331,7 +3378,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3331 | 3378 | ||
3332 | if (!se_sess || !se_lun) { | 3379 | if (!se_sess || !se_lun) { |
3333 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 3380 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
3334 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 3381 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3382 | return -EINVAL; | ||
3335 | } | 3383 | } |
3336 | memset(dest_iport, 0, 64); | 3384 | memset(dest_iport, 0, 64); |
3337 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 3385 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
@@ -3349,7 +3397,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3349 | if (!pr_reg) { | 3397 | if (!pr_reg) { |
3350 | pr_err("SPC-3 PR: Unable to locate PR_REGISTERED" | 3398 | pr_err("SPC-3 PR: Unable to locate PR_REGISTERED" |
3351 | " *pr_reg for REGISTER_AND_MOVE\n"); | 3399 | " *pr_reg for REGISTER_AND_MOVE\n"); |
3352 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 3400 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3401 | return -EINVAL; | ||
3353 | } | 3402 | } |
3354 | /* | 3403 | /* |
3355 | * The provided reservation key much match the existing reservation key | 3404 | * The provided reservation key much match the existing reservation key |
@@ -3360,7 +3409,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3360 | " res_key: 0x%016Lx does not match existing SA REGISTER" | 3409 | " res_key: 0x%016Lx does not match existing SA REGISTER" |
3361 | " res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key); | 3410 | " res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key); |
3362 | core_scsi3_put_pr_reg(pr_reg); | 3411 | core_scsi3_put_pr_reg(pr_reg); |
3363 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 3412 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
3413 | return -EINVAL; | ||
3364 | } | 3414 | } |
3365 | /* | 3415 | /* |
3366 | * The service active reservation key needs to be non zero | 3416 | * The service active reservation key needs to be non zero |
@@ -3369,7 +3419,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3369 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero" | 3419 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero" |
3370 | " sa_res_key\n"); | 3420 | " sa_res_key\n"); |
3371 | core_scsi3_put_pr_reg(pr_reg); | 3421 | core_scsi3_put_pr_reg(pr_reg); |
3372 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3422 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3423 | return -EINVAL; | ||
3373 | } | 3424 | } |
3374 | 3425 | ||
3375 | /* | 3426 | /* |
@@ -3392,7 +3443,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3392 | " does not equal CDB data_length: %u\n", tid_len, | 3443 | " does not equal CDB data_length: %u\n", tid_len, |
3393 | cmd->data_length); | 3444 | cmd->data_length); |
3394 | core_scsi3_put_pr_reg(pr_reg); | 3445 | core_scsi3_put_pr_reg(pr_reg); |
3395 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3446 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3447 | return -EINVAL; | ||
3396 | } | 3448 | } |
3397 | 3449 | ||
3398 | spin_lock(&dev->se_port_lock); | 3450 | spin_lock(&dev->se_port_lock); |
@@ -3417,7 +3469,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3417 | atomic_dec(&dest_se_tpg->tpg_pr_ref_count); | 3469 | atomic_dec(&dest_se_tpg->tpg_pr_ref_count); |
3418 | smp_mb__after_atomic_dec(); | 3470 | smp_mb__after_atomic_dec(); |
3419 | core_scsi3_put_pr_reg(pr_reg); | 3471 | core_scsi3_put_pr_reg(pr_reg); |
3420 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 3472 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3473 | return -EINVAL; | ||
3421 | } | 3474 | } |
3422 | 3475 | ||
3423 | spin_lock(&dev->se_port_lock); | 3476 | spin_lock(&dev->se_port_lock); |
@@ -3430,7 +3483,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3430 | " fabric ops from Relative Target Port Identifier:" | 3483 | " fabric ops from Relative Target Port Identifier:" |
3431 | " %hu\n", rtpi); | 3484 | " %hu\n", rtpi); |
3432 | core_scsi3_put_pr_reg(pr_reg); | 3485 | core_scsi3_put_pr_reg(pr_reg); |
3433 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3486 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3487 | return -EINVAL; | ||
3434 | } | 3488 | } |
3435 | 3489 | ||
3436 | buf = transport_kmap_first_data_page(cmd); | 3490 | buf = transport_kmap_first_data_page(cmd); |
@@ -3445,14 +3499,16 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3445 | " from fabric: %s\n", proto_ident, | 3499 | " from fabric: %s\n", proto_ident, |
3446 | dest_tf_ops->get_fabric_proto_ident(dest_se_tpg), | 3500 | dest_tf_ops->get_fabric_proto_ident(dest_se_tpg), |
3447 | dest_tf_ops->get_fabric_name()); | 3501 | dest_tf_ops->get_fabric_name()); |
3448 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3502 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3503 | ret = -EINVAL; | ||
3449 | goto out; | 3504 | goto out; |
3450 | } | 3505 | } |
3451 | if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) { | 3506 | if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) { |
3452 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not" | 3507 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not" |
3453 | " containg a valid tpg_parse_pr_out_transport_id" | 3508 | " containg a valid tpg_parse_pr_out_transport_id" |
3454 | " function pointer\n"); | 3509 | " function pointer\n"); |
3455 | ret = PYX_TRANSPORT_LU_COMM_FAILURE; | 3510 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3511 | ret = -EINVAL; | ||
3456 | goto out; | 3512 | goto out; |
3457 | } | 3513 | } |
3458 | initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg, | 3514 | initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg, |
@@ -3460,7 +3516,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3460 | if (!initiator_str) { | 3516 | if (!initiator_str) { |
3461 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" | 3517 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" |
3462 | " initiator_str from Transport ID\n"); | 3518 | " initiator_str from Transport ID\n"); |
3463 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3519 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3520 | ret = -EINVAL; | ||
3464 | goto out; | 3521 | goto out; |
3465 | } | 3522 | } |
3466 | 3523 | ||
@@ -3489,7 +3546,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3489 | pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s" | 3546 | pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s" |
3490 | " matches: %s on received I_T Nexus\n", initiator_str, | 3547 | " matches: %s on received I_T Nexus\n", initiator_str, |
3491 | pr_reg_nacl->initiatorname); | 3548 | pr_reg_nacl->initiatorname); |
3492 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3549 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3550 | ret = -EINVAL; | ||
3493 | goto out; | 3551 | goto out; |
3494 | } | 3552 | } |
3495 | if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) { | 3553 | if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) { |
@@ -3497,7 +3555,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3497 | " matches: %s %s on received I_T Nexus\n", | 3555 | " matches: %s %s on received I_T Nexus\n", |
3498 | initiator_str, iport_ptr, pr_reg_nacl->initiatorname, | 3556 | initiator_str, iport_ptr, pr_reg_nacl->initiatorname, |
3499 | pr_reg->pr_reg_isid); | 3557 | pr_reg->pr_reg_isid); |
3500 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3558 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3559 | ret = -EINVAL; | ||
3501 | goto out; | 3560 | goto out; |
3502 | } | 3561 | } |
3503 | after_iport_check: | 3562 | after_iport_check: |
@@ -3517,7 +3576,8 @@ after_iport_check: | |||
3517 | pr_err("Unable to locate %s dest_node_acl for" | 3576 | pr_err("Unable to locate %s dest_node_acl for" |
3518 | " TransportID%s\n", dest_tf_ops->get_fabric_name(), | 3577 | " TransportID%s\n", dest_tf_ops->get_fabric_name(), |
3519 | initiator_str); | 3578 | initiator_str); |
3520 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3579 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3580 | ret = -EINVAL; | ||
3521 | goto out; | 3581 | goto out; |
3522 | } | 3582 | } |
3523 | ret = core_scsi3_nodeacl_depend_item(dest_node_acl); | 3583 | ret = core_scsi3_nodeacl_depend_item(dest_node_acl); |
@@ -3527,7 +3587,8 @@ after_iport_check: | |||
3527 | atomic_dec(&dest_node_acl->acl_pr_ref_count); | 3587 | atomic_dec(&dest_node_acl->acl_pr_ref_count); |
3528 | smp_mb__after_atomic_dec(); | 3588 | smp_mb__after_atomic_dec(); |
3529 | dest_node_acl = NULL; | 3589 | dest_node_acl = NULL; |
3530 | ret = PYX_TRANSPORT_LU_COMM_FAILURE; | 3590 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3591 | ret = -EINVAL; | ||
3531 | goto out; | 3592 | goto out; |
3532 | } | 3593 | } |
3533 | #if 0 | 3594 | #if 0 |
@@ -3543,7 +3604,8 @@ after_iport_check: | |||
3543 | if (!dest_se_deve) { | 3604 | if (!dest_se_deve) { |
3544 | pr_err("Unable to locate %s dest_se_deve from RTPI:" | 3605 | pr_err("Unable to locate %s dest_se_deve from RTPI:" |
3545 | " %hu\n", dest_tf_ops->get_fabric_name(), rtpi); | 3606 | " %hu\n", dest_tf_ops->get_fabric_name(), rtpi); |
3546 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3607 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3608 | ret = -EINVAL; | ||
3547 | goto out; | 3609 | goto out; |
3548 | } | 3610 | } |
3549 | 3611 | ||
@@ -3553,7 +3615,8 @@ after_iport_check: | |||
3553 | atomic_dec(&dest_se_deve->pr_ref_count); | 3615 | atomic_dec(&dest_se_deve->pr_ref_count); |
3554 | smp_mb__after_atomic_dec(); | 3616 | smp_mb__after_atomic_dec(); |
3555 | dest_se_deve = NULL; | 3617 | dest_se_deve = NULL; |
3556 | ret = PYX_TRANSPORT_LU_COMM_FAILURE; | 3618 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3619 | ret = -EINVAL; | ||
3557 | goto out; | 3620 | goto out; |
3558 | } | 3621 | } |
3559 | #if 0 | 3622 | #if 0 |
@@ -3572,7 +3635,8 @@ after_iport_check: | |||
3572 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation" | 3635 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation" |
3573 | " currently held\n"); | 3636 | " currently held\n"); |
3574 | spin_unlock(&dev->dev_reservation_lock); | 3637 | spin_unlock(&dev->dev_reservation_lock); |
3575 | ret = PYX_TRANSPORT_INVALID_CDB_FIELD; | 3638 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
3639 | ret = -EINVAL; | ||
3576 | goto out; | 3640 | goto out; |
3577 | } | 3641 | } |
3578 | /* | 3642 | /* |
@@ -3585,7 +3649,8 @@ after_iport_check: | |||
3585 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T" | 3649 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T" |
3586 | " Nexus is not reservation holder\n"); | 3650 | " Nexus is not reservation holder\n"); |
3587 | spin_unlock(&dev->dev_reservation_lock); | 3651 | spin_unlock(&dev->dev_reservation_lock); |
3588 | ret = PYX_TRANSPORT_RESERVATION_CONFLICT; | 3652 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
3653 | ret = -EINVAL; | ||
3589 | goto out; | 3654 | goto out; |
3590 | } | 3655 | } |
3591 | /* | 3656 | /* |
@@ -3603,7 +3668,8 @@ after_iport_check: | |||
3603 | " reservation for type: %s\n", | 3668 | " reservation for type: %s\n", |
3604 | core_scsi3_pr_dump_type(pr_res_holder->pr_res_type)); | 3669 | core_scsi3_pr_dump_type(pr_res_holder->pr_res_type)); |
3605 | spin_unlock(&dev->dev_reservation_lock); | 3670 | spin_unlock(&dev->dev_reservation_lock); |
3606 | ret = PYX_TRANSPORT_RESERVATION_CONFLICT; | 3671 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
3672 | ret = -EINVAL; | ||
3607 | goto out; | 3673 | goto out; |
3608 | } | 3674 | } |
3609 | pr_res_nacl = pr_res_holder->pr_reg_nacl; | 3675 | pr_res_nacl = pr_res_holder->pr_reg_nacl; |
@@ -3640,7 +3706,8 @@ after_iport_check: | |||
3640 | sa_res_key, 0, aptpl, 2, 1); | 3706 | sa_res_key, 0, aptpl, 2, 1); |
3641 | if (ret != 0) { | 3707 | if (ret != 0) { |
3642 | spin_unlock(&dev->dev_reservation_lock); | 3708 | spin_unlock(&dev->dev_reservation_lock); |
3643 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3709 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3710 | ret = -EINVAL; | ||
3644 | goto out; | 3711 | goto out; |
3645 | } | 3712 | } |
3646 | dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, | 3713 | dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, |
@@ -3771,7 +3838,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3771 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" | 3838 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" |
3772 | " SPC-2 reservation is held, returning" | 3839 | " SPC-2 reservation is held, returning" |
3773 | " RESERVATION_CONFLICT\n"); | 3840 | " RESERVATION_CONFLICT\n"); |
3774 | ret = PYX_TRANSPORT_RESERVATION_CONFLICT; | 3841 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
3842 | ret = EINVAL; | ||
3775 | goto out; | 3843 | goto out; |
3776 | } | 3844 | } |
3777 | 3845 | ||
@@ -3779,13 +3847,16 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3779 | * FIXME: A NULL struct se_session pointer means an this is not coming from | 3847 | * FIXME: A NULL struct se_session pointer means an this is not coming from |
3780 | * a $FABRIC_MOD's nexus, but from internal passthrough ops. | 3848 | * a $FABRIC_MOD's nexus, but from internal passthrough ops. |
3781 | */ | 3849 | */ |
3782 | if (!cmd->se_sess) | 3850 | if (!cmd->se_sess) { |
3783 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 3851 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3852 | return -EINVAL; | ||
3853 | } | ||
3784 | 3854 | ||
3785 | if (cmd->data_length < 24) { | 3855 | if (cmd->data_length < 24) { |
3786 | pr_warn("SPC-PR: Received PR OUT parameter list" | 3856 | pr_warn("SPC-PR: Received PR OUT parameter list" |
3787 | " length too small: %u\n", cmd->data_length); | 3857 | " length too small: %u\n", cmd->data_length); |
3788 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3858 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3859 | ret = -EINVAL; | ||
3789 | goto out; | 3860 | goto out; |
3790 | } | 3861 | } |
3791 | /* | 3862 | /* |
@@ -3820,7 +3891,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3820 | * SPEC_I_PT=1 is only valid for Service action: REGISTER | 3891 | * SPEC_I_PT=1 is only valid for Service action: REGISTER |
3821 | */ | 3892 | */ |
3822 | if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) { | 3893 | if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) { |
3823 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3894 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3895 | ret = -EINVAL; | ||
3824 | goto out; | 3896 | goto out; |
3825 | } | 3897 | } |
3826 | 3898 | ||
@@ -3837,7 +3909,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3837 | (cmd->data_length != 24)) { | 3909 | (cmd->data_length != 24)) { |
3838 | pr_warn("SPC-PR: Received PR OUT illegal parameter" | 3910 | pr_warn("SPC-PR: Received PR OUT illegal parameter" |
3839 | " list length: %u\n", cmd->data_length); | 3911 | " list length: %u\n", cmd->data_length); |
3840 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3912 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3913 | ret = -EINVAL; | ||
3841 | goto out; | 3914 | goto out; |
3842 | } | 3915 | } |
3843 | /* | 3916 | /* |
@@ -3878,7 +3951,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3878 | default: | 3951 | default: |
3879 | pr_err("Unknown PERSISTENT_RESERVE_OUT service" | 3952 | pr_err("Unknown PERSISTENT_RESERVE_OUT service" |
3880 | " action: 0x%02x\n", cdb[1] & 0x1f); | 3953 | " action: 0x%02x\n", cdb[1] & 0x1f); |
3881 | ret = PYX_TRANSPORT_INVALID_CDB_FIELD; | 3954 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
3955 | ret = -EINVAL; | ||
3882 | break; | 3956 | break; |
3883 | } | 3957 | } |
3884 | 3958 | ||
@@ -3906,7 +3980,8 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd) | |||
3906 | if (cmd->data_length < 8) { | 3980 | if (cmd->data_length < 8) { |
3907 | pr_err("PRIN SA READ_KEYS SCSI Data Length: %u" | 3981 | pr_err("PRIN SA READ_KEYS SCSI Data Length: %u" |
3908 | " too small\n", cmd->data_length); | 3982 | " too small\n", cmd->data_length); |
3909 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 3983 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
3984 | return -EINVAL; | ||
3910 | } | 3985 | } |
3911 | 3986 | ||
3912 | buf = transport_kmap_first_data_page(cmd); | 3987 | buf = transport_kmap_first_data_page(cmd); |
@@ -3965,7 +4040,8 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd) | |||
3965 | if (cmd->data_length < 8) { | 4040 | if (cmd->data_length < 8) { |
3966 | pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u" | 4041 | pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u" |
3967 | " too small\n", cmd->data_length); | 4042 | " too small\n", cmd->data_length); |
3968 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 4043 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
4044 | return -EINVAL; | ||
3969 | } | 4045 | } |
3970 | 4046 | ||
3971 | buf = transport_kmap_first_data_page(cmd); | 4047 | buf = transport_kmap_first_data_page(cmd); |
@@ -4047,7 +4123,8 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd) | |||
4047 | if (cmd->data_length < 6) { | 4123 | if (cmd->data_length < 6) { |
4048 | pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:" | 4124 | pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:" |
4049 | " %u too small\n", cmd->data_length); | 4125 | " %u too small\n", cmd->data_length); |
4050 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 4126 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
4127 | return -EINVAL; | ||
4051 | } | 4128 | } |
4052 | 4129 | ||
4053 | buf = transport_kmap_first_data_page(cmd); | 4130 | buf = transport_kmap_first_data_page(cmd); |
@@ -4108,7 +4185,8 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) | |||
4108 | if (cmd->data_length < 8) { | 4185 | if (cmd->data_length < 8) { |
4109 | pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u" | 4186 | pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u" |
4110 | " too small\n", cmd->data_length); | 4187 | " too small\n", cmd->data_length); |
4111 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 4188 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
4189 | return -EINVAL; | ||
4112 | } | 4190 | } |
4113 | 4191 | ||
4114 | buf = transport_kmap_first_data_page(cmd); | 4192 | buf = transport_kmap_first_data_page(cmd); |
@@ -4255,7 +4333,8 @@ int target_scsi3_emulate_pr_in(struct se_task *task) | |||
4255 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" | 4333 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" |
4256 | " SPC-2 reservation is held, returning" | 4334 | " SPC-2 reservation is held, returning" |
4257 | " RESERVATION_CONFLICT\n"); | 4335 | " RESERVATION_CONFLICT\n"); |
4258 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 4336 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
4337 | return -EINVAL; | ||
4259 | } | 4338 | } |
4260 | 4339 | ||
4261 | switch (cmd->t_task_cdb[1] & 0x1f) { | 4340 | switch (cmd->t_task_cdb[1] & 0x1f) { |
@@ -4274,7 +4353,8 @@ int target_scsi3_emulate_pr_in(struct se_task *task) | |||
4274 | default: | 4353 | default: |
4275 | pr_err("Unknown PERSISTENT_RESERVE_IN service" | 4354 | pr_err("Unknown PERSISTENT_RESERVE_IN service" |
4276 | " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); | 4355 | " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); |
4277 | ret = PYX_TRANSPORT_INVALID_CDB_FIELD; | 4356 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
4357 | ret = -EINVAL; | ||
4278 | break; | 4358 | break; |
4279 | } | 4359 | } |
4280 | 4360 | ||
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index ed32e1efe429..8b15e56b0384 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c | |||
@@ -963,6 +963,7 @@ static inline struct bio *pscsi_get_bio(int sg_num) | |||
963 | static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg, | 963 | static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg, |
964 | struct bio **hbio) | 964 | struct bio **hbio) |
965 | { | 965 | { |
966 | struct se_cmd *cmd = task->task_se_cmd; | ||
966 | struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr; | 967 | struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr; |
967 | u32 task_sg_num = task->task_sg_nents; | 968 | u32 task_sg_num = task->task_sg_nents; |
968 | struct bio *bio = NULL, *tbio = NULL; | 969 | struct bio *bio = NULL, *tbio = NULL; |
@@ -971,7 +972,7 @@ static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg, | |||
971 | u32 data_len = task->task_size, i, len, bytes, off; | 972 | u32 data_len = task->task_size, i, len, bytes, off; |
972 | int nr_pages = (task->task_size + task_sg[0].offset + | 973 | int nr_pages = (task->task_size + task_sg[0].offset + |
973 | PAGE_SIZE - 1) >> PAGE_SHIFT; | 974 | PAGE_SIZE - 1) >> PAGE_SHIFT; |
974 | int nr_vecs = 0, rc, ret = PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; | 975 | int nr_vecs = 0, rc; |
975 | int rw = (task->task_data_direction == DMA_TO_DEVICE); | 976 | int rw = (task->task_data_direction == DMA_TO_DEVICE); |
976 | 977 | ||
977 | *hbio = NULL; | 978 | *hbio = NULL; |
@@ -1058,11 +1059,13 @@ fail: | |||
1058 | bio->bi_next = NULL; | 1059 | bio->bi_next = NULL; |
1059 | bio_endio(bio, 0); /* XXX: should be error */ | 1060 | bio_endio(bio, 0); /* XXX: should be error */ |
1060 | } | 1061 | } |
1061 | return ret; | 1062 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1063 | return -ENOMEM; | ||
1062 | } | 1064 | } |
1063 | 1065 | ||
1064 | static int pscsi_do_task(struct se_task *task) | 1066 | static int pscsi_do_task(struct se_task *task) |
1065 | { | 1067 | { |
1068 | struct se_cmd *cmd = task->task_se_cmd; | ||
1066 | struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr; | 1069 | struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr; |
1067 | struct pscsi_plugin_task *pt = PSCSI_TASK(task); | 1070 | struct pscsi_plugin_task *pt = PSCSI_TASK(task); |
1068 | struct request *req; | 1071 | struct request *req; |
@@ -1078,7 +1081,9 @@ static int pscsi_do_task(struct se_task *task) | |||
1078 | if (!req || IS_ERR(req)) { | 1081 | if (!req || IS_ERR(req)) { |
1079 | pr_err("PSCSI: blk_get_request() failed: %ld\n", | 1082 | pr_err("PSCSI: blk_get_request() failed: %ld\n", |
1080 | req ? IS_ERR(req) : -ENOMEM); | 1083 | req ? IS_ERR(req) : -ENOMEM); |
1081 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 1084 | cmd->scsi_sense_reason = |
1085 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1086 | return -ENODEV; | ||
1082 | } | 1087 | } |
1083 | } else { | 1088 | } else { |
1084 | BUG_ON(!task->task_size); | 1089 | BUG_ON(!task->task_size); |
@@ -1087,8 +1092,11 @@ static int pscsi_do_task(struct se_task *task) | |||
1087 | * Setup the main struct request for the task->task_sg[] payload | 1092 | * Setup the main struct request for the task->task_sg[] payload |
1088 | */ | 1093 | */ |
1089 | ret = pscsi_map_sg(task, task->task_sg, &hbio); | 1094 | ret = pscsi_map_sg(task, task->task_sg, &hbio); |
1090 | if (ret < 0) | 1095 | if (ret < 0) { |
1091 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 1096 | cmd->scsi_sense_reason = |
1097 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1098 | return ret; | ||
1099 | } | ||
1092 | 1100 | ||
1093 | req = blk_make_request(pdv->pdv_sd->request_queue, hbio, | 1101 | req = blk_make_request(pdv->pdv_sd->request_queue, hbio, |
1094 | GFP_KERNEL); | 1102 | GFP_KERNEL); |
@@ -1115,7 +1123,7 @@ static int pscsi_do_task(struct se_task *task) | |||
1115 | (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG), | 1123 | (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG), |
1116 | pscsi_req_done); | 1124 | pscsi_req_done); |
1117 | 1125 | ||
1118 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 1126 | return 0; |
1119 | 1127 | ||
1120 | fail: | 1128 | fail: |
1121 | while (hbio) { | 1129 | while (hbio) { |
@@ -1124,7 +1132,8 @@ fail: | |||
1124 | bio->bi_next = NULL; | 1132 | bio->bi_next = NULL; |
1125 | bio_endio(bio, 0); /* XXX: should be error */ | 1133 | bio_endio(bio, 0); /* XXX: should be error */ |
1126 | } | 1134 | } |
1127 | return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; | 1135 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1136 | return -ENOMEM; | ||
1128 | } | 1137 | } |
1129 | 1138 | ||
1130 | /* pscsi_get_sense_buffer(): | 1139 | /* pscsi_get_sense_buffer(): |
@@ -1198,9 +1207,8 @@ static inline void pscsi_process_SAM_status( | |||
1198 | " 0x%02x Result: 0x%08x\n", task, pt->pscsi_cdb[0], | 1207 | " 0x%02x Result: 0x%08x\n", task, pt->pscsi_cdb[0], |
1199 | pt->pscsi_result); | 1208 | pt->pscsi_result); |
1200 | task->task_scsi_status = SAM_STAT_CHECK_CONDITION; | 1209 | task->task_scsi_status = SAM_STAT_CHECK_CONDITION; |
1201 | task->task_error_status = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 1210 | task->task_se_cmd->scsi_sense_reason = |
1202 | task->task_se_cmd->transport_error_status = | 1211 | TCM_UNSUPPORTED_SCSI_OPCODE; |
1203 | PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | ||
1204 | transport_complete_task(task, 0); | 1212 | transport_complete_task(task, 0); |
1205 | break; | 1213 | break; |
1206 | } | 1214 | } |
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 5158d3846f19..02e51faa2f4e 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c | |||
@@ -343,235 +343,74 @@ static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page) | |||
343 | return NULL; | 343 | return NULL; |
344 | } | 344 | } |
345 | 345 | ||
346 | /* rd_MEMCPY_read(): | 346 | static int rd_MEMCPY(struct rd_request *req, u32 read_rd) |
347 | * | ||
348 | * | ||
349 | */ | ||
350 | static int rd_MEMCPY_read(struct rd_request *req) | ||
351 | { | 347 | { |
352 | struct se_task *task = &req->rd_task; | 348 | struct se_task *task = &req->rd_task; |
353 | struct rd_dev *dev = req->rd_task.task_se_cmd->se_dev->dev_ptr; | 349 | struct rd_dev *dev = req->rd_task.task_se_cmd->se_dev->dev_ptr; |
354 | struct rd_dev_sg_table *table; | 350 | struct rd_dev_sg_table *table; |
355 | struct scatterlist *sg_d, *sg_s; | 351 | struct scatterlist *rd_sg; |
356 | void *dst, *src; | 352 | struct sg_mapping_iter m; |
357 | u32 i = 0, j = 0, dst_offset = 0, src_offset = 0; | ||
358 | u32 length, page_end = 0, table_sg_end; | ||
359 | u32 rd_offset = req->rd_offset; | 353 | u32 rd_offset = req->rd_offset; |
354 | u32 src_len; | ||
360 | 355 | ||
361 | table = rd_get_sg_table(dev, req->rd_page); | 356 | table = rd_get_sg_table(dev, req->rd_page); |
362 | if (!table) | 357 | if (!table) |
363 | return -EINVAL; | 358 | return -EINVAL; |
364 | 359 | ||
365 | table_sg_end = (table->page_end_offset - req->rd_page); | 360 | rd_sg = &table->sg_table[req->rd_page - table->page_start_offset]; |
366 | sg_d = task->task_sg; | ||
367 | sg_s = &table->sg_table[req->rd_page - table->page_start_offset]; | ||
368 | 361 | ||
369 | pr_debug("RD[%u]: Read LBA: %llu, Size: %u Page: %u, Offset:" | 362 | pr_debug("RD[%u]: %s LBA: %llu, Size: %u Page: %u, Offset: %u\n", |
370 | " %u\n", dev->rd_dev_id, task->task_lba, req->rd_size, | 363 | dev->rd_dev_id, read_rd ? "Read" : "Write", |
371 | req->rd_page, req->rd_offset); | 364 | task->task_lba, req->rd_size, req->rd_page, |
372 | 365 | rd_offset); | |
373 | src_offset = rd_offset; | ||
374 | 366 | ||
367 | src_len = PAGE_SIZE - rd_offset; | ||
368 | sg_miter_start(&m, task->task_sg, task->task_sg_nents, | ||
369 | read_rd ? SG_MITER_TO_SG : SG_MITER_FROM_SG); | ||
375 | while (req->rd_size) { | 370 | while (req->rd_size) { |
376 | if ((sg_d[i].length - dst_offset) < | 371 | u32 len; |
377 | (sg_s[j].length - src_offset)) { | 372 | void *rd_addr; |
378 | length = (sg_d[i].length - dst_offset); | ||
379 | |||
380 | pr_debug("Step 1 - sg_d[%d]: %p length: %d" | ||
381 | " offset: %u sg_s[%d].length: %u\n", i, | ||
382 | &sg_d[i], sg_d[i].length, sg_d[i].offset, j, | ||
383 | sg_s[j].length); | ||
384 | pr_debug("Step 1 - length: %u dst_offset: %u" | ||
385 | " src_offset: %u\n", length, dst_offset, | ||
386 | src_offset); | ||
387 | |||
388 | if (length > req->rd_size) | ||
389 | length = req->rd_size; | ||
390 | |||
391 | dst = sg_virt(&sg_d[i++]) + dst_offset; | ||
392 | BUG_ON(!dst); | ||
393 | |||
394 | src = sg_virt(&sg_s[j]) + src_offset; | ||
395 | BUG_ON(!src); | ||
396 | |||
397 | dst_offset = 0; | ||
398 | src_offset = length; | ||
399 | page_end = 0; | ||
400 | } else { | ||
401 | length = (sg_s[j].length - src_offset); | ||
402 | |||
403 | pr_debug("Step 2 - sg_d[%d]: %p length: %d" | ||
404 | " offset: %u sg_s[%d].length: %u\n", i, | ||
405 | &sg_d[i], sg_d[i].length, sg_d[i].offset, | ||
406 | j, sg_s[j].length); | ||
407 | pr_debug("Step 2 - length: %u dst_offset: %u" | ||
408 | " src_offset: %u\n", length, dst_offset, | ||
409 | src_offset); | ||
410 | |||
411 | if (length > req->rd_size) | ||
412 | length = req->rd_size; | ||
413 | |||
414 | dst = sg_virt(&sg_d[i]) + dst_offset; | ||
415 | BUG_ON(!dst); | ||
416 | |||
417 | if (sg_d[i].length == length) { | ||
418 | i++; | ||
419 | dst_offset = 0; | ||
420 | } else | ||
421 | dst_offset = length; | ||
422 | |||
423 | src = sg_virt(&sg_s[j++]) + src_offset; | ||
424 | BUG_ON(!src); | ||
425 | |||
426 | src_offset = 0; | ||
427 | page_end = 1; | ||
428 | } | ||
429 | 373 | ||
430 | memcpy(dst, src, length); | 374 | sg_miter_next(&m); |
375 | len = min((u32)m.length, src_len); | ||
376 | m.consumed = len; | ||
431 | 377 | ||
432 | pr_debug("page: %u, remaining size: %u, length: %u," | 378 | rd_addr = sg_virt(rd_sg) + rd_offset; |
433 | " i: %u, j: %u\n", req->rd_page, | ||
434 | (req->rd_size - length), length, i, j); | ||
435 | 379 | ||
436 | req->rd_size -= length; | 380 | if (read_rd) |
437 | if (!req->rd_size) | 381 | memcpy(m.addr, rd_addr, len); |
438 | return 0; | 382 | else |
383 | memcpy(rd_addr, m.addr, len); | ||
439 | 384 | ||
440 | if (!page_end) | 385 | req->rd_size -= len; |
386 | if (!req->rd_size) | ||
441 | continue; | 387 | continue; |
442 | 388 | ||
443 | if (++req->rd_page <= table->page_end_offset) { | 389 | src_len -= len; |
444 | pr_debug("page: %u in same page table\n", | 390 | if (src_len) { |
445 | req->rd_page); | 391 | rd_offset += len; |
446 | continue; | 392 | continue; |
447 | } | 393 | } |
448 | 394 | ||
449 | pr_debug("getting new page table for page: %u\n", | 395 | /* rd page completed, next one please */ |
450 | req->rd_page); | 396 | req->rd_page++; |
451 | 397 | rd_offset = 0; | |
452 | table = rd_get_sg_table(dev, req->rd_page); | 398 | src_len = PAGE_SIZE; |
453 | if (!table) | 399 | if (req->rd_page <= table->page_end_offset) { |
454 | return -EINVAL; | 400 | rd_sg++; |
455 | |||
456 | sg_s = &table->sg_table[j = 0]; | ||
457 | } | ||
458 | |||
459 | return 0; | ||
460 | } | ||
461 | |||
462 | /* rd_MEMCPY_write(): | ||
463 | * | ||
464 | * | ||
465 | */ | ||
466 | static int rd_MEMCPY_write(struct rd_request *req) | ||
467 | { | ||
468 | struct se_task *task = &req->rd_task; | ||
469 | struct rd_dev *dev = req->rd_task.task_se_cmd->se_dev->dev_ptr; | ||
470 | struct rd_dev_sg_table *table; | ||
471 | struct scatterlist *sg_d, *sg_s; | ||
472 | void *dst, *src; | ||
473 | u32 i = 0, j = 0, dst_offset = 0, src_offset = 0; | ||
474 | u32 length, page_end = 0, table_sg_end; | ||
475 | u32 rd_offset = req->rd_offset; | ||
476 | |||
477 | table = rd_get_sg_table(dev, req->rd_page); | ||
478 | if (!table) | ||
479 | return -EINVAL; | ||
480 | |||
481 | table_sg_end = (table->page_end_offset - req->rd_page); | ||
482 | sg_d = &table->sg_table[req->rd_page - table->page_start_offset]; | ||
483 | sg_s = task->task_sg; | ||
484 | |||
485 | pr_debug("RD[%d] Write LBA: %llu, Size: %u, Page: %u," | ||
486 | " Offset: %u\n", dev->rd_dev_id, task->task_lba, req->rd_size, | ||
487 | req->rd_page, req->rd_offset); | ||
488 | |||
489 | dst_offset = rd_offset; | ||
490 | |||
491 | while (req->rd_size) { | ||
492 | if ((sg_s[i].length - src_offset) < | ||
493 | (sg_d[j].length - dst_offset)) { | ||
494 | length = (sg_s[i].length - src_offset); | ||
495 | |||
496 | pr_debug("Step 1 - sg_s[%d]: %p length: %d" | ||
497 | " offset: %d sg_d[%d].length: %u\n", i, | ||
498 | &sg_s[i], sg_s[i].length, sg_s[i].offset, | ||
499 | j, sg_d[j].length); | ||
500 | pr_debug("Step 1 - length: %u src_offset: %u" | ||
501 | " dst_offset: %u\n", length, src_offset, | ||
502 | dst_offset); | ||
503 | |||
504 | if (length > req->rd_size) | ||
505 | length = req->rd_size; | ||
506 | |||
507 | src = sg_virt(&sg_s[i++]) + src_offset; | ||
508 | BUG_ON(!src); | ||
509 | |||
510 | dst = sg_virt(&sg_d[j]) + dst_offset; | ||
511 | BUG_ON(!dst); | ||
512 | |||
513 | src_offset = 0; | ||
514 | dst_offset = length; | ||
515 | page_end = 0; | ||
516 | } else { | ||
517 | length = (sg_d[j].length - dst_offset); | ||
518 | |||
519 | pr_debug("Step 2 - sg_s[%d]: %p length: %d" | ||
520 | " offset: %d sg_d[%d].length: %u\n", i, | ||
521 | &sg_s[i], sg_s[i].length, sg_s[i].offset, | ||
522 | j, sg_d[j].length); | ||
523 | pr_debug("Step 2 - length: %u src_offset: %u" | ||
524 | " dst_offset: %u\n", length, src_offset, | ||
525 | dst_offset); | ||
526 | |||
527 | if (length > req->rd_size) | ||
528 | length = req->rd_size; | ||
529 | |||
530 | src = sg_virt(&sg_s[i]) + src_offset; | ||
531 | BUG_ON(!src); | ||
532 | |||
533 | if (sg_s[i].length == length) { | ||
534 | i++; | ||
535 | src_offset = 0; | ||
536 | } else | ||
537 | src_offset = length; | ||
538 | |||
539 | dst = sg_virt(&sg_d[j++]) + dst_offset; | ||
540 | BUG_ON(!dst); | ||
541 | |||
542 | dst_offset = 0; | ||
543 | page_end = 1; | ||
544 | } | ||
545 | |||
546 | memcpy(dst, src, length); | ||
547 | |||
548 | pr_debug("page: %u, remaining size: %u, length: %u," | ||
549 | " i: %u, j: %u\n", req->rd_page, | ||
550 | (req->rd_size - length), length, i, j); | ||
551 | |||
552 | req->rd_size -= length; | ||
553 | if (!req->rd_size) | ||
554 | return 0; | ||
555 | |||
556 | if (!page_end) | ||
557 | continue; | ||
558 | |||
559 | if (++req->rd_page <= table->page_end_offset) { | ||
560 | pr_debug("page: %u in same page table\n", | ||
561 | req->rd_page); | ||
562 | continue; | 401 | continue; |
563 | } | 402 | } |
564 | 403 | ||
565 | pr_debug("getting new page table for page: %u\n", | ||
566 | req->rd_page); | ||
567 | |||
568 | table = rd_get_sg_table(dev, req->rd_page); | 404 | table = rd_get_sg_table(dev, req->rd_page); |
569 | if (!table) | 405 | if (!table) { |
406 | sg_miter_stop(&m); | ||
570 | return -EINVAL; | 407 | return -EINVAL; |
408 | } | ||
571 | 409 | ||
572 | sg_d = &table->sg_table[j = 0]; | 410 | /* since we increment, the first sg entry is correct */ |
411 | rd_sg = table->sg_table; | ||
573 | } | 412 | } |
574 | 413 | sg_miter_stop(&m); | |
575 | return 0; | 414 | return 0; |
576 | } | 415 | } |
577 | 416 | ||
@@ -583,28 +422,21 @@ static int rd_MEMCPY_do_task(struct se_task *task) | |||
583 | { | 422 | { |
584 | struct se_device *dev = task->task_se_cmd->se_dev; | 423 | struct se_device *dev = task->task_se_cmd->se_dev; |
585 | struct rd_request *req = RD_REQ(task); | 424 | struct rd_request *req = RD_REQ(task); |
586 | unsigned long long lba; | 425 | u64 tmp; |
587 | int ret; | 426 | int ret; |
588 | 427 | ||
589 | req->rd_page = (task->task_lba * dev->se_sub_dev->se_dev_attrib.block_size) / PAGE_SIZE; | 428 | tmp = task->task_lba * dev->se_sub_dev->se_dev_attrib.block_size; |
590 | lba = task->task_lba; | 429 | req->rd_offset = do_div(tmp, PAGE_SIZE); |
591 | req->rd_offset = (do_div(lba, | 430 | req->rd_page = tmp; |
592 | (PAGE_SIZE / dev->se_sub_dev->se_dev_attrib.block_size))) * | ||
593 | dev->se_sub_dev->se_dev_attrib.block_size; | ||
594 | req->rd_size = task->task_size; | 431 | req->rd_size = task->task_size; |
595 | 432 | ||
596 | if (task->task_data_direction == DMA_FROM_DEVICE) | 433 | ret = rd_MEMCPY(req, task->task_data_direction == DMA_FROM_DEVICE); |
597 | ret = rd_MEMCPY_read(req); | ||
598 | else | ||
599 | ret = rd_MEMCPY_write(req); | ||
600 | |||
601 | if (ret != 0) | 434 | if (ret != 0) |
602 | return ret; | 435 | return ret; |
603 | 436 | ||
604 | task->task_scsi_status = GOOD; | 437 | task->task_scsi_status = GOOD; |
605 | transport_complete_task(task, 1); | 438 | transport_complete_task(task, 1); |
606 | 439 | return 0; | |
607 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | ||
608 | } | 440 | } |
609 | 441 | ||
610 | /* rd_free_task(): (Part of se_subsystem_api_t template) | 442 | /* rd_free_task(): (Part of se_subsystem_api_t template) |
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 217e29df6297..684522805a1f 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c | |||
@@ -345,10 +345,6 @@ static void core_tmr_drain_cmd_list( | |||
345 | " %d t_fe_count: %d\n", (preempt_and_abort_list) ? | 345 | " %d t_fe_count: %d\n", (preempt_and_abort_list) ? |
346 | "Preempt" : "", cmd, cmd->t_state, | 346 | "Preempt" : "", cmd, cmd->t_state, |
347 | atomic_read(&cmd->t_fe_count)); | 347 | atomic_read(&cmd->t_fe_count)); |
348 | /* | ||
349 | * Signal that the command has failed via cmd->se_cmd_flags, | ||
350 | */ | ||
351 | transport_new_cmd_failure(cmd); | ||
352 | 348 | ||
353 | core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, | 349 | core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, |
354 | atomic_read(&cmd->t_fe_count)); | 350 | atomic_read(&cmd->t_fe_count)); |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 3400ae6e93f8..0257658e2e3e 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -61,7 +61,6 @@ | |||
61 | static int sub_api_initialized; | 61 | static int sub_api_initialized; |
62 | 62 | ||
63 | static struct workqueue_struct *target_completion_wq; | 63 | static struct workqueue_struct *target_completion_wq; |
64 | static struct kmem_cache *se_cmd_cache; | ||
65 | static struct kmem_cache *se_sess_cache; | 64 | static struct kmem_cache *se_sess_cache; |
66 | struct kmem_cache *se_tmr_req_cache; | 65 | struct kmem_cache *se_tmr_req_cache; |
67 | struct kmem_cache *se_ua_cache; | 66 | struct kmem_cache *se_ua_cache; |
@@ -82,24 +81,18 @@ static int transport_generic_get_mem(struct se_cmd *cmd); | |||
82 | static void transport_put_cmd(struct se_cmd *cmd); | 81 | static void transport_put_cmd(struct se_cmd *cmd); |
83 | static void transport_remove_cmd_from_queue(struct se_cmd *cmd); | 82 | static void transport_remove_cmd_from_queue(struct se_cmd *cmd); |
84 | static int transport_set_sense_codes(struct se_cmd *cmd, u8 asc, u8 ascq); | 83 | static int transport_set_sense_codes(struct se_cmd *cmd, u8 asc, u8 ascq); |
85 | static void transport_generic_request_failure(struct se_cmd *, int, int); | 84 | static void transport_generic_request_failure(struct se_cmd *); |
86 | static void target_complete_ok_work(struct work_struct *work); | 85 | static void target_complete_ok_work(struct work_struct *work); |
87 | 86 | ||
88 | int init_se_kmem_caches(void) | 87 | int init_se_kmem_caches(void) |
89 | { | 88 | { |
90 | se_cmd_cache = kmem_cache_create("se_cmd_cache", | ||
91 | sizeof(struct se_cmd), __alignof__(struct se_cmd), 0, NULL); | ||
92 | if (!se_cmd_cache) { | ||
93 | pr_err("kmem_cache_create for struct se_cmd failed\n"); | ||
94 | goto out; | ||
95 | } | ||
96 | se_tmr_req_cache = kmem_cache_create("se_tmr_cache", | 89 | se_tmr_req_cache = kmem_cache_create("se_tmr_cache", |
97 | sizeof(struct se_tmr_req), __alignof__(struct se_tmr_req), | 90 | sizeof(struct se_tmr_req), __alignof__(struct se_tmr_req), |
98 | 0, NULL); | 91 | 0, NULL); |
99 | if (!se_tmr_req_cache) { | 92 | if (!se_tmr_req_cache) { |
100 | pr_err("kmem_cache_create() for struct se_tmr_req" | 93 | pr_err("kmem_cache_create() for struct se_tmr_req" |
101 | " failed\n"); | 94 | " failed\n"); |
102 | goto out_free_cmd_cache; | 95 | goto out; |
103 | } | 96 | } |
104 | se_sess_cache = kmem_cache_create("se_sess_cache", | 97 | se_sess_cache = kmem_cache_create("se_sess_cache", |
105 | sizeof(struct se_session), __alignof__(struct se_session), | 98 | sizeof(struct se_session), __alignof__(struct se_session), |
@@ -182,8 +175,6 @@ out_free_sess_cache: | |||
182 | kmem_cache_destroy(se_sess_cache); | 175 | kmem_cache_destroy(se_sess_cache); |
183 | out_free_tmr_req_cache: | 176 | out_free_tmr_req_cache: |
184 | kmem_cache_destroy(se_tmr_req_cache); | 177 | kmem_cache_destroy(se_tmr_req_cache); |
185 | out_free_cmd_cache: | ||
186 | kmem_cache_destroy(se_cmd_cache); | ||
187 | out: | 178 | out: |
188 | return -ENOMEM; | 179 | return -ENOMEM; |
189 | } | 180 | } |
@@ -191,7 +182,6 @@ out: | |||
191 | void release_se_kmem_caches(void) | 182 | void release_se_kmem_caches(void) |
192 | { | 183 | { |
193 | destroy_workqueue(target_completion_wq); | 184 | destroy_workqueue(target_completion_wq); |
194 | kmem_cache_destroy(se_cmd_cache); | ||
195 | kmem_cache_destroy(se_tmr_req_cache); | 185 | kmem_cache_destroy(se_tmr_req_cache); |
196 | kmem_cache_destroy(se_sess_cache); | 186 | kmem_cache_destroy(se_sess_cache); |
197 | kmem_cache_destroy(se_ua_cache); | 187 | kmem_cache_destroy(se_ua_cache); |
@@ -680,9 +670,9 @@ void transport_complete_sync_cache(struct se_cmd *cmd, int good) | |||
680 | task->task_scsi_status = GOOD; | 670 | task->task_scsi_status = GOOD; |
681 | } else { | 671 | } else { |
682 | task->task_scsi_status = SAM_STAT_CHECK_CONDITION; | 672 | task->task_scsi_status = SAM_STAT_CHECK_CONDITION; |
683 | task->task_error_status = PYX_TRANSPORT_ILLEGAL_REQUEST; | 673 | task->task_se_cmd->scsi_sense_reason = |
684 | task->task_se_cmd->transport_error_status = | 674 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
685 | PYX_TRANSPORT_ILLEGAL_REQUEST; | 675 | |
686 | } | 676 | } |
687 | 677 | ||
688 | transport_complete_task(task, good); | 678 | transport_complete_task(task, good); |
@@ -693,7 +683,7 @@ static void target_complete_failure_work(struct work_struct *work) | |||
693 | { | 683 | { |
694 | struct se_cmd *cmd = container_of(work, struct se_cmd, work); | 684 | struct se_cmd *cmd = container_of(work, struct se_cmd, work); |
695 | 685 | ||
696 | transport_generic_request_failure(cmd, 1, 1); | 686 | transport_generic_request_failure(cmd); |
697 | } | 687 | } |
698 | 688 | ||
699 | /* transport_complete_task(): | 689 | /* transport_complete_task(): |
@@ -755,10 +745,11 @@ void transport_complete_task(struct se_task *task, int success) | |||
755 | if (cmd->t_tasks_failed) { | 745 | if (cmd->t_tasks_failed) { |
756 | if (!task->task_error_status) { | 746 | if (!task->task_error_status) { |
757 | task->task_error_status = | 747 | task->task_error_status = |
758 | PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 748 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
759 | cmd->transport_error_status = | 749 | cmd->scsi_sense_reason = |
760 | PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 750 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
761 | } | 751 | } |
752 | |||
762 | INIT_WORK(&cmd->work, target_complete_failure_work); | 753 | INIT_WORK(&cmd->work, target_complete_failure_work); |
763 | } else { | 754 | } else { |
764 | atomic_set(&cmd->t_transport_complete, 1); | 755 | atomic_set(&cmd->t_transport_complete, 1); |
@@ -1335,23 +1326,17 @@ struct se_device *transport_add_device_to_core_hba( | |||
1335 | dev->se_hba = hba; | 1326 | dev->se_hba = hba; |
1336 | dev->se_sub_dev = se_dev; | 1327 | dev->se_sub_dev = se_dev; |
1337 | dev->transport = transport; | 1328 | dev->transport = transport; |
1338 | atomic_set(&dev->active_cmds, 0); | ||
1339 | INIT_LIST_HEAD(&dev->dev_list); | 1329 | INIT_LIST_HEAD(&dev->dev_list); |
1340 | INIT_LIST_HEAD(&dev->dev_sep_list); | 1330 | INIT_LIST_HEAD(&dev->dev_sep_list); |
1341 | INIT_LIST_HEAD(&dev->dev_tmr_list); | 1331 | INIT_LIST_HEAD(&dev->dev_tmr_list); |
1342 | INIT_LIST_HEAD(&dev->execute_task_list); | 1332 | INIT_LIST_HEAD(&dev->execute_task_list); |
1343 | INIT_LIST_HEAD(&dev->delayed_cmd_list); | 1333 | INIT_LIST_HEAD(&dev->delayed_cmd_list); |
1344 | INIT_LIST_HEAD(&dev->ordered_cmd_list); | ||
1345 | INIT_LIST_HEAD(&dev->state_task_list); | 1334 | INIT_LIST_HEAD(&dev->state_task_list); |
1346 | INIT_LIST_HEAD(&dev->qf_cmd_list); | 1335 | INIT_LIST_HEAD(&dev->qf_cmd_list); |
1347 | spin_lock_init(&dev->execute_task_lock); | 1336 | spin_lock_init(&dev->execute_task_lock); |
1348 | spin_lock_init(&dev->delayed_cmd_lock); | 1337 | spin_lock_init(&dev->delayed_cmd_lock); |
1349 | spin_lock_init(&dev->ordered_cmd_lock); | ||
1350 | spin_lock_init(&dev->state_task_lock); | ||
1351 | spin_lock_init(&dev->dev_alua_lock); | ||
1352 | spin_lock_init(&dev->dev_reservation_lock); | 1338 | spin_lock_init(&dev->dev_reservation_lock); |
1353 | spin_lock_init(&dev->dev_status_lock); | 1339 | spin_lock_init(&dev->dev_status_lock); |
1354 | spin_lock_init(&dev->dev_status_thr_lock); | ||
1355 | spin_lock_init(&dev->se_port_lock); | 1340 | spin_lock_init(&dev->se_port_lock); |
1356 | spin_lock_init(&dev->se_tmr_lock); | 1341 | spin_lock_init(&dev->se_tmr_lock); |
1357 | spin_lock_init(&dev->qf_cmd_lock); | 1342 | spin_lock_init(&dev->qf_cmd_lock); |
@@ -1507,7 +1492,6 @@ void transport_init_se_cmd( | |||
1507 | { | 1492 | { |
1508 | INIT_LIST_HEAD(&cmd->se_lun_node); | 1493 | INIT_LIST_HEAD(&cmd->se_lun_node); |
1509 | INIT_LIST_HEAD(&cmd->se_delayed_node); | 1494 | INIT_LIST_HEAD(&cmd->se_delayed_node); |
1510 | INIT_LIST_HEAD(&cmd->se_ordered_node); | ||
1511 | INIT_LIST_HEAD(&cmd->se_qf_node); | 1495 | INIT_LIST_HEAD(&cmd->se_qf_node); |
1512 | INIT_LIST_HEAD(&cmd->se_queue_node); | 1496 | INIT_LIST_HEAD(&cmd->se_queue_node); |
1513 | INIT_LIST_HEAD(&cmd->se_cmd_list); | 1497 | INIT_LIST_HEAD(&cmd->se_cmd_list); |
@@ -1573,6 +1557,8 @@ int transport_generic_allocate_tasks( | |||
1573 | pr_err("Received SCSI CDB with command_size: %d that" | 1557 | pr_err("Received SCSI CDB with command_size: %d that" |
1574 | " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", | 1558 | " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", |
1575 | scsi_command_size(cdb), SCSI_MAX_VARLEN_CDB_SIZE); | 1559 | scsi_command_size(cdb), SCSI_MAX_VARLEN_CDB_SIZE); |
1560 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1561 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
1576 | return -EINVAL; | 1562 | return -EINVAL; |
1577 | } | 1563 | } |
1578 | /* | 1564 | /* |
@@ -1588,6 +1574,9 @@ int transport_generic_allocate_tasks( | |||
1588 | " %u > sizeof(cmd->__t_task_cdb): %lu ops\n", | 1574 | " %u > sizeof(cmd->__t_task_cdb): %lu ops\n", |
1589 | scsi_command_size(cdb), | 1575 | scsi_command_size(cdb), |
1590 | (unsigned long)sizeof(cmd->__t_task_cdb)); | 1576 | (unsigned long)sizeof(cmd->__t_task_cdb)); |
1577 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1578 | cmd->scsi_sense_reason = | ||
1579 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1591 | return -ENOMEM; | 1580 | return -ENOMEM; |
1592 | } | 1581 | } |
1593 | } else | 1582 | } else |
@@ -1658,11 +1647,9 @@ int transport_handle_cdb_direct( | |||
1658 | * and call transport_generic_request_failure() if necessary.. | 1647 | * and call transport_generic_request_failure() if necessary.. |
1659 | */ | 1648 | */ |
1660 | ret = transport_generic_new_cmd(cmd); | 1649 | ret = transport_generic_new_cmd(cmd); |
1661 | if (ret < 0) { | 1650 | if (ret < 0) |
1662 | cmd->transport_error_status = ret; | 1651 | transport_generic_request_failure(cmd); |
1663 | transport_generic_request_failure(cmd, 0, | 1652 | |
1664 | (cmd->data_direction != DMA_TO_DEVICE)); | ||
1665 | } | ||
1666 | return 0; | 1653 | return 0; |
1667 | } | 1654 | } |
1668 | EXPORT_SYMBOL(transport_handle_cdb_direct); | 1655 | EXPORT_SYMBOL(transport_handle_cdb_direct); |
@@ -1798,20 +1785,16 @@ static int transport_stop_tasks_for_cmd(struct se_cmd *cmd) | |||
1798 | /* | 1785 | /* |
1799 | * Handle SAM-esque emulation for generic transport request failures. | 1786 | * Handle SAM-esque emulation for generic transport request failures. |
1800 | */ | 1787 | */ |
1801 | static void transport_generic_request_failure( | 1788 | static void transport_generic_request_failure(struct se_cmd *cmd) |
1802 | struct se_cmd *cmd, | ||
1803 | int complete, | ||
1804 | int sc) | ||
1805 | { | 1789 | { |
1806 | int ret = 0; | 1790 | int ret = 0; |
1807 | 1791 | ||
1808 | pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x" | 1792 | pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x" |
1809 | " CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd), | 1793 | " CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd), |
1810 | cmd->t_task_cdb[0]); | 1794 | cmd->t_task_cdb[0]); |
1811 | pr_debug("-----[ i_state: %d t_state: %d transport_error_status: %d\n", | 1795 | pr_debug("-----[ i_state: %d t_state: %d scsi_sense_reason: %d\n", |
1812 | cmd->se_tfo->get_cmd_state(cmd), | 1796 | cmd->se_tfo->get_cmd_state(cmd), |
1813 | cmd->t_state, | 1797 | cmd->t_state, cmd->scsi_sense_reason); |
1814 | cmd->transport_error_status); | ||
1815 | pr_debug("-----[ t_tasks: %d t_task_cdbs_left: %d" | 1798 | pr_debug("-----[ t_tasks: %d t_task_cdbs_left: %d" |
1816 | " t_task_cdbs_sent: %d t_task_cdbs_ex_left: %d --" | 1799 | " t_task_cdbs_sent: %d t_task_cdbs_ex_left: %d --" |
1817 | " t_transport_active: %d t_transport_stop: %d" | 1800 | " t_transport_active: %d t_transport_stop: %d" |
@@ -1829,46 +1812,19 @@ static void transport_generic_request_failure( | |||
1829 | if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) | 1812 | if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) |
1830 | transport_complete_task_attr(cmd); | 1813 | transport_complete_task_attr(cmd); |
1831 | 1814 | ||
1832 | if (complete) { | 1815 | switch (cmd->scsi_sense_reason) { |
1833 | cmd->transport_error_status = PYX_TRANSPORT_LU_COMM_FAILURE; | 1816 | case TCM_NON_EXISTENT_LUN: |
1834 | } | 1817 | case TCM_UNSUPPORTED_SCSI_OPCODE: |
1835 | 1818 | case TCM_INVALID_CDB_FIELD: | |
1836 | switch (cmd->transport_error_status) { | 1819 | case TCM_INVALID_PARAMETER_LIST: |
1837 | case PYX_TRANSPORT_UNKNOWN_SAM_OPCODE: | 1820 | case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE: |
1838 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 1821 | case TCM_UNKNOWN_MODE_PAGE: |
1839 | break; | 1822 | case TCM_WRITE_PROTECTED: |
1840 | case PYX_TRANSPORT_REQ_TOO_MANY_SECTORS: | 1823 | case TCM_CHECK_CONDITION_ABORT_CMD: |
1841 | cmd->scsi_sense_reason = TCM_SECTOR_COUNT_TOO_MANY; | 1824 | case TCM_CHECK_CONDITION_UNIT_ATTENTION: |
1842 | break; | 1825 | case TCM_CHECK_CONDITION_NOT_READY: |
1843 | case PYX_TRANSPORT_INVALID_CDB_FIELD: | ||
1844 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
1845 | break; | ||
1846 | case PYX_TRANSPORT_INVALID_PARAMETER_LIST: | ||
1847 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
1848 | break; | ||
1849 | case PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES: | ||
1850 | if (!sc) | ||
1851 | transport_new_cmd_failure(cmd); | ||
1852 | /* | ||
1853 | * Currently for PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES, | ||
1854 | * we force this session to fall back to session | ||
1855 | * recovery. | ||
1856 | */ | ||
1857 | cmd->se_tfo->fall_back_to_erl0(cmd->se_sess); | ||
1858 | cmd->se_tfo->stop_session(cmd->se_sess, 0, 0); | ||
1859 | |||
1860 | goto check_stop; | ||
1861 | case PYX_TRANSPORT_LU_COMM_FAILURE: | ||
1862 | case PYX_TRANSPORT_ILLEGAL_REQUEST: | ||
1863 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1864 | break; | ||
1865 | case PYX_TRANSPORT_UNKNOWN_MODE_PAGE: | ||
1866 | cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE; | ||
1867 | break; | ||
1868 | case PYX_TRANSPORT_WRITE_PROTECTED: | ||
1869 | cmd->scsi_sense_reason = TCM_WRITE_PROTECTED; | ||
1870 | break; | 1826 | break; |
1871 | case PYX_TRANSPORT_RESERVATION_CONFLICT: | 1827 | case TCM_RESERVATION_CONFLICT: |
1872 | /* | 1828 | /* |
1873 | * No SENSE Data payload for this case, set SCSI Status | 1829 | * No SENSE Data payload for this case, set SCSI Status |
1874 | * and queue the response to $FABRIC_MOD. | 1830 | * and queue the response to $FABRIC_MOD. |
@@ -1893,15 +1849,9 @@ static void transport_generic_request_failure( | |||
1893 | if (ret == -EAGAIN || ret == -ENOMEM) | 1849 | if (ret == -EAGAIN || ret == -ENOMEM) |
1894 | goto queue_full; | 1850 | goto queue_full; |
1895 | goto check_stop; | 1851 | goto check_stop; |
1896 | case PYX_TRANSPORT_USE_SENSE_REASON: | ||
1897 | /* | ||
1898 | * struct se_cmd->scsi_sense_reason already set | ||
1899 | */ | ||
1900 | break; | ||
1901 | default: | 1852 | default: |
1902 | pr_err("Unknown transport error for CDB 0x%02x: %d\n", | 1853 | pr_err("Unknown transport error for CDB 0x%02x: %d\n", |
1903 | cmd->t_task_cdb[0], | 1854 | cmd->t_task_cdb[0], cmd->scsi_sense_reason); |
1904 | cmd->transport_error_status); | ||
1905 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 1855 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
1906 | break; | 1856 | break; |
1907 | } | 1857 | } |
@@ -1912,14 +1862,10 @@ static void transport_generic_request_failure( | |||
1912 | * transport_send_check_condition_and_sense() after handling | 1862 | * transport_send_check_condition_and_sense() after handling |
1913 | * possible unsoliticied write data payloads. | 1863 | * possible unsoliticied write data payloads. |
1914 | */ | 1864 | */ |
1915 | if (!sc && !cmd->se_tfo->new_cmd_map) | 1865 | ret = transport_send_check_condition_and_sense(cmd, |
1916 | transport_new_cmd_failure(cmd); | 1866 | cmd->scsi_sense_reason, 0); |
1917 | else { | 1867 | if (ret == -EAGAIN || ret == -ENOMEM) |
1918 | ret = transport_send_check_condition_and_sense(cmd, | 1868 | goto queue_full; |
1919 | cmd->scsi_sense_reason, 0); | ||
1920 | if (ret == -EAGAIN || ret == -ENOMEM) | ||
1921 | goto queue_full; | ||
1922 | } | ||
1923 | 1869 | ||
1924 | check_stop: | 1870 | check_stop: |
1925 | transport_lun_remove_cmd(cmd); | 1871 | transport_lun_remove_cmd(cmd); |
@@ -2002,19 +1948,12 @@ static inline int transport_execute_task_attr(struct se_cmd *cmd) | |||
2002 | * to allow the passed struct se_cmd list of tasks to the front of the list. | 1948 | * to allow the passed struct se_cmd list of tasks to the front of the list. |
2003 | */ | 1949 | */ |
2004 | if (cmd->sam_task_attr == MSG_HEAD_TAG) { | 1950 | if (cmd->sam_task_attr == MSG_HEAD_TAG) { |
2005 | atomic_inc(&cmd->se_dev->dev_hoq_count); | ||
2006 | smp_mb__after_atomic_inc(); | ||
2007 | pr_debug("Added HEAD_OF_QUEUE for CDB:" | 1951 | pr_debug("Added HEAD_OF_QUEUE for CDB:" |
2008 | " 0x%02x, se_ordered_id: %u\n", | 1952 | " 0x%02x, se_ordered_id: %u\n", |
2009 | cmd->t_task_cdb[0], | 1953 | cmd->t_task_cdb[0], |
2010 | cmd->se_ordered_id); | 1954 | cmd->se_ordered_id); |
2011 | return 1; | 1955 | return 1; |
2012 | } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) { | 1956 | } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) { |
2013 | spin_lock(&cmd->se_dev->ordered_cmd_lock); | ||
2014 | list_add_tail(&cmd->se_ordered_node, | ||
2015 | &cmd->se_dev->ordered_cmd_list); | ||
2016 | spin_unlock(&cmd->se_dev->ordered_cmd_lock); | ||
2017 | |||
2018 | atomic_inc(&cmd->se_dev->dev_ordered_sync); | 1957 | atomic_inc(&cmd->se_dev->dev_ordered_sync); |
2019 | smp_mb__after_atomic_inc(); | 1958 | smp_mb__after_atomic_inc(); |
2020 | 1959 | ||
@@ -2076,9 +2015,9 @@ static int transport_execute_tasks(struct se_cmd *cmd) | |||
2076 | { | 2015 | { |
2077 | int add_tasks; | 2016 | int add_tasks; |
2078 | 2017 | ||
2079 | if (se_dev_check_online(cmd->se_orig_obj_ptr) != 0) { | 2018 | if (se_dev_check_online(cmd->se_dev) != 0) { |
2080 | cmd->transport_error_status = PYX_TRANSPORT_LU_COMM_FAILURE; | 2019 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2081 | transport_generic_request_failure(cmd, 0, 1); | 2020 | transport_generic_request_failure(cmd); |
2082 | return 0; | 2021 | return 0; |
2083 | } | 2022 | } |
2084 | 2023 | ||
@@ -2163,14 +2102,13 @@ check_depth: | |||
2163 | else | 2102 | else |
2164 | error = dev->transport->do_task(task); | 2103 | error = dev->transport->do_task(task); |
2165 | if (error != 0) { | 2104 | if (error != 0) { |
2166 | cmd->transport_error_status = error; | ||
2167 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 2105 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
2168 | task->task_flags &= ~TF_ACTIVE; | 2106 | task->task_flags &= ~TF_ACTIVE; |
2169 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 2107 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
2170 | atomic_set(&cmd->t_transport_sent, 0); | 2108 | atomic_set(&cmd->t_transport_sent, 0); |
2171 | transport_stop_tasks_for_cmd(cmd); | 2109 | transport_stop_tasks_for_cmd(cmd); |
2172 | atomic_inc(&dev->depth_left); | 2110 | atomic_inc(&dev->depth_left); |
2173 | transport_generic_request_failure(cmd, 0, 1); | 2111 | transport_generic_request_failure(cmd); |
2174 | } | 2112 | } |
2175 | 2113 | ||
2176 | goto check_depth; | 2114 | goto check_depth; |
@@ -2178,19 +2116,6 @@ check_depth: | |||
2178 | return 0; | 2116 | return 0; |
2179 | } | 2117 | } |
2180 | 2118 | ||
2181 | void transport_new_cmd_failure(struct se_cmd *se_cmd) | ||
2182 | { | ||
2183 | unsigned long flags; | ||
2184 | /* | ||
2185 | * Any unsolicited data will get dumped for failed command inside of | ||
2186 | * the fabric plugin | ||
2187 | */ | ||
2188 | spin_lock_irqsave(&se_cmd->t_state_lock, flags); | ||
2189 | se_cmd->se_cmd_flags |= SCF_SE_CMD_FAILED; | ||
2190 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
2191 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); | ||
2192 | } | ||
2193 | |||
2194 | static inline u32 transport_get_sectors_6( | 2119 | static inline u32 transport_get_sectors_6( |
2195 | unsigned char *cdb, | 2120 | unsigned char *cdb, |
2196 | struct se_cmd *cmd, | 2121 | struct se_cmd *cmd, |
@@ -2213,10 +2138,15 @@ static inline u32 transport_get_sectors_6( | |||
2213 | 2138 | ||
2214 | /* | 2139 | /* |
2215 | * Everything else assume TYPE_DISK Sector CDB location. | 2140 | * Everything else assume TYPE_DISK Sector CDB location. |
2216 | * Use 8-bit sector value. | 2141 | * Use 8-bit sector value. SBC-3 says: |
2142 | * | ||
2143 | * A TRANSFER LENGTH field set to zero specifies that 256 | ||
2144 | * logical blocks shall be written. Any other value | ||
2145 | * specifies the number of logical blocks that shall be | ||
2146 | * written. | ||
2217 | */ | 2147 | */ |
2218 | type_disk: | 2148 | type_disk: |
2219 | return (u32)cdb[4]; | 2149 | return cdb[4] ? : 256; |
2220 | } | 2150 | } |
2221 | 2151 | ||
2222 | static inline u32 transport_get_sectors_10( | 2152 | static inline u32 transport_get_sectors_10( |
@@ -2460,27 +2390,6 @@ static int transport_get_sense_data(struct se_cmd *cmd) | |||
2460 | return -1; | 2390 | return -1; |
2461 | } | 2391 | } |
2462 | 2392 | ||
2463 | static int | ||
2464 | transport_handle_reservation_conflict(struct se_cmd *cmd) | ||
2465 | { | ||
2466 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
2467 | cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; | ||
2468 | cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; | ||
2469 | /* | ||
2470 | * For UA Interlock Code 11b, a RESERVATION CONFLICT will | ||
2471 | * establish a UNIT ATTENTION with PREVIOUS RESERVATION | ||
2472 | * CONFLICT STATUS. | ||
2473 | * | ||
2474 | * See spc4r17, section 7.4.6 Control Mode Page, Table 349 | ||
2475 | */ | ||
2476 | if (cmd->se_sess && | ||
2477 | cmd->se_dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl == 2) | ||
2478 | core_scsi3_ua_allocate(cmd->se_sess->se_node_acl, | ||
2479 | cmd->orig_fe_lun, 0x2C, | ||
2480 | ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS); | ||
2481 | return -EINVAL; | ||
2482 | } | ||
2483 | |||
2484 | static inline long long transport_dev_end_lba(struct se_device *dev) | 2393 | static inline long long transport_dev_end_lba(struct se_device *dev) |
2485 | { | 2394 | { |
2486 | return dev->transport->get_blocks(dev) + 1; | 2395 | return dev->transport->get_blocks(dev) + 1; |
@@ -2595,8 +2504,12 @@ static int transport_generic_cmd_sequencer( | |||
2595 | */ | 2504 | */ |
2596 | if (su_dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type) != 0) { | 2505 | if (su_dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type) != 0) { |
2597 | if (su_dev->t10_pr.pr_ops.t10_seq_non_holder( | 2506 | if (su_dev->t10_pr.pr_ops.t10_seq_non_holder( |
2598 | cmd, cdb, pr_reg_type) != 0) | 2507 | cmd, cdb, pr_reg_type) != 0) { |
2599 | return transport_handle_reservation_conflict(cmd); | 2508 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; |
2509 | cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; | ||
2510 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
2511 | return -EBUSY; | ||
2512 | } | ||
2600 | /* | 2513 | /* |
2601 | * This means the CDB is allowed for the SCSI Initiator port | 2514 | * This means the CDB is allowed for the SCSI Initiator port |
2602 | * when said port is *NOT* holding the legacy SPC-2 or | 2515 | * when said port is *NOT* holding the legacy SPC-2 or |
@@ -2658,7 +2571,8 @@ static int transport_generic_cmd_sequencer( | |||
2658 | goto out_unsupported_cdb; | 2571 | goto out_unsupported_cdb; |
2659 | size = transport_get_size(sectors, cdb, cmd); | 2572 | size = transport_get_size(sectors, cdb, cmd); |
2660 | cmd->t_task_lba = transport_lba_32(cdb); | 2573 | cmd->t_task_lba = transport_lba_32(cdb); |
2661 | cmd->t_tasks_fua = (cdb[1] & 0x8); | 2574 | if (cdb[1] & 0x8) |
2575 | cmd->se_cmd_flags |= SCF_FUA; | ||
2662 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; | 2576 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; |
2663 | break; | 2577 | break; |
2664 | case WRITE_12: | 2578 | case WRITE_12: |
@@ -2667,7 +2581,8 @@ static int transport_generic_cmd_sequencer( | |||
2667 | goto out_unsupported_cdb; | 2581 | goto out_unsupported_cdb; |
2668 | size = transport_get_size(sectors, cdb, cmd); | 2582 | size = transport_get_size(sectors, cdb, cmd); |
2669 | cmd->t_task_lba = transport_lba_32(cdb); | 2583 | cmd->t_task_lba = transport_lba_32(cdb); |
2670 | cmd->t_tasks_fua = (cdb[1] & 0x8); | 2584 | if (cdb[1] & 0x8) |
2585 | cmd->se_cmd_flags |= SCF_FUA; | ||
2671 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; | 2586 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; |
2672 | break; | 2587 | break; |
2673 | case WRITE_16: | 2588 | case WRITE_16: |
@@ -2676,12 +2591,13 @@ static int transport_generic_cmd_sequencer( | |||
2676 | goto out_unsupported_cdb; | 2591 | goto out_unsupported_cdb; |
2677 | size = transport_get_size(sectors, cdb, cmd); | 2592 | size = transport_get_size(sectors, cdb, cmd); |
2678 | cmd->t_task_lba = transport_lba_64(cdb); | 2593 | cmd->t_task_lba = transport_lba_64(cdb); |
2679 | cmd->t_tasks_fua = (cdb[1] & 0x8); | 2594 | if (cdb[1] & 0x8) |
2595 | cmd->se_cmd_flags |= SCF_FUA; | ||
2680 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; | 2596 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; |
2681 | break; | 2597 | break; |
2682 | case XDWRITEREAD_10: | 2598 | case XDWRITEREAD_10: |
2683 | if ((cmd->data_direction != DMA_TO_DEVICE) || | 2599 | if ((cmd->data_direction != DMA_TO_DEVICE) || |
2684 | !(cmd->t_tasks_bidi)) | 2600 | !(cmd->se_cmd_flags & SCF_BIDI)) |
2685 | goto out_invalid_cdb_field; | 2601 | goto out_invalid_cdb_field; |
2686 | sectors = transport_get_sectors_10(cdb, cmd, §or_ret); | 2602 | sectors = transport_get_sectors_10(cdb, cmd, §or_ret); |
2687 | if (sector_ret) | 2603 | if (sector_ret) |
@@ -2700,7 +2616,8 @@ static int transport_generic_cmd_sequencer( | |||
2700 | * Setup BIDI XOR callback to be run after I/O completion. | 2616 | * Setup BIDI XOR callback to be run after I/O completion. |
2701 | */ | 2617 | */ |
2702 | cmd->transport_complete_callback = &transport_xor_callback; | 2618 | cmd->transport_complete_callback = &transport_xor_callback; |
2703 | cmd->t_tasks_fua = (cdb[1] & 0x8); | 2619 | if (cdb[1] & 0x8) |
2620 | cmd->se_cmd_flags |= SCF_FUA; | ||
2704 | break; | 2621 | break; |
2705 | case VARIABLE_LENGTH_CMD: | 2622 | case VARIABLE_LENGTH_CMD: |
2706 | service_action = get_unaligned_be16(&cdb[8]); | 2623 | service_action = get_unaligned_be16(&cdb[8]); |
@@ -2728,7 +2645,8 @@ static int transport_generic_cmd_sequencer( | |||
2728 | * completion. | 2645 | * completion. |
2729 | */ | 2646 | */ |
2730 | cmd->transport_complete_callback = &transport_xor_callback; | 2647 | cmd->transport_complete_callback = &transport_xor_callback; |
2731 | cmd->t_tasks_fua = (cdb[10] & 0x8); | 2648 | if (cdb[1] & 0x8) |
2649 | cmd->se_cmd_flags |= SCF_FUA; | ||
2732 | break; | 2650 | break; |
2733 | case WRITE_SAME_32: | 2651 | case WRITE_SAME_32: |
2734 | sectors = transport_get_sectors_32(cdb, cmd, §or_ret); | 2652 | sectors = transport_get_sectors_32(cdb, cmd, §or_ret); |
@@ -3171,18 +3089,13 @@ static void transport_complete_task_attr(struct se_cmd *cmd) | |||
3171 | " SIMPLE: %u\n", dev->dev_cur_ordered_id, | 3089 | " SIMPLE: %u\n", dev->dev_cur_ordered_id, |
3172 | cmd->se_ordered_id); | 3090 | cmd->se_ordered_id); |
3173 | } else if (cmd->sam_task_attr == MSG_HEAD_TAG) { | 3091 | } else if (cmd->sam_task_attr == MSG_HEAD_TAG) { |
3174 | atomic_dec(&dev->dev_hoq_count); | ||
3175 | smp_mb__after_atomic_dec(); | ||
3176 | dev->dev_cur_ordered_id++; | 3092 | dev->dev_cur_ordered_id++; |
3177 | pr_debug("Incremented dev_cur_ordered_id: %u for" | 3093 | pr_debug("Incremented dev_cur_ordered_id: %u for" |
3178 | " HEAD_OF_QUEUE: %u\n", dev->dev_cur_ordered_id, | 3094 | " HEAD_OF_QUEUE: %u\n", dev->dev_cur_ordered_id, |
3179 | cmd->se_ordered_id); | 3095 | cmd->se_ordered_id); |
3180 | } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) { | 3096 | } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) { |
3181 | spin_lock(&dev->ordered_cmd_lock); | ||
3182 | list_del(&cmd->se_ordered_node); | ||
3183 | atomic_dec(&dev->dev_ordered_sync); | 3097 | atomic_dec(&dev->dev_ordered_sync); |
3184 | smp_mb__after_atomic_dec(); | 3098 | smp_mb__after_atomic_dec(); |
3185 | spin_unlock(&dev->ordered_cmd_lock); | ||
3186 | 3099 | ||
3187 | dev->dev_cur_ordered_id++; | 3100 | dev->dev_cur_ordered_id++; |
3188 | pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED:" | 3101 | pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED:" |
@@ -3495,6 +3408,18 @@ int transport_generic_map_mem_to_cmd( | |||
3495 | 3408 | ||
3496 | if ((cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) || | 3409 | if ((cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) || |
3497 | (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB)) { | 3410 | (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB)) { |
3411 | /* | ||
3412 | * Reject SCSI data overflow with map_mem_to_cmd() as incoming | ||
3413 | * scatterlists already have been set to follow what the fabric | ||
3414 | * passes for the original expected data transfer length. | ||
3415 | */ | ||
3416 | if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { | ||
3417 | pr_warn("Rejecting SCSI DATA overflow for fabric using" | ||
3418 | " SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC\n"); | ||
3419 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
3420 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
3421 | return -EINVAL; | ||
3422 | } | ||
3498 | 3423 | ||
3499 | cmd->t_data_sg = sgl; | 3424 | cmd->t_data_sg = sgl; |
3500 | cmd->t_data_nents = sgl_count; | 3425 | cmd->t_data_nents = sgl_count; |
@@ -3813,7 +3738,7 @@ int transport_generic_new_cmd(struct se_cmd *cmd) | |||
3813 | cmd->data_length) { | 3738 | cmd->data_length) { |
3814 | ret = transport_generic_get_mem(cmd); | 3739 | ret = transport_generic_get_mem(cmd); |
3815 | if (ret < 0) | 3740 | if (ret < 0) |
3816 | return ret; | 3741 | goto out_fail; |
3817 | } | 3742 | } |
3818 | 3743 | ||
3819 | /* | 3744 | /* |
@@ -3842,8 +3767,15 @@ int transport_generic_new_cmd(struct se_cmd *cmd) | |||
3842 | task_cdbs = transport_allocate_control_task(cmd); | 3767 | task_cdbs = transport_allocate_control_task(cmd); |
3843 | } | 3768 | } |
3844 | 3769 | ||
3845 | if (task_cdbs <= 0) | 3770 | if (task_cdbs < 0) |
3846 | goto out_fail; | 3771 | goto out_fail; |
3772 | else if (!task_cdbs && (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)) { | ||
3773 | cmd->t_state = TRANSPORT_COMPLETE; | ||
3774 | atomic_set(&cmd->t_transport_active, 1); | ||
3775 | INIT_WORK(&cmd->work, target_complete_ok_work); | ||
3776 | queue_work(target_completion_wq, &cmd->work); | ||
3777 | return 0; | ||
3778 | } | ||
3847 | 3779 | ||
3848 | if (set_counts) { | 3780 | if (set_counts) { |
3849 | atomic_inc(&cmd->t_fe_count); | 3781 | atomic_inc(&cmd->t_fe_count); |
@@ -3929,7 +3861,7 @@ static int transport_generic_write_pending(struct se_cmd *cmd) | |||
3929 | else if (ret < 0) | 3861 | else if (ret < 0) |
3930 | return ret; | 3862 | return ret; |
3931 | 3863 | ||
3932 | return PYX_TRANSPORT_WRITE_PENDING; | 3864 | return 1; |
3933 | 3865 | ||
3934 | queue_full: | 3866 | queue_full: |
3935 | pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); | 3867 | pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); |
@@ -4602,9 +4534,6 @@ void transport_send_task_abort(struct se_cmd *cmd) | |||
4602 | if (cmd->se_tfo->write_pending_status(cmd) != 0) { | 4534 | if (cmd->se_tfo->write_pending_status(cmd) != 0) { |
4603 | atomic_inc(&cmd->t_transport_aborted); | 4535 | atomic_inc(&cmd->t_transport_aborted); |
4604 | smp_mb__after_atomic_inc(); | 4536 | smp_mb__after_atomic_inc(); |
4605 | cmd->scsi_status = SAM_STAT_TASK_ABORTED; | ||
4606 | transport_new_cmd_failure(cmd); | ||
4607 | return; | ||
4608 | } | 4537 | } |
4609 | } | 4538 | } |
4610 | cmd->scsi_status = SAM_STAT_TASK_ABORTED; | 4539 | cmd->scsi_status = SAM_STAT_TASK_ABORTED; |
@@ -4670,8 +4599,6 @@ static int transport_processing_thread(void *param) | |||
4670 | struct se_cmd *cmd; | 4599 | struct se_cmd *cmd; |
4671 | struct se_device *dev = (struct se_device *) param; | 4600 | struct se_device *dev = (struct se_device *) param; |
4672 | 4601 | ||
4673 | set_user_nice(current, -20); | ||
4674 | |||
4675 | while (!kthread_should_stop()) { | 4602 | while (!kthread_should_stop()) { |
4676 | ret = wait_event_interruptible(dev->dev_queue_obj.thread_wq, | 4603 | ret = wait_event_interruptible(dev->dev_queue_obj.thread_wq, |
4677 | atomic_read(&dev->dev_queue_obj.queue_cnt) || | 4604 | atomic_read(&dev->dev_queue_obj.queue_cnt) || |
@@ -4698,18 +4625,13 @@ get_cmd: | |||
4698 | } | 4625 | } |
4699 | ret = cmd->se_tfo->new_cmd_map(cmd); | 4626 | ret = cmd->se_tfo->new_cmd_map(cmd); |
4700 | if (ret < 0) { | 4627 | if (ret < 0) { |
4701 | cmd->transport_error_status = ret; | 4628 | transport_generic_request_failure(cmd); |
4702 | transport_generic_request_failure(cmd, | ||
4703 | 0, (cmd->data_direction != | ||
4704 | DMA_TO_DEVICE)); | ||
4705 | break; | 4629 | break; |
4706 | } | 4630 | } |
4707 | ret = transport_generic_new_cmd(cmd); | 4631 | ret = transport_generic_new_cmd(cmd); |
4708 | if (ret < 0) { | 4632 | if (ret < 0) { |
4709 | cmd->transport_error_status = ret; | 4633 | transport_generic_request_failure(cmd); |
4710 | transport_generic_request_failure(cmd, | 4634 | break; |
4711 | 0, (cmd->data_direction != | ||
4712 | DMA_TO_DEVICE)); | ||
4713 | } | 4635 | } |
4714 | break; | 4636 | break; |
4715 | case TRANSPORT_PROCESS_WRITE: | 4637 | case TRANSPORT_PROCESS_WRITE: |
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index 4fac37c4c615..71fc9cea5dc9 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c | |||
@@ -200,7 +200,7 @@ int ft_write_pending(struct se_cmd *se_cmd) | |||
200 | lport = ep->lp; | 200 | lport = ep->lp; |
201 | fp = fc_frame_alloc(lport, sizeof(*txrdy)); | 201 | fp = fc_frame_alloc(lport, sizeof(*txrdy)); |
202 | if (!fp) | 202 | if (!fp) |
203 | return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; | 203 | return -ENOMEM; /* Signal QUEUE_FULL */ |
204 | 204 | ||
205 | txrdy = fc_frame_payload_get(fp, sizeof(*txrdy)); | 205 | txrdy = fc_frame_payload_get(fp, sizeof(*txrdy)); |
206 | memset(txrdy, 0, sizeof(*txrdy)); | 206 | memset(txrdy, 0, sizeof(*txrdy)); |
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index 5f770412ca40..9402b7387cac 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c | |||
@@ -436,8 +436,7 @@ static void ft_del_lport(struct se_wwn *wwn) | |||
436 | struct ft_lport_acl *lacl = container_of(wwn, | 436 | struct ft_lport_acl *lacl = container_of(wwn, |
437 | struct ft_lport_acl, fc_lport_wwn); | 437 | struct ft_lport_acl, fc_lport_wwn); |
438 | 438 | ||
439 | pr_debug("del lport %s\n", | 439 | pr_debug("del lport %s\n", lacl->name); |
440 | config_item_name(&wwn->wwn_group.cg_item)); | ||
441 | mutex_lock(&ft_lport_lock); | 440 | mutex_lock(&ft_lport_lock); |
442 | list_del(&lacl->list); | 441 | list_del(&lacl->list); |
443 | mutex_unlock(&ft_lport_lock); | 442 | mutex_unlock(&ft_lport_lock); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index f0d5718d2587..2ad813674d77 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -5107,11 +5107,11 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
5107 | struct btrfs_root *root = orig_root->fs_info->extent_root; | 5107 | struct btrfs_root *root = orig_root->fs_info->extent_root; |
5108 | struct btrfs_free_cluster *last_ptr = NULL; | 5108 | struct btrfs_free_cluster *last_ptr = NULL; |
5109 | struct btrfs_block_group_cache *block_group = NULL; | 5109 | struct btrfs_block_group_cache *block_group = NULL; |
5110 | struct btrfs_block_group_cache *used_block_group; | ||
5110 | int empty_cluster = 2 * 1024 * 1024; | 5111 | int empty_cluster = 2 * 1024 * 1024; |
5111 | int allowed_chunk_alloc = 0; | 5112 | int allowed_chunk_alloc = 0; |
5112 | int done_chunk_alloc = 0; | 5113 | int done_chunk_alloc = 0; |
5113 | struct btrfs_space_info *space_info; | 5114 | struct btrfs_space_info *space_info; |
5114 | int last_ptr_loop = 0; | ||
5115 | int loop = 0; | 5115 | int loop = 0; |
5116 | int index = 0; | 5116 | int index = 0; |
5117 | int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? | 5117 | int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? |
@@ -5173,6 +5173,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
5173 | ideal_cache: | 5173 | ideal_cache: |
5174 | block_group = btrfs_lookup_block_group(root->fs_info, | 5174 | block_group = btrfs_lookup_block_group(root->fs_info, |
5175 | search_start); | 5175 | search_start); |
5176 | used_block_group = block_group; | ||
5176 | /* | 5177 | /* |
5177 | * we don't want to use the block group if it doesn't match our | 5178 | * we don't want to use the block group if it doesn't match our |
5178 | * allocation bits, or if its not cached. | 5179 | * allocation bits, or if its not cached. |
@@ -5210,6 +5211,7 @@ search: | |||
5210 | u64 offset; | 5211 | u64 offset; |
5211 | int cached; | 5212 | int cached; |
5212 | 5213 | ||
5214 | used_block_group = block_group; | ||
5213 | btrfs_get_block_group(block_group); | 5215 | btrfs_get_block_group(block_group); |
5214 | search_start = block_group->key.objectid; | 5216 | search_start = block_group->key.objectid; |
5215 | 5217 | ||
@@ -5286,71 +5288,62 @@ alloc: | |||
5286 | spin_unlock(&block_group->free_space_ctl->tree_lock); | 5288 | spin_unlock(&block_group->free_space_ctl->tree_lock); |
5287 | 5289 | ||
5288 | /* | 5290 | /* |
5289 | * Ok we want to try and use the cluster allocator, so lets look | 5291 | * Ok we want to try and use the cluster allocator, so |
5290 | * there, unless we are on LOOP_NO_EMPTY_SIZE, since we will | 5292 | * lets look there |
5291 | * have tried the cluster allocator plenty of times at this | ||
5292 | * point and not have found anything, so we are likely way too | ||
5293 | * fragmented for the clustering stuff to find anything, so lets | ||
5294 | * just skip it and let the allocator find whatever block it can | ||
5295 | * find | ||
5296 | */ | 5293 | */ |
5297 | if (last_ptr && loop < LOOP_NO_EMPTY_SIZE) { | 5294 | if (last_ptr) { |
5298 | /* | 5295 | /* |
5299 | * the refill lock keeps out other | 5296 | * the refill lock keeps out other |
5300 | * people trying to start a new cluster | 5297 | * people trying to start a new cluster |
5301 | */ | 5298 | */ |
5302 | spin_lock(&last_ptr->refill_lock); | 5299 | spin_lock(&last_ptr->refill_lock); |
5303 | if (!last_ptr->block_group || | 5300 | used_block_group = last_ptr->block_group; |
5304 | last_ptr->block_group->ro || | 5301 | if (used_block_group != block_group && |
5305 | !block_group_bits(last_ptr->block_group, data)) | 5302 | (!used_block_group || |
5303 | used_block_group->ro || | ||
5304 | !block_group_bits(used_block_group, data))) { | ||
5305 | used_block_group = block_group; | ||
5306 | goto refill_cluster; | 5306 | goto refill_cluster; |
5307 | } | ||
5308 | |||
5309 | if (used_block_group != block_group) | ||
5310 | btrfs_get_block_group(used_block_group); | ||
5307 | 5311 | ||
5308 | offset = btrfs_alloc_from_cluster(block_group, last_ptr, | 5312 | offset = btrfs_alloc_from_cluster(used_block_group, |
5309 | num_bytes, search_start); | 5313 | last_ptr, num_bytes, used_block_group->key.objectid); |
5310 | if (offset) { | 5314 | if (offset) { |
5311 | /* we have a block, we're done */ | 5315 | /* we have a block, we're done */ |
5312 | spin_unlock(&last_ptr->refill_lock); | 5316 | spin_unlock(&last_ptr->refill_lock); |
5313 | goto checks; | 5317 | goto checks; |
5314 | } | 5318 | } |
5315 | 5319 | ||
5316 | spin_lock(&last_ptr->lock); | 5320 | WARN_ON(last_ptr->block_group != used_block_group); |
5317 | /* | 5321 | if (used_block_group != block_group) { |
5318 | * whoops, this cluster doesn't actually point to | 5322 | btrfs_put_block_group(used_block_group); |
5319 | * this block group. Get a ref on the block | 5323 | used_block_group = block_group; |
5320 | * group is does point to and try again | ||
5321 | */ | ||
5322 | if (!last_ptr_loop && last_ptr->block_group && | ||
5323 | last_ptr->block_group != block_group && | ||
5324 | index <= | ||
5325 | get_block_group_index(last_ptr->block_group)) { | ||
5326 | |||
5327 | btrfs_put_block_group(block_group); | ||
5328 | block_group = last_ptr->block_group; | ||
5329 | btrfs_get_block_group(block_group); | ||
5330 | spin_unlock(&last_ptr->lock); | ||
5331 | spin_unlock(&last_ptr->refill_lock); | ||
5332 | |||
5333 | last_ptr_loop = 1; | ||
5334 | search_start = block_group->key.objectid; | ||
5335 | /* | ||
5336 | * we know this block group is properly | ||
5337 | * in the list because | ||
5338 | * btrfs_remove_block_group, drops the | ||
5339 | * cluster before it removes the block | ||
5340 | * group from the list | ||
5341 | */ | ||
5342 | goto have_block_group; | ||
5343 | } | 5324 | } |
5344 | spin_unlock(&last_ptr->lock); | ||
5345 | refill_cluster: | 5325 | refill_cluster: |
5326 | BUG_ON(used_block_group != block_group); | ||
5327 | /* If we are on LOOP_NO_EMPTY_SIZE, we can't | ||
5328 | * set up a new clusters, so lets just skip it | ||
5329 | * and let the allocator find whatever block | ||
5330 | * it can find. If we reach this point, we | ||
5331 | * will have tried the cluster allocator | ||
5332 | * plenty of times and not have found | ||
5333 | * anything, so we are likely way too | ||
5334 | * fragmented for the clustering stuff to find | ||
5335 | * anything. */ | ||
5336 | if (loop >= LOOP_NO_EMPTY_SIZE) { | ||
5337 | spin_unlock(&last_ptr->refill_lock); | ||
5338 | goto unclustered_alloc; | ||
5339 | } | ||
5340 | |||
5346 | /* | 5341 | /* |
5347 | * this cluster didn't work out, free it and | 5342 | * this cluster didn't work out, free it and |
5348 | * start over | 5343 | * start over |
5349 | */ | 5344 | */ |
5350 | btrfs_return_cluster_to_free_space(NULL, last_ptr); | 5345 | btrfs_return_cluster_to_free_space(NULL, last_ptr); |
5351 | 5346 | ||
5352 | last_ptr_loop = 0; | ||
5353 | |||
5354 | /* allocate a cluster in this block group */ | 5347 | /* allocate a cluster in this block group */ |
5355 | ret = btrfs_find_space_cluster(trans, root, | 5348 | ret = btrfs_find_space_cluster(trans, root, |
5356 | block_group, last_ptr, | 5349 | block_group, last_ptr, |
@@ -5390,6 +5383,7 @@ refill_cluster: | |||
5390 | goto loop; | 5383 | goto loop; |
5391 | } | 5384 | } |
5392 | 5385 | ||
5386 | unclustered_alloc: | ||
5393 | offset = btrfs_find_space_for_alloc(block_group, search_start, | 5387 | offset = btrfs_find_space_for_alloc(block_group, search_start, |
5394 | num_bytes, empty_size); | 5388 | num_bytes, empty_size); |
5395 | /* | 5389 | /* |
@@ -5416,14 +5410,14 @@ checks: | |||
5416 | search_start = stripe_align(root, offset); | 5410 | search_start = stripe_align(root, offset); |
5417 | /* move on to the next group */ | 5411 | /* move on to the next group */ |
5418 | if (search_start + num_bytes >= search_end) { | 5412 | if (search_start + num_bytes >= search_end) { |
5419 | btrfs_add_free_space(block_group, offset, num_bytes); | 5413 | btrfs_add_free_space(used_block_group, offset, num_bytes); |
5420 | goto loop; | 5414 | goto loop; |
5421 | } | 5415 | } |
5422 | 5416 | ||
5423 | /* move on to the next group */ | 5417 | /* move on to the next group */ |
5424 | if (search_start + num_bytes > | 5418 | if (search_start + num_bytes > |
5425 | block_group->key.objectid + block_group->key.offset) { | 5419 | used_block_group->key.objectid + used_block_group->key.offset) { |
5426 | btrfs_add_free_space(block_group, offset, num_bytes); | 5420 | btrfs_add_free_space(used_block_group, offset, num_bytes); |
5427 | goto loop; | 5421 | goto loop; |
5428 | } | 5422 | } |
5429 | 5423 | ||
@@ -5431,14 +5425,14 @@ checks: | |||
5431 | ins->offset = num_bytes; | 5425 | ins->offset = num_bytes; |
5432 | 5426 | ||
5433 | if (offset < search_start) | 5427 | if (offset < search_start) |
5434 | btrfs_add_free_space(block_group, offset, | 5428 | btrfs_add_free_space(used_block_group, offset, |
5435 | search_start - offset); | 5429 | search_start - offset); |
5436 | BUG_ON(offset > search_start); | 5430 | BUG_ON(offset > search_start); |
5437 | 5431 | ||
5438 | ret = btrfs_update_reserved_bytes(block_group, num_bytes, | 5432 | ret = btrfs_update_reserved_bytes(used_block_group, num_bytes, |
5439 | alloc_type); | 5433 | alloc_type); |
5440 | if (ret == -EAGAIN) { | 5434 | if (ret == -EAGAIN) { |
5441 | btrfs_add_free_space(block_group, offset, num_bytes); | 5435 | btrfs_add_free_space(used_block_group, offset, num_bytes); |
5442 | goto loop; | 5436 | goto loop; |
5443 | } | 5437 | } |
5444 | 5438 | ||
@@ -5447,15 +5441,19 @@ checks: | |||
5447 | ins->offset = num_bytes; | 5441 | ins->offset = num_bytes; |
5448 | 5442 | ||
5449 | if (offset < search_start) | 5443 | if (offset < search_start) |
5450 | btrfs_add_free_space(block_group, offset, | 5444 | btrfs_add_free_space(used_block_group, offset, |
5451 | search_start - offset); | 5445 | search_start - offset); |
5452 | BUG_ON(offset > search_start); | 5446 | BUG_ON(offset > search_start); |
5447 | if (used_block_group != block_group) | ||
5448 | btrfs_put_block_group(used_block_group); | ||
5453 | btrfs_put_block_group(block_group); | 5449 | btrfs_put_block_group(block_group); |
5454 | break; | 5450 | break; |
5455 | loop: | 5451 | loop: |
5456 | failed_cluster_refill = false; | 5452 | failed_cluster_refill = false; |
5457 | failed_alloc = false; | 5453 | failed_alloc = false; |
5458 | BUG_ON(index != get_block_group_index(block_group)); | 5454 | BUG_ON(index != get_block_group_index(block_group)); |
5455 | if (used_block_group != block_group) | ||
5456 | btrfs_put_block_group(used_block_group); | ||
5459 | btrfs_put_block_group(block_group); | 5457 | btrfs_put_block_group(block_group); |
5460 | } | 5458 | } |
5461 | up_read(&space_info->groups_sem); | 5459 | up_read(&space_info->groups_sem); |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index be1bf627a14b..49f3c9dc09f4 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -935,8 +935,10 @@ again: | |||
935 | node = tree_search(tree, start); | 935 | node = tree_search(tree, start); |
936 | if (!node) { | 936 | if (!node) { |
937 | prealloc = alloc_extent_state_atomic(prealloc); | 937 | prealloc = alloc_extent_state_atomic(prealloc); |
938 | if (!prealloc) | 938 | if (!prealloc) { |
939 | return -ENOMEM; | 939 | err = -ENOMEM; |
940 | goto out; | ||
941 | } | ||
940 | err = insert_state(tree, prealloc, start, end, &bits); | 942 | err = insert_state(tree, prealloc, start, end, &bits); |
941 | prealloc = NULL; | 943 | prealloc = NULL; |
942 | BUG_ON(err == -EEXIST); | 944 | BUG_ON(err == -EEXIST); |
@@ -992,8 +994,10 @@ hit_next: | |||
992 | */ | 994 | */ |
993 | if (state->start < start) { | 995 | if (state->start < start) { |
994 | prealloc = alloc_extent_state_atomic(prealloc); | 996 | prealloc = alloc_extent_state_atomic(prealloc); |
995 | if (!prealloc) | 997 | if (!prealloc) { |
996 | return -ENOMEM; | 998 | err = -ENOMEM; |
999 | goto out; | ||
1000 | } | ||
997 | err = split_state(tree, state, prealloc, start); | 1001 | err = split_state(tree, state, prealloc, start); |
998 | BUG_ON(err == -EEXIST); | 1002 | BUG_ON(err == -EEXIST); |
999 | prealloc = NULL; | 1003 | prealloc = NULL; |
@@ -1024,8 +1028,10 @@ hit_next: | |||
1024 | this_end = last_start - 1; | 1028 | this_end = last_start - 1; |
1025 | 1029 | ||
1026 | prealloc = alloc_extent_state_atomic(prealloc); | 1030 | prealloc = alloc_extent_state_atomic(prealloc); |
1027 | if (!prealloc) | 1031 | if (!prealloc) { |
1028 | return -ENOMEM; | 1032 | err = -ENOMEM; |
1033 | goto out; | ||
1034 | } | ||
1029 | 1035 | ||
1030 | /* | 1036 | /* |
1031 | * Avoid to free 'prealloc' if it can be merged with | 1037 | * Avoid to free 'prealloc' if it can be merged with |
@@ -1051,8 +1057,10 @@ hit_next: | |||
1051 | */ | 1057 | */ |
1052 | if (state->start <= end && state->end > end) { | 1058 | if (state->start <= end && state->end > end) { |
1053 | prealloc = alloc_extent_state_atomic(prealloc); | 1059 | prealloc = alloc_extent_state_atomic(prealloc); |
1054 | if (!prealloc) | 1060 | if (!prealloc) { |
1055 | return -ENOMEM; | 1061 | err = -ENOMEM; |
1062 | goto out; | ||
1063 | } | ||
1056 | 1064 | ||
1057 | err = split_state(tree, state, prealloc, end + 1); | 1065 | err = split_state(tree, state, prealloc, end + 1); |
1058 | BUG_ON(err == -EEXIST); | 1066 | BUG_ON(err == -EEXIST); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index c37433d3cd82..0a8c8f8304b1 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1611,7 +1611,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1611 | if ((sb->s_flags & MS_RDONLY) && !root->fs_info->fs_devices->seeding) | 1611 | if ((sb->s_flags & MS_RDONLY) && !root->fs_info->fs_devices->seeding) |
1612 | return -EINVAL; | 1612 | return -EINVAL; |
1613 | 1613 | ||
1614 | bdev = blkdev_get_by_path(device_path, FMODE_EXCL, | 1614 | bdev = blkdev_get_by_path(device_path, FMODE_WRITE | FMODE_EXCL, |
1615 | root->fs_info->bdev_holder); | 1615 | root->fs_info->bdev_holder); |
1616 | if (IS_ERR(bdev)) | 1616 | if (IS_ERR(bdev)) |
1617 | return PTR_ERR(bdev); | 1617 | return PTR_ERR(bdev); |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index d6a972df0338..8cd4b52d4217 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -441,6 +441,8 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig, | |||
441 | smb_msg.msg_controllen = 0; | 441 | smb_msg.msg_controllen = 0; |
442 | 442 | ||
443 | for (total_read = 0; to_read; total_read += length, to_read -= length) { | 443 | for (total_read = 0; to_read; total_read += length, to_read -= length) { |
444 | try_to_freeze(); | ||
445 | |||
444 | if (server_unresponsive(server)) { | 446 | if (server_unresponsive(server)) { |
445 | total_read = -EAGAIN; | 447 | total_read = -EAGAIN; |
446 | break; | 448 | break; |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index cf0b1539b321..4dd9283885e7 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -702,6 +702,13 @@ cifs_find_lock_conflict(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock, | |||
702 | lock->type, lock->netfid, conf_lock); | 702 | lock->type, lock->netfid, conf_lock); |
703 | } | 703 | } |
704 | 704 | ||
705 | /* | ||
706 | * Check if there is another lock that prevents us to set the lock (mandatory | ||
707 | * style). If such a lock exists, update the flock structure with its | ||
708 | * properties. Otherwise, set the flock type to F_UNLCK if we can cache brlocks | ||
709 | * or leave it the same if we can't. Returns 0 if we don't need to request to | ||
710 | * the server or 1 otherwise. | ||
711 | */ | ||
705 | static int | 712 | static int |
706 | cifs_lock_test(struct cifsInodeInfo *cinode, __u64 offset, __u64 length, | 713 | cifs_lock_test(struct cifsInodeInfo *cinode, __u64 offset, __u64 length, |
707 | __u8 type, __u16 netfid, struct file_lock *flock) | 714 | __u8 type, __u16 netfid, struct file_lock *flock) |
@@ -739,6 +746,12 @@ cifs_lock_add(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock) | |||
739 | mutex_unlock(&cinode->lock_mutex); | 746 | mutex_unlock(&cinode->lock_mutex); |
740 | } | 747 | } |
741 | 748 | ||
749 | /* | ||
750 | * Set the byte-range lock (mandatory style). Returns: | ||
751 | * 1) 0, if we set the lock and don't need to request to the server; | ||
752 | * 2) 1, if no locks prevent us but we need to request to the server; | ||
753 | * 3) -EACCESS, if there is a lock that prevents us and wait is false. | ||
754 | */ | ||
742 | static int | 755 | static int |
743 | cifs_lock_add_if(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock, | 756 | cifs_lock_add_if(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock, |
744 | bool wait) | 757 | bool wait) |
@@ -778,6 +791,13 @@ try_again: | |||
778 | return rc; | 791 | return rc; |
779 | } | 792 | } |
780 | 793 | ||
794 | /* | ||
795 | * Check if there is another lock that prevents us to set the lock (posix | ||
796 | * style). If such a lock exists, update the flock structure with its | ||
797 | * properties. Otherwise, set the flock type to F_UNLCK if we can cache brlocks | ||
798 | * or leave it the same if we can't. Returns 0 if we don't need to request to | ||
799 | * the server or 1 otherwise. | ||
800 | */ | ||
781 | static int | 801 | static int |
782 | cifs_posix_lock_test(struct file *file, struct file_lock *flock) | 802 | cifs_posix_lock_test(struct file *file, struct file_lock *flock) |
783 | { | 803 | { |
@@ -800,6 +820,12 @@ cifs_posix_lock_test(struct file *file, struct file_lock *flock) | |||
800 | return rc; | 820 | return rc; |
801 | } | 821 | } |
802 | 822 | ||
823 | /* | ||
824 | * Set the byte-range lock (posix style). Returns: | ||
825 | * 1) 0, if we set the lock and don't need to request to the server; | ||
826 | * 2) 1, if we need to request to the server; | ||
827 | * 3) <0, if the error occurs while setting the lock. | ||
828 | */ | ||
803 | static int | 829 | static int |
804 | cifs_posix_lock_set(struct file *file, struct file_lock *flock) | 830 | cifs_posix_lock_set(struct file *file, struct file_lock *flock) |
805 | { | 831 | { |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 5de03ec20144..a090bbe6ee29 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -554,7 +554,10 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon, | |||
554 | rc); | 554 | rc); |
555 | return rc; | 555 | return rc; |
556 | } | 556 | } |
557 | cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile); | 557 | /* FindFirst/Next set last_entry to NULL on malformed reply */ |
558 | if (cifsFile->srch_inf.last_entry) | ||
559 | cifs_save_resume_key(cifsFile->srch_inf.last_entry, | ||
560 | cifsFile); | ||
558 | } | 561 | } |
559 | 562 | ||
560 | while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && | 563 | while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && |
@@ -562,7 +565,10 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon, | |||
562 | cFYI(1, "calling findnext2"); | 565 | cFYI(1, "calling findnext2"); |
563 | rc = CIFSFindNext(xid, pTcon, cifsFile->netfid, | 566 | rc = CIFSFindNext(xid, pTcon, cifsFile->netfid, |
564 | &cifsFile->srch_inf); | 567 | &cifsFile->srch_inf); |
565 | cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile); | 568 | /* FindFirst/Next set last_entry to NULL on malformed reply */ |
569 | if (cifsFile->srch_inf.last_entry) | ||
570 | cifs_save_resume_key(cifsFile->srch_inf.last_entry, | ||
571 | cifsFile); | ||
566 | if (rc) | 572 | if (rc) |
567 | return -ENOENT; | 573 | return -ENOENT; |
568 | } | 574 | } |
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c index 7cacba12b8f1..80d850881938 100644 --- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c | |||
@@ -209,7 +209,7 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16, | |||
209 | { | 209 | { |
210 | int rc; | 210 | int rc; |
211 | int len; | 211 | int len; |
212 | __u16 wpwd[129]; | 212 | __le16 wpwd[129]; |
213 | 213 | ||
214 | /* Password cannot be longer than 128 characters */ | 214 | /* Password cannot be longer than 128 characters */ |
215 | if (passwd) /* Password must be converted to NT unicode */ | 215 | if (passwd) /* Password must be converted to NT unicode */ |
@@ -219,8 +219,8 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16, | |||
219 | *wpwd = 0; /* Ensure string is null terminated */ | 219 | *wpwd = 0; /* Ensure string is null terminated */ |
220 | } | 220 | } |
221 | 221 | ||
222 | rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__u16)); | 222 | rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__le16)); |
223 | memset(wpwd, 0, 129 * sizeof(__u16)); | 223 | memset(wpwd, 0, 129 * sizeof(__le16)); |
224 | 224 | ||
225 | return rc; | 225 | return rc; |
226 | } | 226 | } |
diff --git a/fs/dcache.c b/fs/dcache.c index 10ba92def3f6..89509b5a090e 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -2439,16 +2439,14 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name) | |||
2439 | /** | 2439 | /** |
2440 | * prepend_path - Prepend path string to a buffer | 2440 | * prepend_path - Prepend path string to a buffer |
2441 | * @path: the dentry/vfsmount to report | 2441 | * @path: the dentry/vfsmount to report |
2442 | * @root: root vfsmnt/dentry (may be modified by this function) | 2442 | * @root: root vfsmnt/dentry |
2443 | * @buffer: pointer to the end of the buffer | 2443 | * @buffer: pointer to the end of the buffer |
2444 | * @buflen: pointer to buffer length | 2444 | * @buflen: pointer to buffer length |
2445 | * | 2445 | * |
2446 | * Caller holds the rename_lock. | 2446 | * Caller holds the rename_lock. |
2447 | * | ||
2448 | * If path is not reachable from the supplied root, then the value of | ||
2449 | * root is changed (without modifying refcounts). | ||
2450 | */ | 2447 | */ |
2451 | static int prepend_path(const struct path *path, struct path *root, | 2448 | static int prepend_path(const struct path *path, |
2449 | const struct path *root, | ||
2452 | char **buffer, int *buflen) | 2450 | char **buffer, int *buflen) |
2453 | { | 2451 | { |
2454 | struct dentry *dentry = path->dentry; | 2452 | struct dentry *dentry = path->dentry; |
@@ -2483,10 +2481,10 @@ static int prepend_path(const struct path *path, struct path *root, | |||
2483 | dentry = parent; | 2481 | dentry = parent; |
2484 | } | 2482 | } |
2485 | 2483 | ||
2486 | out: | ||
2487 | if (!error && !slash) | 2484 | if (!error && !slash) |
2488 | error = prepend(buffer, buflen, "/", 1); | 2485 | error = prepend(buffer, buflen, "/", 1); |
2489 | 2486 | ||
2487 | out: | ||
2490 | br_read_unlock(vfsmount_lock); | 2488 | br_read_unlock(vfsmount_lock); |
2491 | return error; | 2489 | return error; |
2492 | 2490 | ||
@@ -2500,15 +2498,17 @@ global_root: | |||
2500 | WARN(1, "Root dentry has weird name <%.*s>\n", | 2498 | WARN(1, "Root dentry has weird name <%.*s>\n", |
2501 | (int) dentry->d_name.len, dentry->d_name.name); | 2499 | (int) dentry->d_name.len, dentry->d_name.name); |
2502 | } | 2500 | } |
2503 | root->mnt = vfsmnt; | 2501 | if (!slash) |
2504 | root->dentry = dentry; | 2502 | error = prepend(buffer, buflen, "/", 1); |
2503 | if (!error) | ||
2504 | error = vfsmnt->mnt_ns ? 1 : 2; | ||
2505 | goto out; | 2505 | goto out; |
2506 | } | 2506 | } |
2507 | 2507 | ||
2508 | /** | 2508 | /** |
2509 | * __d_path - return the path of a dentry | 2509 | * __d_path - return the path of a dentry |
2510 | * @path: the dentry/vfsmount to report | 2510 | * @path: the dentry/vfsmount to report |
2511 | * @root: root vfsmnt/dentry (may be modified by this function) | 2511 | * @root: root vfsmnt/dentry |
2512 | * @buf: buffer to return value in | 2512 | * @buf: buffer to return value in |
2513 | * @buflen: buffer length | 2513 | * @buflen: buffer length |
2514 | * | 2514 | * |
@@ -2519,10 +2519,10 @@ global_root: | |||
2519 | * | 2519 | * |
2520 | * "buflen" should be positive. | 2520 | * "buflen" should be positive. |
2521 | * | 2521 | * |
2522 | * If path is not reachable from the supplied root, then the value of | 2522 | * If the path is not reachable from the supplied root, return %NULL. |
2523 | * root is changed (without modifying refcounts). | ||
2524 | */ | 2523 | */ |
2525 | char *__d_path(const struct path *path, struct path *root, | 2524 | char *__d_path(const struct path *path, |
2525 | const struct path *root, | ||
2526 | char *buf, int buflen) | 2526 | char *buf, int buflen) |
2527 | { | 2527 | { |
2528 | char *res = buf + buflen; | 2528 | char *res = buf + buflen; |
@@ -2533,7 +2533,28 @@ char *__d_path(const struct path *path, struct path *root, | |||
2533 | error = prepend_path(path, root, &res, &buflen); | 2533 | error = prepend_path(path, root, &res, &buflen); |
2534 | write_sequnlock(&rename_lock); | 2534 | write_sequnlock(&rename_lock); |
2535 | 2535 | ||
2536 | if (error) | 2536 | if (error < 0) |
2537 | return ERR_PTR(error); | ||
2538 | if (error > 0) | ||
2539 | return NULL; | ||
2540 | return res; | ||
2541 | } | ||
2542 | |||
2543 | char *d_absolute_path(const struct path *path, | ||
2544 | char *buf, int buflen) | ||
2545 | { | ||
2546 | struct path root = {}; | ||
2547 | char *res = buf + buflen; | ||
2548 | int error; | ||
2549 | |||
2550 | prepend(&res, &buflen, "\0", 1); | ||
2551 | write_seqlock(&rename_lock); | ||
2552 | error = prepend_path(path, &root, &res, &buflen); | ||
2553 | write_sequnlock(&rename_lock); | ||
2554 | |||
2555 | if (error > 1) | ||
2556 | error = -EINVAL; | ||
2557 | if (error < 0) | ||
2537 | return ERR_PTR(error); | 2558 | return ERR_PTR(error); |
2538 | return res; | 2559 | return res; |
2539 | } | 2560 | } |
@@ -2541,8 +2562,9 @@ char *__d_path(const struct path *path, struct path *root, | |||
2541 | /* | 2562 | /* |
2542 | * same as __d_path but appends "(deleted)" for unlinked files. | 2563 | * same as __d_path but appends "(deleted)" for unlinked files. |
2543 | */ | 2564 | */ |
2544 | static int path_with_deleted(const struct path *path, struct path *root, | 2565 | static int path_with_deleted(const struct path *path, |
2545 | char **buf, int *buflen) | 2566 | const struct path *root, |
2567 | char **buf, int *buflen) | ||
2546 | { | 2568 | { |
2547 | prepend(buf, buflen, "\0", 1); | 2569 | prepend(buf, buflen, "\0", 1); |
2548 | if (d_unlinked(path->dentry)) { | 2570 | if (d_unlinked(path->dentry)) { |
@@ -2579,7 +2601,6 @@ char *d_path(const struct path *path, char *buf, int buflen) | |||
2579 | { | 2601 | { |
2580 | char *res = buf + buflen; | 2602 | char *res = buf + buflen; |
2581 | struct path root; | 2603 | struct path root; |
2582 | struct path tmp; | ||
2583 | int error; | 2604 | int error; |
2584 | 2605 | ||
2585 | /* | 2606 | /* |
@@ -2594,9 +2615,8 @@ char *d_path(const struct path *path, char *buf, int buflen) | |||
2594 | 2615 | ||
2595 | get_fs_root(current->fs, &root); | 2616 | get_fs_root(current->fs, &root); |
2596 | write_seqlock(&rename_lock); | 2617 | write_seqlock(&rename_lock); |
2597 | tmp = root; | 2618 | error = path_with_deleted(path, &root, &res, &buflen); |
2598 | error = path_with_deleted(path, &tmp, &res, &buflen); | 2619 | if (error < 0) |
2599 | if (error) | ||
2600 | res = ERR_PTR(error); | 2620 | res = ERR_PTR(error); |
2601 | write_sequnlock(&rename_lock); | 2621 | write_sequnlock(&rename_lock); |
2602 | path_put(&root); | 2622 | path_put(&root); |
@@ -2617,7 +2637,6 @@ char *d_path_with_unreachable(const struct path *path, char *buf, int buflen) | |||
2617 | { | 2637 | { |
2618 | char *res = buf + buflen; | 2638 | char *res = buf + buflen; |
2619 | struct path root; | 2639 | struct path root; |
2620 | struct path tmp; | ||
2621 | int error; | 2640 | int error; |
2622 | 2641 | ||
2623 | if (path->dentry->d_op && path->dentry->d_op->d_dname) | 2642 | if (path->dentry->d_op && path->dentry->d_op->d_dname) |
@@ -2625,9 +2644,8 @@ char *d_path_with_unreachable(const struct path *path, char *buf, int buflen) | |||
2625 | 2644 | ||
2626 | get_fs_root(current->fs, &root); | 2645 | get_fs_root(current->fs, &root); |
2627 | write_seqlock(&rename_lock); | 2646 | write_seqlock(&rename_lock); |
2628 | tmp = root; | 2647 | error = path_with_deleted(path, &root, &res, &buflen); |
2629 | error = path_with_deleted(path, &tmp, &res, &buflen); | 2648 | if (error > 0) |
2630 | if (!error && !path_equal(&tmp, &root)) | ||
2631 | error = prepend_unreachable(&res, &buflen); | 2649 | error = prepend_unreachable(&res, &buflen); |
2632 | write_sequnlock(&rename_lock); | 2650 | write_sequnlock(&rename_lock); |
2633 | path_put(&root); | 2651 | path_put(&root); |
@@ -2758,19 +2776,18 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) | |||
2758 | write_seqlock(&rename_lock); | 2776 | write_seqlock(&rename_lock); |
2759 | if (!d_unlinked(pwd.dentry)) { | 2777 | if (!d_unlinked(pwd.dentry)) { |
2760 | unsigned long len; | 2778 | unsigned long len; |
2761 | struct path tmp = root; | ||
2762 | char *cwd = page + PAGE_SIZE; | 2779 | char *cwd = page + PAGE_SIZE; |
2763 | int buflen = PAGE_SIZE; | 2780 | int buflen = PAGE_SIZE; |
2764 | 2781 | ||
2765 | prepend(&cwd, &buflen, "\0", 1); | 2782 | prepend(&cwd, &buflen, "\0", 1); |
2766 | error = prepend_path(&pwd, &tmp, &cwd, &buflen); | 2783 | error = prepend_path(&pwd, &root, &cwd, &buflen); |
2767 | write_sequnlock(&rename_lock); | 2784 | write_sequnlock(&rename_lock); |
2768 | 2785 | ||
2769 | if (error) | 2786 | if (error < 0) |
2770 | goto out; | 2787 | goto out; |
2771 | 2788 | ||
2772 | /* Unreachable from current root */ | 2789 | /* Unreachable from current root */ |
2773 | if (!path_equal(&tmp, &root)) { | 2790 | if (error > 0) { |
2774 | error = prepend_unreachable(&cwd, &buflen); | 2791 | error = prepend_unreachable(&cwd, &buflen); |
2775 | if (error) | 2792 | if (error) |
2776 | goto out; | 2793 | goto out; |
diff --git a/fs/namespace.c b/fs/namespace.c index 6d3a1963879b..cfc6d4448aa5 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -1048,15 +1048,12 @@ static int show_mountinfo(struct seq_file *m, void *v) | |||
1048 | if (err) | 1048 | if (err) |
1049 | goto out; | 1049 | goto out; |
1050 | seq_putc(m, ' '); | 1050 | seq_putc(m, ' '); |
1051 | seq_path_root(m, &mnt_path, &root, " \t\n\\"); | 1051 | |
1052 | if (root.mnt != p->root.mnt || root.dentry != p->root.dentry) { | 1052 | /* mountpoints outside of chroot jail will give SEQ_SKIP on this */ |
1053 | /* | 1053 | err = seq_path_root(m, &mnt_path, &root, " \t\n\\"); |
1054 | * Mountpoint is outside root, discard that one. Ugly, | 1054 | if (err) |
1055 | * but less so than trying to do that in iterator in a | 1055 | goto out; |
1056 | * race-free way (due to renames). | 1056 | |
1057 | */ | ||
1058 | return SEQ_SKIP; | ||
1059 | } | ||
1060 | seq_puts(m, mnt->mnt_flags & MNT_READONLY ? " ro" : " rw"); | 1057 | seq_puts(m, mnt->mnt_flags & MNT_READONLY ? " ro" : " rw"); |
1061 | show_mnt_opts(m, mnt); | 1058 | show_mnt_opts(m, mnt); |
1062 | 1059 | ||
@@ -2776,3 +2773,8 @@ void kern_unmount(struct vfsmount *mnt) | |||
2776 | } | 2773 | } |
2777 | } | 2774 | } |
2778 | EXPORT_SYMBOL(kern_unmount); | 2775 | EXPORT_SYMBOL(kern_unmount); |
2776 | |||
2777 | bool our_mnt(struct vfsmount *mnt) | ||
2778 | { | ||
2779 | return check_mnt(mnt); | ||
2780 | } | ||
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index 586174168e2a..80e4645f7990 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c | |||
@@ -131,12 +131,13 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
131 | K(i.freeswap), | 131 | K(i.freeswap), |
132 | K(global_page_state(NR_FILE_DIRTY)), | 132 | K(global_page_state(NR_FILE_DIRTY)), |
133 | K(global_page_state(NR_WRITEBACK)), | 133 | K(global_page_state(NR_WRITEBACK)), |
134 | K(global_page_state(NR_ANON_PAGES) | ||
135 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 134 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
135 | K(global_page_state(NR_ANON_PAGES) | ||
136 | + global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * | 136 | + global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * |
137 | HPAGE_PMD_NR | 137 | HPAGE_PMD_NR), |
138 | #else | ||
139 | K(global_page_state(NR_ANON_PAGES)), | ||
138 | #endif | 140 | #endif |
139 | ), | ||
140 | K(global_page_state(NR_FILE_MAPPED)), | 141 | K(global_page_state(NR_FILE_MAPPED)), |
141 | K(global_page_state(NR_SHMEM)), | 142 | K(global_page_state(NR_SHMEM)), |
142 | K(global_page_state(NR_SLAB_RECLAIMABLE) + | 143 | K(global_page_state(NR_SLAB_RECLAIMABLE) + |
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index 42b274da92c3..2a30d67dd6b8 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c | |||
@@ -32,7 +32,7 @@ static cputime64_t get_idle_time(int cpu) | |||
32 | idle = kstat_cpu(cpu).cpustat.idle; | 32 | idle = kstat_cpu(cpu).cpustat.idle; |
33 | idle = cputime64_add(idle, arch_idle_time(cpu)); | 33 | idle = cputime64_add(idle, arch_idle_time(cpu)); |
34 | } else | 34 | } else |
35 | idle = usecs_to_cputime(idle_time); | 35 | idle = nsecs_to_jiffies64(1000 * idle_time); |
36 | 36 | ||
37 | return idle; | 37 | return idle; |
38 | } | 38 | } |
@@ -46,7 +46,7 @@ static cputime64_t get_iowait_time(int cpu) | |||
46 | /* !NO_HZ so we can rely on cpustat.iowait */ | 46 | /* !NO_HZ so we can rely on cpustat.iowait */ |
47 | iowait = kstat_cpu(cpu).cpustat.iowait; | 47 | iowait = kstat_cpu(cpu).cpustat.iowait; |
48 | else | 48 | else |
49 | iowait = usecs_to_cputime(iowait_time); | 49 | iowait = nsecs_to_jiffies64(1000 * iowait_time); |
50 | 50 | ||
51 | return iowait; | 51 | return iowait; |
52 | } | 52 | } |
diff --git a/fs/seq_file.c b/fs/seq_file.c index 05d6b0e78c95..dba43c3ea3af 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
@@ -449,8 +449,6 @@ EXPORT_SYMBOL(seq_path); | |||
449 | 449 | ||
450 | /* | 450 | /* |
451 | * Same as seq_path, but relative to supplied root. | 451 | * Same as seq_path, but relative to supplied root. |
452 | * | ||
453 | * root may be changed, see __d_path(). | ||
454 | */ | 452 | */ |
455 | int seq_path_root(struct seq_file *m, struct path *path, struct path *root, | 453 | int seq_path_root(struct seq_file *m, struct path *path, struct path *root, |
456 | char *esc) | 454 | char *esc) |
@@ -463,6 +461,8 @@ int seq_path_root(struct seq_file *m, struct path *path, struct path *root, | |||
463 | char *p; | 461 | char *p; |
464 | 462 | ||
465 | p = __d_path(path, root, buf, size); | 463 | p = __d_path(path, root, buf, size); |
464 | if (!p) | ||
465 | return SEQ_SKIP; | ||
466 | res = PTR_ERR(p); | 466 | res = PTR_ERR(p); |
467 | if (!IS_ERR(p)) { | 467 | if (!IS_ERR(p)) { |
468 | char *end = mangle_path(buf, p, esc); | 468 | char *end = mangle_path(buf, p, esc); |
@@ -474,7 +474,7 @@ int seq_path_root(struct seq_file *m, struct path *path, struct path *root, | |||
474 | } | 474 | } |
475 | seq_commit(m, res); | 475 | seq_commit(m, res); |
476 | 476 | ||
477 | return res < 0 ? res : 0; | 477 | return res < 0 && res != -ENAMETOOLONG ? res : 0; |
478 | } | 478 | } |
479 | 479 | ||
480 | /* | 480 | /* |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index c68baeb0974a..d0ab78837057 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -2383,6 +2383,8 @@ xfs_bmap_btalloc( | |||
2383 | int tryagain; | 2383 | int tryagain; |
2384 | int error; | 2384 | int error; |
2385 | 2385 | ||
2386 | ASSERT(ap->length); | ||
2387 | |||
2386 | mp = ap->ip->i_mount; | 2388 | mp = ap->ip->i_mount; |
2387 | align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0; | 2389 | align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0; |
2388 | if (unlikely(align)) { | 2390 | if (unlikely(align)) { |
@@ -4629,6 +4631,8 @@ xfs_bmapi_allocate( | |||
4629 | int error; | 4631 | int error; |
4630 | int rt; | 4632 | int rt; |
4631 | 4633 | ||
4634 | ASSERT(bma->length > 0); | ||
4635 | |||
4632 | rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(bma->ip); | 4636 | rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(bma->ip); |
4633 | 4637 | ||
4634 | /* | 4638 | /* |
@@ -4849,6 +4853,7 @@ xfs_bmapi_write( | |||
4849 | ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); | 4853 | ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); |
4850 | ASSERT(!(flags & XFS_BMAPI_IGSTATE)); | 4854 | ASSERT(!(flags & XFS_BMAPI_IGSTATE)); |
4851 | ASSERT(tp != NULL); | 4855 | ASSERT(tp != NULL); |
4856 | ASSERT(len > 0); | ||
4852 | 4857 | ||
4853 | whichfork = (flags & XFS_BMAPI_ATTRFORK) ? | 4858 | whichfork = (flags & XFS_BMAPI_ATTRFORK) ? |
4854 | XFS_ATTR_FORK : XFS_DATA_FORK; | 4859 | XFS_ATTR_FORK : XFS_DATA_FORK; |
@@ -4918,9 +4923,22 @@ xfs_bmapi_write( | |||
4918 | bma.eof = eof; | 4923 | bma.eof = eof; |
4919 | bma.conv = !!(flags & XFS_BMAPI_CONVERT); | 4924 | bma.conv = !!(flags & XFS_BMAPI_CONVERT); |
4920 | bma.wasdel = wasdelay; | 4925 | bma.wasdel = wasdelay; |
4921 | bma.length = len; | ||
4922 | bma.offset = bno; | 4926 | bma.offset = bno; |
4923 | 4927 | ||
4928 | /* | ||
4929 | * There's a 32/64 bit type mismatch between the | ||
4930 | * allocation length request (which can be 64 bits in | ||
4931 | * length) and the bma length request, which is | ||
4932 | * xfs_extlen_t and therefore 32 bits. Hence we have to | ||
4933 | * check for 32-bit overflows and handle them here. | ||
4934 | */ | ||
4935 | if (len > (xfs_filblks_t)MAXEXTLEN) | ||
4936 | bma.length = MAXEXTLEN; | ||
4937 | else | ||
4938 | bma.length = len; | ||
4939 | |||
4940 | ASSERT(len > 0); | ||
4941 | ASSERT(bma.length > 0); | ||
4924 | error = xfs_bmapi_allocate(&bma, flags); | 4942 | error = xfs_bmapi_allocate(&bma, flags); |
4925 | if (error) | 4943 | if (error) |
4926 | goto error0; | 4944 | goto error0; |
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c index da108977b21f..558910f5e3c0 100644 --- a/fs/xfs/xfs_export.c +++ b/fs/xfs/xfs_export.c | |||
@@ -98,22 +98,22 @@ xfs_fs_encode_fh( | |||
98 | switch (fileid_type) { | 98 | switch (fileid_type) { |
99 | case FILEID_INO32_GEN_PARENT: | 99 | case FILEID_INO32_GEN_PARENT: |
100 | spin_lock(&dentry->d_lock); | 100 | spin_lock(&dentry->d_lock); |
101 | fid->i32.parent_ino = dentry->d_parent->d_inode->i_ino; | 101 | fid->i32.parent_ino = XFS_I(dentry->d_parent->d_inode)->i_ino; |
102 | fid->i32.parent_gen = dentry->d_parent->d_inode->i_generation; | 102 | fid->i32.parent_gen = dentry->d_parent->d_inode->i_generation; |
103 | spin_unlock(&dentry->d_lock); | 103 | spin_unlock(&dentry->d_lock); |
104 | /*FALLTHRU*/ | 104 | /*FALLTHRU*/ |
105 | case FILEID_INO32_GEN: | 105 | case FILEID_INO32_GEN: |
106 | fid->i32.ino = inode->i_ino; | 106 | fid->i32.ino = XFS_I(inode)->i_ino; |
107 | fid->i32.gen = inode->i_generation; | 107 | fid->i32.gen = inode->i_generation; |
108 | break; | 108 | break; |
109 | case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG: | 109 | case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG: |
110 | spin_lock(&dentry->d_lock); | 110 | spin_lock(&dentry->d_lock); |
111 | fid64->parent_ino = dentry->d_parent->d_inode->i_ino; | 111 | fid64->parent_ino = XFS_I(dentry->d_parent->d_inode)->i_ino; |
112 | fid64->parent_gen = dentry->d_parent->d_inode->i_generation; | 112 | fid64->parent_gen = dentry->d_parent->d_inode->i_generation; |
113 | spin_unlock(&dentry->d_lock); | 113 | spin_unlock(&dentry->d_lock); |
114 | /*FALLTHRU*/ | 114 | /*FALLTHRU*/ |
115 | case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG: | 115 | case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG: |
116 | fid64->ino = inode->i_ino; | 116 | fid64->ino = XFS_I(inode)->i_ino; |
117 | fid64->gen = inode->i_generation; | 117 | fid64->gen = inode->i_generation; |
118 | break; | 118 | break; |
119 | } | 119 | } |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index a14cd89fe465..34817adf4b9e 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -150,6 +150,117 @@ xlog_grant_add_space( | |||
150 | } while (head_val != old); | 150 | } while (head_val != old); |
151 | } | 151 | } |
152 | 152 | ||
153 | STATIC bool | ||
154 | xlog_reserveq_wake( | ||
155 | struct log *log, | ||
156 | int *free_bytes) | ||
157 | { | ||
158 | struct xlog_ticket *tic; | ||
159 | int need_bytes; | ||
160 | |||
161 | list_for_each_entry(tic, &log->l_reserveq, t_queue) { | ||
162 | if (tic->t_flags & XLOG_TIC_PERM_RESERV) | ||
163 | need_bytes = tic->t_unit_res * tic->t_cnt; | ||
164 | else | ||
165 | need_bytes = tic->t_unit_res; | ||
166 | |||
167 | if (*free_bytes < need_bytes) | ||
168 | return false; | ||
169 | *free_bytes -= need_bytes; | ||
170 | |||
171 | trace_xfs_log_grant_wake_up(log, tic); | ||
172 | wake_up(&tic->t_wait); | ||
173 | } | ||
174 | |||
175 | return true; | ||
176 | } | ||
177 | |||
178 | STATIC bool | ||
179 | xlog_writeq_wake( | ||
180 | struct log *log, | ||
181 | int *free_bytes) | ||
182 | { | ||
183 | struct xlog_ticket *tic; | ||
184 | int need_bytes; | ||
185 | |||
186 | list_for_each_entry(tic, &log->l_writeq, t_queue) { | ||
187 | ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV); | ||
188 | |||
189 | need_bytes = tic->t_unit_res; | ||
190 | |||
191 | if (*free_bytes < need_bytes) | ||
192 | return false; | ||
193 | *free_bytes -= need_bytes; | ||
194 | |||
195 | trace_xfs_log_regrant_write_wake_up(log, tic); | ||
196 | wake_up(&tic->t_wait); | ||
197 | } | ||
198 | |||
199 | return true; | ||
200 | } | ||
201 | |||
202 | STATIC int | ||
203 | xlog_reserveq_wait( | ||
204 | struct log *log, | ||
205 | struct xlog_ticket *tic, | ||
206 | int need_bytes) | ||
207 | { | ||
208 | list_add_tail(&tic->t_queue, &log->l_reserveq); | ||
209 | |||
210 | do { | ||
211 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
212 | goto shutdown; | ||
213 | xlog_grant_push_ail(log, need_bytes); | ||
214 | |||
215 | XFS_STATS_INC(xs_sleep_logspace); | ||
216 | trace_xfs_log_grant_sleep(log, tic); | ||
217 | |||
218 | xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock); | ||
219 | trace_xfs_log_grant_wake(log, tic); | ||
220 | |||
221 | spin_lock(&log->l_grant_reserve_lock); | ||
222 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
223 | goto shutdown; | ||
224 | } while (xlog_space_left(log, &log->l_grant_reserve_head) < need_bytes); | ||
225 | |||
226 | list_del_init(&tic->t_queue); | ||
227 | return 0; | ||
228 | shutdown: | ||
229 | list_del_init(&tic->t_queue); | ||
230 | return XFS_ERROR(EIO); | ||
231 | } | ||
232 | |||
233 | STATIC int | ||
234 | xlog_writeq_wait( | ||
235 | struct log *log, | ||
236 | struct xlog_ticket *tic, | ||
237 | int need_bytes) | ||
238 | { | ||
239 | list_add_tail(&tic->t_queue, &log->l_writeq); | ||
240 | |||
241 | do { | ||
242 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
243 | goto shutdown; | ||
244 | xlog_grant_push_ail(log, need_bytes); | ||
245 | |||
246 | XFS_STATS_INC(xs_sleep_logspace); | ||
247 | trace_xfs_log_regrant_write_sleep(log, tic); | ||
248 | |||
249 | xlog_wait(&tic->t_wait, &log->l_grant_write_lock); | ||
250 | trace_xfs_log_regrant_write_wake(log, tic); | ||
251 | |||
252 | spin_lock(&log->l_grant_write_lock); | ||
253 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
254 | goto shutdown; | ||
255 | } while (xlog_space_left(log, &log->l_grant_write_head) < need_bytes); | ||
256 | |||
257 | list_del_init(&tic->t_queue); | ||
258 | return 0; | ||
259 | shutdown: | ||
260 | list_del_init(&tic->t_queue); | ||
261 | return XFS_ERROR(EIO); | ||
262 | } | ||
263 | |||
153 | static void | 264 | static void |
154 | xlog_tic_reset_res(xlog_ticket_t *tic) | 265 | xlog_tic_reset_res(xlog_ticket_t *tic) |
155 | { | 266 | { |
@@ -350,8 +461,19 @@ xfs_log_reserve( | |||
350 | retval = xlog_grant_log_space(log, internal_ticket); | 461 | retval = xlog_grant_log_space(log, internal_ticket); |
351 | } | 462 | } |
352 | 463 | ||
464 | if (unlikely(retval)) { | ||
465 | /* | ||
466 | * If we are failing, make sure the ticket doesn't have any | ||
467 | * current reservations. We don't want to add this back | ||
468 | * when the ticket/ transaction gets cancelled. | ||
469 | */ | ||
470 | internal_ticket->t_curr_res = 0; | ||
471 | /* ungrant will give back unit_res * t_cnt. */ | ||
472 | internal_ticket->t_cnt = 0; | ||
473 | } | ||
474 | |||
353 | return retval; | 475 | return retval; |
354 | } /* xfs_log_reserve */ | 476 | } |
355 | 477 | ||
356 | 478 | ||
357 | /* | 479 | /* |
@@ -2481,8 +2603,8 @@ restart: | |||
2481 | /* | 2603 | /* |
2482 | * Atomically get the log space required for a log ticket. | 2604 | * Atomically get the log space required for a log ticket. |
2483 | * | 2605 | * |
2484 | * Once a ticket gets put onto the reserveq, it will only return after | 2606 | * Once a ticket gets put onto the reserveq, it will only return after the |
2485 | * the needed reservation is satisfied. | 2607 | * needed reservation is satisfied. |
2486 | * | 2608 | * |
2487 | * This function is structured so that it has a lock free fast path. This is | 2609 | * This function is structured so that it has a lock free fast path. This is |
2488 | * necessary because every new transaction reservation will come through this | 2610 | * necessary because every new transaction reservation will come through this |
@@ -2490,113 +2612,53 @@ restart: | |||
2490 | * every pass. | 2612 | * every pass. |
2491 | * | 2613 | * |
2492 | * As tickets are only ever moved on and off the reserveq under the | 2614 | * As tickets are only ever moved on and off the reserveq under the |
2493 | * l_grant_reserve_lock, we only need to take that lock if we are going | 2615 | * l_grant_reserve_lock, we only need to take that lock if we are going to add |
2494 | * to add the ticket to the queue and sleep. We can avoid taking the lock if the | 2616 | * the ticket to the queue and sleep. We can avoid taking the lock if the ticket |
2495 | * ticket was never added to the reserveq because the t_queue list head will be | 2617 | * was never added to the reserveq because the t_queue list head will be empty |
2496 | * empty and we hold the only reference to it so it can safely be checked | 2618 | * and we hold the only reference to it so it can safely be checked unlocked. |
2497 | * unlocked. | ||
2498 | */ | 2619 | */ |
2499 | STATIC int | 2620 | STATIC int |
2500 | xlog_grant_log_space(xlog_t *log, | 2621 | xlog_grant_log_space( |
2501 | xlog_ticket_t *tic) | 2622 | struct log *log, |
2623 | struct xlog_ticket *tic) | ||
2502 | { | 2624 | { |
2503 | int free_bytes; | 2625 | int free_bytes, need_bytes; |
2504 | int need_bytes; | 2626 | int error = 0; |
2505 | 2627 | ||
2506 | #ifdef DEBUG | 2628 | ASSERT(!(log->l_flags & XLOG_ACTIVE_RECOVERY)); |
2507 | if (log->l_flags & XLOG_ACTIVE_RECOVERY) | ||
2508 | panic("grant Recovery problem"); | ||
2509 | #endif | ||
2510 | 2629 | ||
2511 | trace_xfs_log_grant_enter(log, tic); | 2630 | trace_xfs_log_grant_enter(log, tic); |
2512 | 2631 | ||
2632 | /* | ||
2633 | * If there are other waiters on the queue then give them a chance at | ||
2634 | * logspace before us. Wake up the first waiters, if we do not wake | ||
2635 | * up all the waiters then go to sleep waiting for more free space, | ||
2636 | * otherwise try to get some space for this transaction. | ||
2637 | */ | ||
2513 | need_bytes = tic->t_unit_res; | 2638 | need_bytes = tic->t_unit_res; |
2514 | if (tic->t_flags & XFS_LOG_PERM_RESERV) | 2639 | if (tic->t_flags & XFS_LOG_PERM_RESERV) |
2515 | need_bytes *= tic->t_ocnt; | 2640 | need_bytes *= tic->t_ocnt; |
2516 | |||
2517 | /* something is already sleeping; insert new transaction at end */ | ||
2518 | if (!list_empty_careful(&log->l_reserveq)) { | ||
2519 | spin_lock(&log->l_grant_reserve_lock); | ||
2520 | /* recheck the queue now we are locked */ | ||
2521 | if (list_empty(&log->l_reserveq)) { | ||
2522 | spin_unlock(&log->l_grant_reserve_lock); | ||
2523 | goto redo; | ||
2524 | } | ||
2525 | list_add_tail(&tic->t_queue, &log->l_reserveq); | ||
2526 | |||
2527 | trace_xfs_log_grant_sleep1(log, tic); | ||
2528 | |||
2529 | /* | ||
2530 | * Gotta check this before going to sleep, while we're | ||
2531 | * holding the grant lock. | ||
2532 | */ | ||
2533 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
2534 | goto error_return; | ||
2535 | |||
2536 | XFS_STATS_INC(xs_sleep_logspace); | ||
2537 | xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock); | ||
2538 | |||
2539 | /* | ||
2540 | * If we got an error, and the filesystem is shutting down, | ||
2541 | * we'll catch it down below. So just continue... | ||
2542 | */ | ||
2543 | trace_xfs_log_grant_wake1(log, tic); | ||
2544 | } | ||
2545 | |||
2546 | redo: | ||
2547 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
2548 | goto error_return_unlocked; | ||
2549 | |||
2550 | free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); | 2641 | free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); |
2551 | if (free_bytes < need_bytes) { | 2642 | if (!list_empty_careful(&log->l_reserveq)) { |
2552 | spin_lock(&log->l_grant_reserve_lock); | 2643 | spin_lock(&log->l_grant_reserve_lock); |
2553 | if (list_empty(&tic->t_queue)) | 2644 | if (!xlog_reserveq_wake(log, &free_bytes) || |
2554 | list_add_tail(&tic->t_queue, &log->l_reserveq); | 2645 | free_bytes < need_bytes) |
2555 | 2646 | error = xlog_reserveq_wait(log, tic, need_bytes); | |
2556 | trace_xfs_log_grant_sleep2(log, tic); | 2647 | spin_unlock(&log->l_grant_reserve_lock); |
2557 | 2648 | } else if (free_bytes < need_bytes) { | |
2558 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
2559 | goto error_return; | ||
2560 | |||
2561 | xlog_grant_push_ail(log, need_bytes); | ||
2562 | |||
2563 | XFS_STATS_INC(xs_sleep_logspace); | ||
2564 | xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock); | ||
2565 | |||
2566 | trace_xfs_log_grant_wake2(log, tic); | ||
2567 | goto redo; | ||
2568 | } | ||
2569 | |||
2570 | if (!list_empty(&tic->t_queue)) { | ||
2571 | spin_lock(&log->l_grant_reserve_lock); | 2649 | spin_lock(&log->l_grant_reserve_lock); |
2572 | list_del_init(&tic->t_queue); | 2650 | error = xlog_reserveq_wait(log, tic, need_bytes); |
2573 | spin_unlock(&log->l_grant_reserve_lock); | 2651 | spin_unlock(&log->l_grant_reserve_lock); |
2574 | } | 2652 | } |
2653 | if (error) | ||
2654 | return error; | ||
2575 | 2655 | ||
2576 | /* we've got enough space */ | ||
2577 | xlog_grant_add_space(log, &log->l_grant_reserve_head, need_bytes); | 2656 | xlog_grant_add_space(log, &log->l_grant_reserve_head, need_bytes); |
2578 | xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); | 2657 | xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); |
2579 | trace_xfs_log_grant_exit(log, tic); | 2658 | trace_xfs_log_grant_exit(log, tic); |
2580 | xlog_verify_grant_tail(log); | 2659 | xlog_verify_grant_tail(log); |
2581 | return 0; | 2660 | return 0; |
2582 | 2661 | } | |
2583 | error_return_unlocked: | ||
2584 | spin_lock(&log->l_grant_reserve_lock); | ||
2585 | error_return: | ||
2586 | list_del_init(&tic->t_queue); | ||
2587 | spin_unlock(&log->l_grant_reserve_lock); | ||
2588 | trace_xfs_log_grant_error(log, tic); | ||
2589 | |||
2590 | /* | ||
2591 | * If we are failing, make sure the ticket doesn't have any | ||
2592 | * current reservations. We don't want to add this back when | ||
2593 | * the ticket/transaction gets cancelled. | ||
2594 | */ | ||
2595 | tic->t_curr_res = 0; | ||
2596 | tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */ | ||
2597 | return XFS_ERROR(EIO); | ||
2598 | } /* xlog_grant_log_space */ | ||
2599 | |||
2600 | 2662 | ||
2601 | /* | 2663 | /* |
2602 | * Replenish the byte reservation required by moving the grant write head. | 2664 | * Replenish the byte reservation required by moving the grant write head. |
@@ -2605,10 +2667,12 @@ error_return: | |||
2605 | * free fast path. | 2667 | * free fast path. |
2606 | */ | 2668 | */ |
2607 | STATIC int | 2669 | STATIC int |
2608 | xlog_regrant_write_log_space(xlog_t *log, | 2670 | xlog_regrant_write_log_space( |
2609 | xlog_ticket_t *tic) | 2671 | struct log *log, |
2672 | struct xlog_ticket *tic) | ||
2610 | { | 2673 | { |
2611 | int free_bytes, need_bytes; | 2674 | int free_bytes, need_bytes; |
2675 | int error = 0; | ||
2612 | 2676 | ||
2613 | tic->t_curr_res = tic->t_unit_res; | 2677 | tic->t_curr_res = tic->t_unit_res; |
2614 | xlog_tic_reset_res(tic); | 2678 | xlog_tic_reset_res(tic); |
@@ -2616,104 +2680,38 @@ xlog_regrant_write_log_space(xlog_t *log, | |||
2616 | if (tic->t_cnt > 0) | 2680 | if (tic->t_cnt > 0) |
2617 | return 0; | 2681 | return 0; |
2618 | 2682 | ||
2619 | #ifdef DEBUG | 2683 | ASSERT(!(log->l_flags & XLOG_ACTIVE_RECOVERY)); |
2620 | if (log->l_flags & XLOG_ACTIVE_RECOVERY) | ||
2621 | panic("regrant Recovery problem"); | ||
2622 | #endif | ||
2623 | 2684 | ||
2624 | trace_xfs_log_regrant_write_enter(log, tic); | 2685 | trace_xfs_log_regrant_write_enter(log, tic); |
2625 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
2626 | goto error_return_unlocked; | ||
2627 | 2686 | ||
2628 | /* If there are other waiters on the queue then give them a | 2687 | /* |
2629 | * chance at logspace before us. Wake up the first waiters, | 2688 | * If there are other waiters on the queue then give them a chance at |
2630 | * if we do not wake up all the waiters then go to sleep waiting | 2689 | * logspace before us. Wake up the first waiters, if we do not wake |
2631 | * for more free space, otherwise try to get some space for | 2690 | * up all the waiters then go to sleep waiting for more free space, |
2632 | * this transaction. | 2691 | * otherwise try to get some space for this transaction. |
2633 | */ | 2692 | */ |
2634 | need_bytes = tic->t_unit_res; | 2693 | need_bytes = tic->t_unit_res; |
2635 | if (!list_empty_careful(&log->l_writeq)) { | ||
2636 | struct xlog_ticket *ntic; | ||
2637 | |||
2638 | spin_lock(&log->l_grant_write_lock); | ||
2639 | free_bytes = xlog_space_left(log, &log->l_grant_write_head); | ||
2640 | list_for_each_entry(ntic, &log->l_writeq, t_queue) { | ||
2641 | ASSERT(ntic->t_flags & XLOG_TIC_PERM_RESERV); | ||
2642 | |||
2643 | if (free_bytes < ntic->t_unit_res) | ||
2644 | break; | ||
2645 | free_bytes -= ntic->t_unit_res; | ||
2646 | wake_up(&ntic->t_wait); | ||
2647 | } | ||
2648 | |||
2649 | if (ntic != list_first_entry(&log->l_writeq, | ||
2650 | struct xlog_ticket, t_queue)) { | ||
2651 | if (list_empty(&tic->t_queue)) | ||
2652 | list_add_tail(&tic->t_queue, &log->l_writeq); | ||
2653 | trace_xfs_log_regrant_write_sleep1(log, tic); | ||
2654 | |||
2655 | xlog_grant_push_ail(log, need_bytes); | ||
2656 | |||
2657 | XFS_STATS_INC(xs_sleep_logspace); | ||
2658 | xlog_wait(&tic->t_wait, &log->l_grant_write_lock); | ||
2659 | trace_xfs_log_regrant_write_wake1(log, tic); | ||
2660 | } else | ||
2661 | spin_unlock(&log->l_grant_write_lock); | ||
2662 | } | ||
2663 | |||
2664 | redo: | ||
2665 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
2666 | goto error_return_unlocked; | ||
2667 | |||
2668 | free_bytes = xlog_space_left(log, &log->l_grant_write_head); | 2694 | free_bytes = xlog_space_left(log, &log->l_grant_write_head); |
2669 | if (free_bytes < need_bytes) { | 2695 | if (!list_empty_careful(&log->l_writeq)) { |
2670 | spin_lock(&log->l_grant_write_lock); | 2696 | spin_lock(&log->l_grant_write_lock); |
2671 | if (list_empty(&tic->t_queue)) | 2697 | if (!xlog_writeq_wake(log, &free_bytes) || |
2672 | list_add_tail(&tic->t_queue, &log->l_writeq); | 2698 | free_bytes < need_bytes) |
2673 | 2699 | error = xlog_writeq_wait(log, tic, need_bytes); | |
2674 | if (XLOG_FORCED_SHUTDOWN(log)) | 2700 | spin_unlock(&log->l_grant_write_lock); |
2675 | goto error_return; | 2701 | } else if (free_bytes < need_bytes) { |
2676 | |||
2677 | xlog_grant_push_ail(log, need_bytes); | ||
2678 | |||
2679 | XFS_STATS_INC(xs_sleep_logspace); | ||
2680 | trace_xfs_log_regrant_write_sleep2(log, tic); | ||
2681 | xlog_wait(&tic->t_wait, &log->l_grant_write_lock); | ||
2682 | |||
2683 | trace_xfs_log_regrant_write_wake2(log, tic); | ||
2684 | goto redo; | ||
2685 | } | ||
2686 | |||
2687 | if (!list_empty(&tic->t_queue)) { | ||
2688 | spin_lock(&log->l_grant_write_lock); | 2702 | spin_lock(&log->l_grant_write_lock); |
2689 | list_del_init(&tic->t_queue); | 2703 | error = xlog_writeq_wait(log, tic, need_bytes); |
2690 | spin_unlock(&log->l_grant_write_lock); | 2704 | spin_unlock(&log->l_grant_write_lock); |
2691 | } | 2705 | } |
2692 | 2706 | ||
2693 | /* we've got enough space */ | 2707 | if (error) |
2708 | return error; | ||
2709 | |||
2694 | xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); | 2710 | xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); |
2695 | trace_xfs_log_regrant_write_exit(log, tic); | 2711 | trace_xfs_log_regrant_write_exit(log, tic); |
2696 | xlog_verify_grant_tail(log); | 2712 | xlog_verify_grant_tail(log); |
2697 | return 0; | 2713 | return 0; |
2698 | 2714 | } | |
2699 | |||
2700 | error_return_unlocked: | ||
2701 | spin_lock(&log->l_grant_write_lock); | ||
2702 | error_return: | ||
2703 | list_del_init(&tic->t_queue); | ||
2704 | spin_unlock(&log->l_grant_write_lock); | ||
2705 | trace_xfs_log_regrant_write_error(log, tic); | ||
2706 | |||
2707 | /* | ||
2708 | * If we are failing, make sure the ticket doesn't have any | ||
2709 | * current reservations. We don't want to add this back when | ||
2710 | * the ticket/transaction gets cancelled. | ||
2711 | */ | ||
2712 | tic->t_curr_res = 0; | ||
2713 | tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */ | ||
2714 | return XFS_ERROR(EIO); | ||
2715 | } /* xlog_regrant_write_log_space */ | ||
2716 | |||
2717 | 2715 | ||
2718 | /* The first cnt-1 times through here we don't need to | 2716 | /* The first cnt-1 times through here we don't need to |
2719 | * move the grant write head because the permanent | 2717 | * move the grant write head because the permanent |
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index f1d2802b2f07..494035798873 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h | |||
@@ -834,18 +834,14 @@ DEFINE_LOGGRANT_EVENT(xfs_log_umount_write); | |||
834 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_enter); | 834 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_enter); |
835 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_exit); | 835 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_exit); |
836 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_error); | 836 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_error); |
837 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep1); | 837 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep); |
838 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake1); | 838 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake); |
839 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep2); | ||
840 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake2); | ||
841 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake_up); | 839 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake_up); |
842 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_enter); | 840 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_enter); |
843 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_exit); | 841 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_exit); |
844 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_error); | 842 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_error); |
845 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep1); | 843 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep); |
846 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake1); | 844 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake); |
847 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep2); | ||
848 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake2); | ||
849 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake_up); | 845 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake_up); |
850 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_enter); | 846 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_enter); |
851 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_exit); | 847 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_exit); |
diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h index f4c38d8c6674..2292d1af9d70 100644 --- a/include/asm-generic/unistd.h +++ b/include/asm-generic/unistd.h | |||
@@ -685,9 +685,15 @@ __SYSCALL(__NR_syncfs, sys_syncfs) | |||
685 | __SYSCALL(__NR_setns, sys_setns) | 685 | __SYSCALL(__NR_setns, sys_setns) |
686 | #define __NR_sendmmsg 269 | 686 | #define __NR_sendmmsg 269 |
687 | __SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg) | 687 | __SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg) |
688 | #define __NR_process_vm_readv 270 | ||
689 | __SC_COMP(__NR_process_vm_readv, sys_process_vm_readv, \ | ||
690 | compat_sys_process_vm_readv) | ||
691 | #define __NR_process_vm_writev 271 | ||
692 | __SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \ | ||
693 | compat_sys_process_vm_writev) | ||
688 | 694 | ||
689 | #undef __NR_syscalls | 695 | #undef __NR_syscalls |
690 | #define __NR_syscalls 270 | 696 | #define __NR_syscalls 272 |
691 | 697 | ||
692 | /* | 698 | /* |
693 | * All syscalls below here should go away really, | 699 | * All syscalls below here should go away really, |
diff --git a/include/linux/amd-iommu.h b/include/linux/amd-iommu.h index a6863a2dec1f..06688c42167d 100644 --- a/include/linux/amd-iommu.h +++ b/include/linux/amd-iommu.h | |||
@@ -20,12 +20,105 @@ | |||
20 | #ifndef _ASM_X86_AMD_IOMMU_H | 20 | #ifndef _ASM_X86_AMD_IOMMU_H |
21 | #define _ASM_X86_AMD_IOMMU_H | 21 | #define _ASM_X86_AMD_IOMMU_H |
22 | 22 | ||
23 | #include <linux/irqreturn.h> | 23 | #include <linux/types.h> |
24 | 24 | ||
25 | #ifdef CONFIG_AMD_IOMMU | 25 | #ifdef CONFIG_AMD_IOMMU |
26 | 26 | ||
27 | struct task_struct; | ||
28 | struct pci_dev; | ||
29 | |||
27 | extern int amd_iommu_detect(void); | 30 | extern int amd_iommu_detect(void); |
28 | 31 | ||
32 | |||
33 | /** | ||
34 | * amd_iommu_enable_device_erratum() - Enable erratum workaround for device | ||
35 | * in the IOMMUv2 driver | ||
36 | * @pdev: The PCI device the workaround is necessary for | ||
37 | * @erratum: The erratum workaround to enable | ||
38 | * | ||
39 | * The function needs to be called before amd_iommu_init_device(). | ||
40 | * Possible values for the erratum number are for now: | ||
41 | * - AMD_PRI_DEV_ERRATUM_ENABLE_RESET - Reset PRI capability when PRI | ||
42 | * is enabled | ||
43 | * - AMD_PRI_DEV_ERRATUM_LIMIT_REQ_ONE - Limit number of outstanding PRI | ||
44 | * requests to one | ||
45 | */ | ||
46 | #define AMD_PRI_DEV_ERRATUM_ENABLE_RESET 0 | ||
47 | #define AMD_PRI_DEV_ERRATUM_LIMIT_REQ_ONE 1 | ||
48 | |||
49 | extern void amd_iommu_enable_device_erratum(struct pci_dev *pdev, u32 erratum); | ||
50 | |||
51 | /** | ||
52 | * amd_iommu_init_device() - Init device for use with IOMMUv2 driver | ||
53 | * @pdev: The PCI device to initialize | ||
54 | * @pasids: Number of PASIDs to support for this device | ||
55 | * | ||
56 | * This function does all setup for the device pdev so that it can be | ||
57 | * used with IOMMUv2. | ||
58 | * Returns 0 on success or negative value on error. | ||
59 | */ | ||
60 | extern int amd_iommu_init_device(struct pci_dev *pdev, int pasids); | ||
61 | |||
62 | /** | ||
63 | * amd_iommu_free_device() - Free all IOMMUv2 related device resources | ||
64 | * and disable IOMMUv2 usage for this device | ||
65 | * @pdev: The PCI device to disable IOMMUv2 usage for' | ||
66 | */ | ||
67 | extern void amd_iommu_free_device(struct pci_dev *pdev); | ||
68 | |||
69 | /** | ||
70 | * amd_iommu_bind_pasid() - Bind a given task to a PASID on a device | ||
71 | * @pdev: The PCI device to bind the task to | ||
72 | * @pasid: The PASID on the device the task should be bound to | ||
73 | * @task: the task to bind | ||
74 | * | ||
75 | * The function returns 0 on success or a negative value on error. | ||
76 | */ | ||
77 | extern int amd_iommu_bind_pasid(struct pci_dev *pdev, int pasid, | ||
78 | struct task_struct *task); | ||
79 | |||
80 | /** | ||
81 | * amd_iommu_unbind_pasid() - Unbind a PASID from its task on | ||
82 | * a device | ||
83 | * @pdev: The device of the PASID | ||
84 | * @pasid: The PASID to unbind | ||
85 | * | ||
86 | * When this function returns the device is no longer using the PASID | ||
87 | * and the PASID is no longer bound to its task. | ||
88 | */ | ||
89 | extern void amd_iommu_unbind_pasid(struct pci_dev *pdev, int pasid); | ||
90 | |||
91 | /** | ||
92 | * amd_iommu_set_invalid_ppr_cb() - Register a call-back for failed | ||
93 | * PRI requests | ||
94 | * @pdev: The PCI device the call-back should be registered for | ||
95 | * @cb: The call-back function | ||
96 | * | ||
97 | * The IOMMUv2 driver invokes this call-back when it is unable to | ||
98 | * successfully handle a PRI request. The device driver can then decide | ||
99 | * which PRI response the device should see. Possible return values for | ||
100 | * the call-back are: | ||
101 | * | ||
102 | * - AMD_IOMMU_INV_PRI_RSP_SUCCESS - Send SUCCESS back to the device | ||
103 | * - AMD_IOMMU_INV_PRI_RSP_INVALID - Send INVALID back to the device | ||
104 | * - AMD_IOMMU_INV_PRI_RSP_FAIL - Send Failure back to the device, | ||
105 | * the device is required to disable | ||
106 | * PRI when it receives this response | ||
107 | * | ||
108 | * The function returns 0 on success or negative value on error. | ||
109 | */ | ||
110 | #define AMD_IOMMU_INV_PRI_RSP_SUCCESS 0 | ||
111 | #define AMD_IOMMU_INV_PRI_RSP_INVALID 1 | ||
112 | #define AMD_IOMMU_INV_PRI_RSP_FAIL 2 | ||
113 | |||
114 | typedef int (*amd_iommu_invalid_ppr_cb)(struct pci_dev *pdev, | ||
115 | int pasid, | ||
116 | unsigned long address, | ||
117 | u16); | ||
118 | |||
119 | extern int amd_iommu_set_invalid_ppr_cb(struct pci_dev *pdev, | ||
120 | amd_iommu_invalid_ppr_cb cb); | ||
121 | |||
29 | #else | 122 | #else |
30 | 123 | ||
31 | static inline int amd_iommu_detect(void) { return -ENODEV; } | 124 | static inline int amd_iommu_detect(void) { return -ENODEV; } |
diff --git a/include/linux/compat.h b/include/linux/compat.h index 154bf5683015..66ed067fb729 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
@@ -552,5 +552,14 @@ extern ssize_t compat_rw_copy_check_uvector(int type, | |||
552 | 552 | ||
553 | extern void __user *compat_alloc_user_space(unsigned long len); | 553 | extern void __user *compat_alloc_user_space(unsigned long len); |
554 | 554 | ||
555 | asmlinkage ssize_t compat_sys_process_vm_readv(compat_pid_t pid, | ||
556 | const struct compat_iovec __user *lvec, | ||
557 | unsigned long liovcnt, const struct compat_iovec __user *rvec, | ||
558 | unsigned long riovcnt, unsigned long flags); | ||
559 | asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid, | ||
560 | const struct compat_iovec __user *lvec, | ||
561 | unsigned long liovcnt, const struct compat_iovec __user *rvec, | ||
562 | unsigned long riovcnt, unsigned long flags); | ||
563 | |||
555 | #endif /* CONFIG_COMPAT */ | 564 | #endif /* CONFIG_COMPAT */ |
556 | #endif /* _LINUX_COMPAT_H */ | 565 | #endif /* _LINUX_COMPAT_H */ |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 4df926199369..ed9f74f6c519 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -339,7 +339,8 @@ extern int d_validate(struct dentry *, struct dentry *); | |||
339 | */ | 339 | */ |
340 | extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); | 340 | extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); |
341 | 341 | ||
342 | extern char *__d_path(const struct path *path, struct path *root, char *, int); | 342 | extern char *__d_path(const struct path *, const struct path *, char *, int); |
343 | extern char *d_absolute_path(const struct path *, char *, int); | ||
343 | extern char *d_path(const struct path *, char *, int); | 344 | extern char *d_path(const struct path *, char *, int); |
344 | extern char *d_path_with_unreachable(const struct path *, char *, int); | 345 | extern char *d_path_with_unreachable(const struct path *, char *, int); |
345 | extern char *dentry_path_raw(struct dentry *, char *, int); | 346 | extern char *dentry_path_raw(struct dentry *, char *, int); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index e3130220ce3e..e0bc4ffb8e7f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -393,8 +393,8 @@ struct inodes_stat_t { | |||
393 | #include <linux/semaphore.h> | 393 | #include <linux/semaphore.h> |
394 | #include <linux/fiemap.h> | 394 | #include <linux/fiemap.h> |
395 | #include <linux/rculist_bl.h> | 395 | #include <linux/rculist_bl.h> |
396 | #include <linux/shrinker.h> | ||
397 | #include <linux/atomic.h> | 396 | #include <linux/atomic.h> |
397 | #include <linux/shrinker.h> | ||
398 | 398 | ||
399 | #include <asm/byteorder.h> | 399 | #include <asm/byteorder.h> |
400 | 400 | ||
@@ -1942,6 +1942,7 @@ extern int fd_statfs(int, struct kstatfs *); | |||
1942 | extern int statfs_by_dentry(struct dentry *, struct kstatfs *); | 1942 | extern int statfs_by_dentry(struct dentry *, struct kstatfs *); |
1943 | extern int freeze_super(struct super_block *super); | 1943 | extern int freeze_super(struct super_block *super); |
1944 | extern int thaw_super(struct super_block *super); | 1944 | extern int thaw_super(struct super_block *super); |
1945 | extern bool our_mnt(struct vfsmount *mnt); | ||
1945 | 1946 | ||
1946 | extern int current_umask(void); | 1947 | extern int current_umask(void); |
1947 | 1948 | ||
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 96efa6794ea5..c3da42dd22ba 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
@@ -172,6 +172,7 @@ enum { | |||
172 | TRACE_EVENT_FL_FILTERED_BIT, | 172 | TRACE_EVENT_FL_FILTERED_BIT, |
173 | TRACE_EVENT_FL_RECORDED_CMD_BIT, | 173 | TRACE_EVENT_FL_RECORDED_CMD_BIT, |
174 | TRACE_EVENT_FL_CAP_ANY_BIT, | 174 | TRACE_EVENT_FL_CAP_ANY_BIT, |
175 | TRACE_EVENT_FL_NO_SET_FILTER_BIT, | ||
175 | }; | 176 | }; |
176 | 177 | ||
177 | enum { | 178 | enum { |
@@ -179,6 +180,7 @@ enum { | |||
179 | TRACE_EVENT_FL_FILTERED = (1 << TRACE_EVENT_FL_FILTERED_BIT), | 180 | TRACE_EVENT_FL_FILTERED = (1 << TRACE_EVENT_FL_FILTERED_BIT), |
180 | TRACE_EVENT_FL_RECORDED_CMD = (1 << TRACE_EVENT_FL_RECORDED_CMD_BIT), | 181 | TRACE_EVENT_FL_RECORDED_CMD = (1 << TRACE_EVENT_FL_RECORDED_CMD_BIT), |
181 | TRACE_EVENT_FL_CAP_ANY = (1 << TRACE_EVENT_FL_CAP_ANY_BIT), | 182 | TRACE_EVENT_FL_CAP_ANY = (1 << TRACE_EVENT_FL_CAP_ANY_BIT), |
183 | TRACE_EVENT_FL_NO_SET_FILTER = (1 << TRACE_EVENT_FL_NO_SET_FILTER_BIT), | ||
182 | }; | 184 | }; |
183 | 185 | ||
184 | struct ftrace_event_call { | 186 | struct ftrace_event_call { |
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 94b1e356c02a..32574eef9394 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h | |||
@@ -126,6 +126,8 @@ extern struct cred init_cred; | |||
126 | # define INIT_PERF_EVENTS(tsk) | 126 | # define INIT_PERF_EVENTS(tsk) |
127 | #endif | 127 | #endif |
128 | 128 | ||
129 | #define INIT_TASK_COMM "swapper" | ||
130 | |||
129 | /* | 131 | /* |
130 | * INIT_TASK is used to set up the first task table, touch at | 132 | * INIT_TASK is used to set up the first task table, touch at |
131 | * your own risk!. Base=0, limit=0x1fffff (=2MB) | 133 | * your own risk!. Base=0, limit=0x1fffff (=2MB) |
@@ -162,7 +164,7 @@ extern struct cred init_cred; | |||
162 | .group_leader = &tsk, \ | 164 | .group_leader = &tsk, \ |
163 | RCU_INIT_POINTER(.real_cred, &init_cred), \ | 165 | RCU_INIT_POINTER(.real_cred, &init_cred), \ |
164 | RCU_INIT_POINTER(.cred, &init_cred), \ | 166 | RCU_INIT_POINTER(.cred, &init_cred), \ |
165 | .comm = "swapper", \ | 167 | .comm = INIT_TASK_COMM, \ |
166 | .thread = INIT_THREAD, \ | 168 | .thread = INIT_THREAD, \ |
167 | .fs = &init_fs, \ | 169 | .fs = &init_fs, \ |
168 | .files = &init_files, \ | 170 | .files = &init_files, \ |
diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 432acc4c054d..cc26f89c4ee6 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h | |||
@@ -48,19 +48,33 @@ struct iommu_domain { | |||
48 | 48 | ||
49 | #ifdef CONFIG_IOMMU_API | 49 | #ifdef CONFIG_IOMMU_API |
50 | 50 | ||
51 | /** | ||
52 | * struct iommu_ops - iommu ops and capabilities | ||
53 | * @domain_init: init iommu domain | ||
54 | * @domain_destroy: destroy iommu domain | ||
55 | * @attach_dev: attach device to an iommu domain | ||
56 | * @detach_dev: detach device from an iommu domain | ||
57 | * @map: map a physically contiguous memory region to an iommu domain | ||
58 | * @unmap: unmap a physically contiguous memory region from an iommu domain | ||
59 | * @iova_to_phys: translate iova to physical address | ||
60 | * @domain_has_cap: domain capabilities query | ||
61 | * @commit: commit iommu domain | ||
62 | * @pgsize_bitmap: bitmap of supported page sizes | ||
63 | */ | ||
51 | struct iommu_ops { | 64 | struct iommu_ops { |
52 | int (*domain_init)(struct iommu_domain *domain); | 65 | int (*domain_init)(struct iommu_domain *domain); |
53 | void (*domain_destroy)(struct iommu_domain *domain); | 66 | void (*domain_destroy)(struct iommu_domain *domain); |
54 | int (*attach_dev)(struct iommu_domain *domain, struct device *dev); | 67 | int (*attach_dev)(struct iommu_domain *domain, struct device *dev); |
55 | void (*detach_dev)(struct iommu_domain *domain, struct device *dev); | 68 | void (*detach_dev)(struct iommu_domain *domain, struct device *dev); |
56 | int (*map)(struct iommu_domain *domain, unsigned long iova, | 69 | int (*map)(struct iommu_domain *domain, unsigned long iova, |
57 | phys_addr_t paddr, int gfp_order, int prot); | 70 | phys_addr_t paddr, size_t size, int prot); |
58 | int (*unmap)(struct iommu_domain *domain, unsigned long iova, | 71 | size_t (*unmap)(struct iommu_domain *domain, unsigned long iova, |
59 | int gfp_order); | 72 | size_t size); |
60 | phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, | 73 | phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, |
61 | unsigned long iova); | 74 | unsigned long iova); |
62 | int (*domain_has_cap)(struct iommu_domain *domain, | 75 | int (*domain_has_cap)(struct iommu_domain *domain, |
63 | unsigned long cap); | 76 | unsigned long cap); |
77 | unsigned long pgsize_bitmap; | ||
64 | }; | 78 | }; |
65 | 79 | ||
66 | extern int bus_set_iommu(struct bus_type *bus, struct iommu_ops *ops); | 80 | extern int bus_set_iommu(struct bus_type *bus, struct iommu_ops *ops); |
@@ -72,9 +86,9 @@ extern int iommu_attach_device(struct iommu_domain *domain, | |||
72 | extern void iommu_detach_device(struct iommu_domain *domain, | 86 | extern void iommu_detach_device(struct iommu_domain *domain, |
73 | struct device *dev); | 87 | struct device *dev); |
74 | extern int iommu_map(struct iommu_domain *domain, unsigned long iova, | 88 | extern int iommu_map(struct iommu_domain *domain, unsigned long iova, |
75 | phys_addr_t paddr, int gfp_order, int prot); | 89 | phys_addr_t paddr, size_t size, int prot); |
76 | extern int iommu_unmap(struct iommu_domain *domain, unsigned long iova, | 90 | extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, |
77 | int gfp_order); | 91 | size_t size); |
78 | extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, | 92 | extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, |
79 | unsigned long iova); | 93 | unsigned long iova); |
80 | extern int iommu_domain_has_cap(struct iommu_domain *domain, | 94 | extern int iommu_domain_has_cap(struct iommu_domain *domain, |
diff --git a/include/linux/mm.h b/include/linux/mm.h index 3dc3a8c2c485..4baadd18f4ad 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/mmzone.h> | 10 | #include <linux/mmzone.h> |
11 | #include <linux/rbtree.h> | 11 | #include <linux/rbtree.h> |
12 | #include <linux/prio_tree.h> | 12 | #include <linux/prio_tree.h> |
13 | #include <linux/atomic.h> | ||
13 | #include <linux/debug_locks.h> | 14 | #include <linux/debug_locks.h> |
14 | #include <linux/mm_types.h> | 15 | #include <linux/mm_types.h> |
15 | #include <linux/range.h> | 16 | #include <linux/range.h> |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 172ba70306d1..2aaee0ca9da8 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -517,8 +517,12 @@ | |||
517 | #define PCI_DEVICE_ID_AMD_11H_NB_DRAM 0x1302 | 517 | #define PCI_DEVICE_ID_AMD_11H_NB_DRAM 0x1302 |
518 | #define PCI_DEVICE_ID_AMD_11H_NB_MISC 0x1303 | 518 | #define PCI_DEVICE_ID_AMD_11H_NB_MISC 0x1303 |
519 | #define PCI_DEVICE_ID_AMD_11H_NB_LINK 0x1304 | 519 | #define PCI_DEVICE_ID_AMD_11H_NB_LINK 0x1304 |
520 | #define PCI_DEVICE_ID_AMD_15H_NB_F0 0x1600 | ||
521 | #define PCI_DEVICE_ID_AMD_15H_NB_F1 0x1601 | ||
522 | #define PCI_DEVICE_ID_AMD_15H_NB_F2 0x1602 | ||
520 | #define PCI_DEVICE_ID_AMD_15H_NB_F3 0x1603 | 523 | #define PCI_DEVICE_ID_AMD_15H_NB_F3 0x1603 |
521 | #define PCI_DEVICE_ID_AMD_15H_NB_F4 0x1604 | 524 | #define PCI_DEVICE_ID_AMD_15H_NB_F4 0x1604 |
525 | #define PCI_DEVICE_ID_AMD_15H_NB_F5 0x1605 | ||
522 | #define PCI_DEVICE_ID_AMD_CNB17H_F3 0x1703 | 526 | #define PCI_DEVICE_ID_AMD_CNB17H_F3 0x1703 |
523 | #define PCI_DEVICE_ID_AMD_LANCE 0x2000 | 527 | #define PCI_DEVICE_ID_AMD_LANCE 0x2000 |
524 | #define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001 | 528 | #define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001 |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 1e9ebe5e0091..b1f89122bf6a 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
@@ -822,6 +822,7 @@ struct perf_event { | |||
822 | int mmap_locked; | 822 | int mmap_locked; |
823 | struct user_struct *mmap_user; | 823 | struct user_struct *mmap_user; |
824 | struct ring_buffer *rb; | 824 | struct ring_buffer *rb; |
825 | struct list_head rb_entry; | ||
825 | 826 | ||
826 | /* poll related */ | 827 | /* poll related */ |
827 | wait_queue_head_t waitq; | 828 | wait_queue_head_t waitq; |
diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h index a83833a1f7a2..07ceb97d53fa 100644 --- a/include/linux/shrinker.h +++ b/include/linux/shrinker.h | |||
@@ -35,7 +35,7 @@ struct shrinker { | |||
35 | 35 | ||
36 | /* These are for internal use */ | 36 | /* These are for internal use */ |
37 | struct list_head list; | 37 | struct list_head list; |
38 | long nr; /* objs pending delete */ | 38 | atomic_long_t nr_in_batch; /* objs pending delete */ |
39 | }; | 39 | }; |
40 | #define DEFAULT_SEEKS 2 /* A good number if you don't know better. */ | 40 | #define DEFAULT_SEEKS 2 /* A good number if you don't know better. */ |
41 | extern void register_shrinker(struct shrinker *); | 41 | extern void register_shrinker(struct shrinker *); |
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 7f5fed3c89e1..6873c7dd9145 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
@@ -103,9 +103,10 @@ enum se_cmd_flags_table { | |||
103 | SCF_SCSI_NON_DATA_CDB = 0x00000040, | 103 | SCF_SCSI_NON_DATA_CDB = 0x00000040, |
104 | SCF_SCSI_CDB_EXCEPTION = 0x00000080, | 104 | SCF_SCSI_CDB_EXCEPTION = 0x00000080, |
105 | SCF_SCSI_RESERVATION_CONFLICT = 0x00000100, | 105 | SCF_SCSI_RESERVATION_CONFLICT = 0x00000100, |
106 | SCF_SE_CMD_FAILED = 0x00000400, | 106 | SCF_FUA = 0x00000200, |
107 | SCF_SE_LUN_CMD = 0x00000800, | 107 | SCF_SE_LUN_CMD = 0x00000800, |
108 | SCF_SE_ALLOW_EOO = 0x00001000, | 108 | SCF_SE_ALLOW_EOO = 0x00001000, |
109 | SCF_BIDI = 0x00002000, | ||
109 | SCF_SENT_CHECK_CONDITION = 0x00004000, | 110 | SCF_SENT_CHECK_CONDITION = 0x00004000, |
110 | SCF_OVERFLOW_BIT = 0x00008000, | 111 | SCF_OVERFLOW_BIT = 0x00008000, |
111 | SCF_UNDERFLOW_BIT = 0x00010000, | 112 | SCF_UNDERFLOW_BIT = 0x00010000, |
@@ -154,6 +155,7 @@ enum tcm_sense_reason_table { | |||
154 | TCM_CHECK_CONDITION_ABORT_CMD = 0x0d, | 155 | TCM_CHECK_CONDITION_ABORT_CMD = 0x0d, |
155 | TCM_CHECK_CONDITION_UNIT_ATTENTION = 0x0e, | 156 | TCM_CHECK_CONDITION_UNIT_ATTENTION = 0x0e, |
156 | TCM_CHECK_CONDITION_NOT_READY = 0x0f, | 157 | TCM_CHECK_CONDITION_NOT_READY = 0x0f, |
158 | TCM_RESERVATION_CONFLICT = 0x10, | ||
157 | }; | 159 | }; |
158 | 160 | ||
159 | struct se_obj { | 161 | struct se_obj { |
@@ -211,7 +213,6 @@ struct t10_alua_lu_gp { | |||
211 | u16 lu_gp_id; | 213 | u16 lu_gp_id; |
212 | int lu_gp_valid_id; | 214 | int lu_gp_valid_id; |
213 | u32 lu_gp_members; | 215 | u32 lu_gp_members; |
214 | atomic_t lu_gp_shutdown; | ||
215 | atomic_t lu_gp_ref_cnt; | 216 | atomic_t lu_gp_ref_cnt; |
216 | spinlock_t lu_gp_lock; | 217 | spinlock_t lu_gp_lock; |
217 | struct config_group lu_gp_group; | 218 | struct config_group lu_gp_group; |
@@ -422,11 +423,9 @@ struct se_cmd { | |||
422 | int sam_task_attr; | 423 | int sam_task_attr; |
423 | /* Transport protocol dependent state, see transport_state_table */ | 424 | /* Transport protocol dependent state, see transport_state_table */ |
424 | enum transport_state_table t_state; | 425 | enum transport_state_table t_state; |
425 | /* Transport specific error status */ | ||
426 | int transport_error_status; | ||
427 | /* Used to signal cmd->se_tfo->check_release_cmd() usage per cmd */ | 426 | /* Used to signal cmd->se_tfo->check_release_cmd() usage per cmd */ |
428 | int check_release:1; | 427 | unsigned check_release:1; |
429 | int cmd_wait_set:1; | 428 | unsigned cmd_wait_set:1; |
430 | /* See se_cmd_flags_table */ | 429 | /* See se_cmd_flags_table */ |
431 | u32 se_cmd_flags; | 430 | u32 se_cmd_flags; |
432 | u32 se_ordered_id; | 431 | u32 se_ordered_id; |
@@ -441,13 +440,10 @@ struct se_cmd { | |||
441 | /* Used for sense data */ | 440 | /* Used for sense data */ |
442 | void *sense_buffer; | 441 | void *sense_buffer; |
443 | struct list_head se_delayed_node; | 442 | struct list_head se_delayed_node; |
444 | struct list_head se_ordered_node; | ||
445 | struct list_head se_lun_node; | 443 | struct list_head se_lun_node; |
446 | struct list_head se_qf_node; | 444 | struct list_head se_qf_node; |
447 | struct se_device *se_dev; | 445 | struct se_device *se_dev; |
448 | struct se_dev_entry *se_deve; | 446 | struct se_dev_entry *se_deve; |
449 | struct se_device *se_obj_ptr; | ||
450 | struct se_device *se_orig_obj_ptr; | ||
451 | struct se_lun *se_lun; | 447 | struct se_lun *se_lun; |
452 | /* Only used for internal passthrough and legacy TCM fabric modules */ | 448 | /* Only used for internal passthrough and legacy TCM fabric modules */ |
453 | struct se_session *se_sess; | 449 | struct se_session *se_sess; |
@@ -463,8 +459,6 @@ struct se_cmd { | |||
463 | unsigned char __t_task_cdb[TCM_MAX_COMMAND_SIZE]; | 459 | unsigned char __t_task_cdb[TCM_MAX_COMMAND_SIZE]; |
464 | unsigned long long t_task_lba; | 460 | unsigned long long t_task_lba; |
465 | int t_tasks_failed; | 461 | int t_tasks_failed; |
466 | int t_tasks_fua; | ||
467 | bool t_tasks_bidi; | ||
468 | u32 t_tasks_sg_chained_no; | 462 | u32 t_tasks_sg_chained_no; |
469 | atomic_t t_fe_count; | 463 | atomic_t t_fe_count; |
470 | atomic_t t_se_count; | 464 | atomic_t t_se_count; |
@@ -489,14 +483,6 @@ struct se_cmd { | |||
489 | 483 | ||
490 | struct work_struct work; | 484 | struct work_struct work; |
491 | 485 | ||
492 | /* | ||
493 | * Used for pre-registered fabric SGL passthrough WRITE and READ | ||
494 | * with the special SCF_PASSTHROUGH_CONTIG_TO_SG case for TCM_Loop | ||
495 | * and other HW target mode fabric modules. | ||
496 | */ | ||
497 | struct scatterlist *t_task_pt_sgl; | ||
498 | u32 t_task_pt_sgl_num; | ||
499 | |||
500 | struct scatterlist *t_data_sg; | 486 | struct scatterlist *t_data_sg; |
501 | unsigned int t_data_nents; | 487 | unsigned int t_data_nents; |
502 | struct scatterlist *t_bidi_data_sg; | 488 | struct scatterlist *t_bidi_data_sg; |
@@ -562,7 +548,7 @@ struct se_node_acl { | |||
562 | } ____cacheline_aligned; | 548 | } ____cacheline_aligned; |
563 | 549 | ||
564 | struct se_session { | 550 | struct se_session { |
565 | int sess_tearing_down:1; | 551 | unsigned sess_tearing_down:1; |
566 | u64 sess_bin_isid; | 552 | u64 sess_bin_isid; |
567 | struct se_node_acl *se_node_acl; | 553 | struct se_node_acl *se_node_acl; |
568 | struct se_portal_group *se_tpg; | 554 | struct se_portal_group *se_tpg; |
@@ -683,7 +669,6 @@ struct se_subsystem_dev { | |||
683 | struct t10_reservation t10_pr; | 669 | struct t10_reservation t10_pr; |
684 | spinlock_t se_dev_lock; | 670 | spinlock_t se_dev_lock; |
685 | void *se_dev_su_ptr; | 671 | void *se_dev_su_ptr; |
686 | struct list_head se_dev_node; | ||
687 | struct config_group se_dev_group; | 672 | struct config_group se_dev_group; |
688 | /* For T10 Reservations */ | 673 | /* For T10 Reservations */ |
689 | struct config_group se_dev_pr_group; | 674 | struct config_group se_dev_pr_group; |
@@ -692,9 +677,6 @@ struct se_subsystem_dev { | |||
692 | } ____cacheline_aligned; | 677 | } ____cacheline_aligned; |
693 | 678 | ||
694 | struct se_device { | 679 | struct se_device { |
695 | /* Set to 1 if thread is NOT sleeping on thread_sem */ | ||
696 | u8 thread_active; | ||
697 | u8 dev_status_timer_flags; | ||
698 | /* RELATIVE TARGET PORT IDENTIFER Counter */ | 680 | /* RELATIVE TARGET PORT IDENTIFER Counter */ |
699 | u16 dev_rpti_counter; | 681 | u16 dev_rpti_counter; |
700 | /* Used for SAM Task Attribute ordering */ | 682 | /* Used for SAM Task Attribute ordering */ |
@@ -719,14 +701,10 @@ struct se_device { | |||
719 | u64 write_bytes; | 701 | u64 write_bytes; |
720 | spinlock_t stats_lock; | 702 | spinlock_t stats_lock; |
721 | /* Active commands on this virtual SE device */ | 703 | /* Active commands on this virtual SE device */ |
722 | atomic_t active_cmds; | ||
723 | atomic_t simple_cmds; | 704 | atomic_t simple_cmds; |
724 | atomic_t depth_left; | 705 | atomic_t depth_left; |
725 | atomic_t dev_ordered_id; | 706 | atomic_t dev_ordered_id; |
726 | atomic_t dev_tur_active; | ||
727 | atomic_t execute_tasks; | 707 | atomic_t execute_tasks; |
728 | atomic_t dev_status_thr_count; | ||
729 | atomic_t dev_hoq_count; | ||
730 | atomic_t dev_ordered_sync; | 708 | atomic_t dev_ordered_sync; |
731 | atomic_t dev_qf_count; | 709 | atomic_t dev_qf_count; |
732 | struct se_obj dev_obj; | 710 | struct se_obj dev_obj; |
@@ -734,14 +712,9 @@ struct se_device { | |||
734 | struct se_obj dev_export_obj; | 712 | struct se_obj dev_export_obj; |
735 | struct se_queue_obj dev_queue_obj; | 713 | struct se_queue_obj dev_queue_obj; |
736 | spinlock_t delayed_cmd_lock; | 714 | spinlock_t delayed_cmd_lock; |
737 | spinlock_t ordered_cmd_lock; | ||
738 | spinlock_t execute_task_lock; | 715 | spinlock_t execute_task_lock; |
739 | spinlock_t state_task_lock; | ||
740 | spinlock_t dev_alua_lock; | ||
741 | spinlock_t dev_reservation_lock; | 716 | spinlock_t dev_reservation_lock; |
742 | spinlock_t dev_state_lock; | ||
743 | spinlock_t dev_status_lock; | 717 | spinlock_t dev_status_lock; |
744 | spinlock_t dev_status_thr_lock; | ||
745 | spinlock_t se_port_lock; | 718 | spinlock_t se_port_lock; |
746 | spinlock_t se_tmr_lock; | 719 | spinlock_t se_tmr_lock; |
747 | spinlock_t qf_cmd_lock; | 720 | spinlock_t qf_cmd_lock; |
@@ -753,14 +726,10 @@ struct se_device { | |||
753 | struct t10_pr_registration *dev_pr_res_holder; | 726 | struct t10_pr_registration *dev_pr_res_holder; |
754 | struct list_head dev_sep_list; | 727 | struct list_head dev_sep_list; |
755 | struct list_head dev_tmr_list; | 728 | struct list_head dev_tmr_list; |
756 | struct timer_list dev_status_timer; | ||
757 | /* Pointer to descriptor for processing thread */ | 729 | /* Pointer to descriptor for processing thread */ |
758 | struct task_struct *process_thread; | 730 | struct task_struct *process_thread; |
759 | pid_t process_thread_pid; | ||
760 | struct task_struct *dev_mgmt_thread; | ||
761 | struct work_struct qf_work_queue; | 731 | struct work_struct qf_work_queue; |
762 | struct list_head delayed_cmd_list; | 732 | struct list_head delayed_cmd_list; |
763 | struct list_head ordered_cmd_list; | ||
764 | struct list_head execute_task_list; | 733 | struct list_head execute_task_list; |
765 | struct list_head state_task_list; | 734 | struct list_head state_task_list; |
766 | struct list_head qf_cmd_list; | 735 | struct list_head qf_cmd_list; |
@@ -771,8 +740,6 @@ struct se_device { | |||
771 | struct se_subsystem_api *transport; | 740 | struct se_subsystem_api *transport; |
772 | /* Linked list for struct se_hba struct se_device list */ | 741 | /* Linked list for struct se_hba struct se_device list */ |
773 | struct list_head dev_list; | 742 | struct list_head dev_list; |
774 | /* Linked list for struct se_global->g_se_dev_list */ | ||
775 | struct list_head g_se_dev_list; | ||
776 | } ____cacheline_aligned; | 743 | } ____cacheline_aligned; |
777 | 744 | ||
778 | struct se_hba { | 745 | struct se_hba { |
@@ -834,7 +801,6 @@ struct se_port { | |||
834 | u32 sep_index; | 801 | u32 sep_index; |
835 | struct scsi_port_stats sep_stats; | 802 | struct scsi_port_stats sep_stats; |
836 | /* Used for ALUA Target Port Groups membership */ | 803 | /* Used for ALUA Target Port Groups membership */ |
837 | atomic_t sep_tg_pt_gp_active; | ||
838 | atomic_t sep_tg_pt_secondary_offline; | 804 | atomic_t sep_tg_pt_secondary_offline; |
839 | /* Used for PR ALL_TG_PT=1 */ | 805 | /* Used for PR ALL_TG_PT=1 */ |
840 | atomic_t sep_tg_pt_ref_cnt; | 806 | atomic_t sep_tg_pt_ref_cnt; |
diff --git a/include/target/target_core_transport.h b/include/target/target_core_transport.h index c16e9431dd01..dac4f2d859fd 100644 --- a/include/target/target_core_transport.h +++ b/include/target/target_core_transport.h | |||
@@ -10,29 +10,6 @@ | |||
10 | 10 | ||
11 | #define PYX_TRANSPORT_STATUS_INTERVAL 5 /* In seconds */ | 11 | #define PYX_TRANSPORT_STATUS_INTERVAL 5 /* In seconds */ |
12 | 12 | ||
13 | #define PYX_TRANSPORT_SENT_TO_TRANSPORT 0 | ||
14 | #define PYX_TRANSPORT_WRITE_PENDING 1 | ||
15 | |||
16 | #define PYX_TRANSPORT_UNKNOWN_SAM_OPCODE -1 | ||
17 | #define PYX_TRANSPORT_HBA_QUEUE_FULL -2 | ||
18 | #define PYX_TRANSPORT_REQ_TOO_MANY_SECTORS -3 | ||
19 | #define PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES -4 | ||
20 | #define PYX_TRANSPORT_INVALID_CDB_FIELD -5 | ||
21 | #define PYX_TRANSPORT_INVALID_PARAMETER_LIST -6 | ||
22 | #define PYX_TRANSPORT_LU_COMM_FAILURE -7 | ||
23 | #define PYX_TRANSPORT_UNKNOWN_MODE_PAGE -8 | ||
24 | #define PYX_TRANSPORT_WRITE_PROTECTED -9 | ||
25 | #define PYX_TRANSPORT_RESERVATION_CONFLICT -10 | ||
26 | #define PYX_TRANSPORT_ILLEGAL_REQUEST -11 | ||
27 | #define PYX_TRANSPORT_USE_SENSE_REASON -12 | ||
28 | |||
29 | #ifndef SAM_STAT_RESERVATION_CONFLICT | ||
30 | #define SAM_STAT_RESERVATION_CONFLICT 0x18 | ||
31 | #endif | ||
32 | |||
33 | #define TRANSPORT_PLUGIN_FREE 0 | ||
34 | #define TRANSPORT_PLUGIN_REGISTERED 1 | ||
35 | |||
36 | #define TRANSPORT_PLUGIN_PHBA_PDEV 1 | 13 | #define TRANSPORT_PLUGIN_PHBA_PDEV 1 |
37 | #define TRANSPORT_PLUGIN_VHBA_PDEV 2 | 14 | #define TRANSPORT_PLUGIN_VHBA_PDEV 2 |
38 | #define TRANSPORT_PLUGIN_VHBA_VDEV 3 | 15 | #define TRANSPORT_PLUGIN_VHBA_VDEV 3 |
@@ -158,7 +135,6 @@ extern int transport_generic_allocate_tasks(struct se_cmd *, unsigned char *); | |||
158 | extern int transport_handle_cdb_direct(struct se_cmd *); | 135 | extern int transport_handle_cdb_direct(struct se_cmd *); |
159 | extern int transport_generic_handle_cdb_map(struct se_cmd *); | 136 | extern int transport_generic_handle_cdb_map(struct se_cmd *); |
160 | extern int transport_generic_handle_data(struct se_cmd *); | 137 | extern int transport_generic_handle_data(struct se_cmd *); |
161 | extern void transport_new_cmd_failure(struct se_cmd *); | ||
162 | extern int transport_generic_handle_tmr(struct se_cmd *); | 138 | extern int transport_generic_handle_tmr(struct se_cmd *); |
163 | extern bool target_stop_task(struct se_task *task, unsigned long *flags); | 139 | extern bool target_stop_task(struct se_task *task, unsigned long *flags); |
164 | extern int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32, | 140 | extern int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32, |
diff --git a/kernel/events/core.c b/kernel/events/core.c index 0e8457da6f95..d3b9df5962c2 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -185,6 +185,9 @@ static void cpu_ctx_sched_in(struct perf_cpu_context *cpuctx, | |||
185 | static void update_context_time(struct perf_event_context *ctx); | 185 | static void update_context_time(struct perf_event_context *ctx); |
186 | static u64 perf_event_time(struct perf_event *event); | 186 | static u64 perf_event_time(struct perf_event *event); |
187 | 187 | ||
188 | static void ring_buffer_attach(struct perf_event *event, | ||
189 | struct ring_buffer *rb); | ||
190 | |||
188 | void __weak perf_event_print_debug(void) { } | 191 | void __weak perf_event_print_debug(void) { } |
189 | 192 | ||
190 | extern __weak const char *perf_pmu_name(void) | 193 | extern __weak const char *perf_pmu_name(void) |
@@ -2171,9 +2174,10 @@ static void perf_event_context_sched_in(struct perf_event_context *ctx, | |||
2171 | */ | 2174 | */ |
2172 | cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE); | 2175 | cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE); |
2173 | 2176 | ||
2174 | perf_event_sched_in(cpuctx, ctx, task); | 2177 | if (ctx->nr_events) |
2178 | cpuctx->task_ctx = ctx; | ||
2175 | 2179 | ||
2176 | cpuctx->task_ctx = ctx; | 2180 | perf_event_sched_in(cpuctx, cpuctx->task_ctx, task); |
2177 | 2181 | ||
2178 | perf_pmu_enable(ctx->pmu); | 2182 | perf_pmu_enable(ctx->pmu); |
2179 | perf_ctx_unlock(cpuctx, ctx); | 2183 | perf_ctx_unlock(cpuctx, ctx); |
@@ -3190,12 +3194,33 @@ static unsigned int perf_poll(struct file *file, poll_table *wait) | |||
3190 | struct ring_buffer *rb; | 3194 | struct ring_buffer *rb; |
3191 | unsigned int events = POLL_HUP; | 3195 | unsigned int events = POLL_HUP; |
3192 | 3196 | ||
3197 | /* | ||
3198 | * Race between perf_event_set_output() and perf_poll(): perf_poll() | ||
3199 | * grabs the rb reference but perf_event_set_output() overrides it. | ||
3200 | * Here is the timeline for two threads T1, T2: | ||
3201 | * t0: T1, rb = rcu_dereference(event->rb) | ||
3202 | * t1: T2, old_rb = event->rb | ||
3203 | * t2: T2, event->rb = new rb | ||
3204 | * t3: T2, ring_buffer_detach(old_rb) | ||
3205 | * t4: T1, ring_buffer_attach(rb1) | ||
3206 | * t5: T1, poll_wait(event->waitq) | ||
3207 | * | ||
3208 | * To avoid this problem, we grab mmap_mutex in perf_poll() | ||
3209 | * thereby ensuring that the assignment of the new ring buffer | ||
3210 | * and the detachment of the old buffer appear atomic to perf_poll() | ||
3211 | */ | ||
3212 | mutex_lock(&event->mmap_mutex); | ||
3213 | |||
3193 | rcu_read_lock(); | 3214 | rcu_read_lock(); |
3194 | rb = rcu_dereference(event->rb); | 3215 | rb = rcu_dereference(event->rb); |
3195 | if (rb) | 3216 | if (rb) { |
3217 | ring_buffer_attach(event, rb); | ||
3196 | events = atomic_xchg(&rb->poll, 0); | 3218 | events = atomic_xchg(&rb->poll, 0); |
3219 | } | ||
3197 | rcu_read_unlock(); | 3220 | rcu_read_unlock(); |
3198 | 3221 | ||
3222 | mutex_unlock(&event->mmap_mutex); | ||
3223 | |||
3199 | poll_wait(file, &event->waitq, wait); | 3224 | poll_wait(file, &event->waitq, wait); |
3200 | 3225 | ||
3201 | return events; | 3226 | return events; |
@@ -3496,6 +3521,49 @@ unlock: | |||
3496 | return ret; | 3521 | return ret; |
3497 | } | 3522 | } |
3498 | 3523 | ||
3524 | static void ring_buffer_attach(struct perf_event *event, | ||
3525 | struct ring_buffer *rb) | ||
3526 | { | ||
3527 | unsigned long flags; | ||
3528 | |||
3529 | if (!list_empty(&event->rb_entry)) | ||
3530 | return; | ||
3531 | |||
3532 | spin_lock_irqsave(&rb->event_lock, flags); | ||
3533 | if (!list_empty(&event->rb_entry)) | ||
3534 | goto unlock; | ||
3535 | |||
3536 | list_add(&event->rb_entry, &rb->event_list); | ||
3537 | unlock: | ||
3538 | spin_unlock_irqrestore(&rb->event_lock, flags); | ||
3539 | } | ||
3540 | |||
3541 | static void ring_buffer_detach(struct perf_event *event, | ||
3542 | struct ring_buffer *rb) | ||
3543 | { | ||
3544 | unsigned long flags; | ||
3545 | |||
3546 | if (list_empty(&event->rb_entry)) | ||
3547 | return; | ||
3548 | |||
3549 | spin_lock_irqsave(&rb->event_lock, flags); | ||
3550 | list_del_init(&event->rb_entry); | ||
3551 | wake_up_all(&event->waitq); | ||
3552 | spin_unlock_irqrestore(&rb->event_lock, flags); | ||
3553 | } | ||
3554 | |||
3555 | static void ring_buffer_wakeup(struct perf_event *event) | ||
3556 | { | ||
3557 | struct ring_buffer *rb; | ||
3558 | |||
3559 | rcu_read_lock(); | ||
3560 | rb = rcu_dereference(event->rb); | ||
3561 | list_for_each_entry_rcu(event, &rb->event_list, rb_entry) { | ||
3562 | wake_up_all(&event->waitq); | ||
3563 | } | ||
3564 | rcu_read_unlock(); | ||
3565 | } | ||
3566 | |||
3499 | static void rb_free_rcu(struct rcu_head *rcu_head) | 3567 | static void rb_free_rcu(struct rcu_head *rcu_head) |
3500 | { | 3568 | { |
3501 | struct ring_buffer *rb; | 3569 | struct ring_buffer *rb; |
@@ -3521,9 +3589,19 @@ static struct ring_buffer *ring_buffer_get(struct perf_event *event) | |||
3521 | 3589 | ||
3522 | static void ring_buffer_put(struct ring_buffer *rb) | 3590 | static void ring_buffer_put(struct ring_buffer *rb) |
3523 | { | 3591 | { |
3592 | struct perf_event *event, *n; | ||
3593 | unsigned long flags; | ||
3594 | |||
3524 | if (!atomic_dec_and_test(&rb->refcount)) | 3595 | if (!atomic_dec_and_test(&rb->refcount)) |
3525 | return; | 3596 | return; |
3526 | 3597 | ||
3598 | spin_lock_irqsave(&rb->event_lock, flags); | ||
3599 | list_for_each_entry_safe(event, n, &rb->event_list, rb_entry) { | ||
3600 | list_del_init(&event->rb_entry); | ||
3601 | wake_up_all(&event->waitq); | ||
3602 | } | ||
3603 | spin_unlock_irqrestore(&rb->event_lock, flags); | ||
3604 | |||
3527 | call_rcu(&rb->rcu_head, rb_free_rcu); | 3605 | call_rcu(&rb->rcu_head, rb_free_rcu); |
3528 | } | 3606 | } |
3529 | 3607 | ||
@@ -3546,6 +3624,7 @@ static void perf_mmap_close(struct vm_area_struct *vma) | |||
3546 | atomic_long_sub((size >> PAGE_SHIFT) + 1, &user->locked_vm); | 3624 | atomic_long_sub((size >> PAGE_SHIFT) + 1, &user->locked_vm); |
3547 | vma->vm_mm->pinned_vm -= event->mmap_locked; | 3625 | vma->vm_mm->pinned_vm -= event->mmap_locked; |
3548 | rcu_assign_pointer(event->rb, NULL); | 3626 | rcu_assign_pointer(event->rb, NULL); |
3627 | ring_buffer_detach(event, rb); | ||
3549 | mutex_unlock(&event->mmap_mutex); | 3628 | mutex_unlock(&event->mmap_mutex); |
3550 | 3629 | ||
3551 | ring_buffer_put(rb); | 3630 | ring_buffer_put(rb); |
@@ -3700,7 +3779,7 @@ static const struct file_operations perf_fops = { | |||
3700 | 3779 | ||
3701 | void perf_event_wakeup(struct perf_event *event) | 3780 | void perf_event_wakeup(struct perf_event *event) |
3702 | { | 3781 | { |
3703 | wake_up_all(&event->waitq); | 3782 | ring_buffer_wakeup(event); |
3704 | 3783 | ||
3705 | if (event->pending_kill) { | 3784 | if (event->pending_kill) { |
3706 | kill_fasync(&event->fasync, SIGIO, event->pending_kill); | 3785 | kill_fasync(&event->fasync, SIGIO, event->pending_kill); |
@@ -5822,6 +5901,8 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, | |||
5822 | INIT_LIST_HEAD(&event->group_entry); | 5901 | INIT_LIST_HEAD(&event->group_entry); |
5823 | INIT_LIST_HEAD(&event->event_entry); | 5902 | INIT_LIST_HEAD(&event->event_entry); |
5824 | INIT_LIST_HEAD(&event->sibling_list); | 5903 | INIT_LIST_HEAD(&event->sibling_list); |
5904 | INIT_LIST_HEAD(&event->rb_entry); | ||
5905 | |||
5825 | init_waitqueue_head(&event->waitq); | 5906 | init_waitqueue_head(&event->waitq); |
5826 | init_irq_work(&event->pending, perf_pending_event); | 5907 | init_irq_work(&event->pending, perf_pending_event); |
5827 | 5908 | ||
@@ -6028,6 +6109,8 @@ set: | |||
6028 | 6109 | ||
6029 | old_rb = event->rb; | 6110 | old_rb = event->rb; |
6030 | rcu_assign_pointer(event->rb, rb); | 6111 | rcu_assign_pointer(event->rb, rb); |
6112 | if (old_rb) | ||
6113 | ring_buffer_detach(event, old_rb); | ||
6031 | ret = 0; | 6114 | ret = 0; |
6032 | unlock: | 6115 | unlock: |
6033 | mutex_unlock(&event->mmap_mutex); | 6116 | mutex_unlock(&event->mmap_mutex); |
diff --git a/kernel/events/internal.h b/kernel/events/internal.h index 09097dd8116c..64568a699375 100644 --- a/kernel/events/internal.h +++ b/kernel/events/internal.h | |||
@@ -22,6 +22,9 @@ struct ring_buffer { | |||
22 | local_t lost; /* nr records lost */ | 22 | local_t lost; /* nr records lost */ |
23 | 23 | ||
24 | long watermark; /* wakeup watermark */ | 24 | long watermark; /* wakeup watermark */ |
25 | /* poll crap */ | ||
26 | spinlock_t event_lock; | ||
27 | struct list_head event_list; | ||
25 | 28 | ||
26 | struct perf_event_mmap_page *user_page; | 29 | struct perf_event_mmap_page *user_page; |
27 | void *data_pages[0]; | 30 | void *data_pages[0]; |
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index a2a29205cc0f..7f3011c6b57f 100644 --- a/kernel/events/ring_buffer.c +++ b/kernel/events/ring_buffer.c | |||
@@ -209,6 +209,9 @@ ring_buffer_init(struct ring_buffer *rb, long watermark, int flags) | |||
209 | rb->writable = 1; | 209 | rb->writable = 1; |
210 | 210 | ||
211 | atomic_set(&rb->refcount, 1); | 211 | atomic_set(&rb->refcount, 1); |
212 | |||
213 | INIT_LIST_HEAD(&rb->event_list); | ||
214 | spin_lock_init(&rb->event_lock); | ||
212 | } | 215 | } |
213 | 216 | ||
214 | #ifndef CONFIG_PERF_USE_VMALLOC | 217 | #ifndef CONFIG_PERF_USE_VMALLOC |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 0e2b179bc7b3..1da999f5e746 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -623,8 +623,9 @@ static irqreturn_t irq_nested_primary_handler(int irq, void *dev_id) | |||
623 | 623 | ||
624 | static int irq_wait_for_interrupt(struct irqaction *action) | 624 | static int irq_wait_for_interrupt(struct irqaction *action) |
625 | { | 625 | { |
626 | set_current_state(TASK_INTERRUPTIBLE); | ||
627 | |||
626 | while (!kthread_should_stop()) { | 628 | while (!kthread_should_stop()) { |
627 | set_current_state(TASK_INTERRUPTIBLE); | ||
628 | 629 | ||
629 | if (test_and_clear_bit(IRQTF_RUNTHREAD, | 630 | if (test_and_clear_bit(IRQTF_RUNTHREAD, |
630 | &action->thread_flags)) { | 631 | &action->thread_flags)) { |
@@ -632,7 +633,9 @@ static int irq_wait_for_interrupt(struct irqaction *action) | |||
632 | return 0; | 633 | return 0; |
633 | } | 634 | } |
634 | schedule(); | 635 | schedule(); |
636 | set_current_state(TASK_INTERRUPTIBLE); | ||
635 | } | 637 | } |
638 | __set_current_state(TASK_RUNNING); | ||
636 | return -1; | 639 | return -1; |
637 | } | 640 | } |
638 | 641 | ||
diff --git a/kernel/jump_label.c b/kernel/jump_label.c index bbdfe2a462a0..66ff7109f697 100644 --- a/kernel/jump_label.c +++ b/kernel/jump_label.c | |||
@@ -66,8 +66,9 @@ void jump_label_inc(struct jump_label_key *key) | |||
66 | return; | 66 | return; |
67 | 67 | ||
68 | jump_label_lock(); | 68 | jump_label_lock(); |
69 | if (atomic_add_return(1, &key->enabled) == 1) | 69 | if (atomic_read(&key->enabled) == 0) |
70 | jump_label_update(key, JUMP_LABEL_ENABLE); | 70 | jump_label_update(key, JUMP_LABEL_ENABLE); |
71 | atomic_inc(&key->enabled); | ||
71 | jump_label_unlock(); | 72 | jump_label_unlock(); |
72 | } | 73 | } |
73 | 74 | ||
diff --git a/kernel/lockdep.c b/kernel/lockdep.c index e69434b070da..b2e08c932d91 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/stringify.h> | 44 | #include <linux/stringify.h> |
45 | #include <linux/bitops.h> | 45 | #include <linux/bitops.h> |
46 | #include <linux/gfp.h> | 46 | #include <linux/gfp.h> |
47 | #include <linux/kmemcheck.h> | ||
47 | 48 | ||
48 | #include <asm/sections.h> | 49 | #include <asm/sections.h> |
49 | 50 | ||
@@ -2948,7 +2949,12 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, | |||
2948 | void lockdep_init_map(struct lockdep_map *lock, const char *name, | 2949 | void lockdep_init_map(struct lockdep_map *lock, const char *name, |
2949 | struct lock_class_key *key, int subclass) | 2950 | struct lock_class_key *key, int subclass) |
2950 | { | 2951 | { |
2951 | memset(lock, 0, sizeof(*lock)); | 2952 | int i; |
2953 | |||
2954 | kmemcheck_mark_initialized(lock, sizeof(*lock)); | ||
2955 | |||
2956 | for (i = 0; i < NR_LOCKDEP_CACHING_CLASSES; i++) | ||
2957 | lock->class_cache[i] = NULL; | ||
2952 | 2958 | ||
2953 | #ifdef CONFIG_LOCK_STAT | 2959 | #ifdef CONFIG_LOCK_STAT |
2954 | lock->cpu = raw_smp_processor_id(); | 2960 | lock->cpu = raw_smp_processor_id(); |
diff --git a/kernel/printk.c b/kernel/printk.c index 1455a0d4eedd..7982a0a841ea 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -1293,10 +1293,11 @@ again: | |||
1293 | raw_spin_lock(&logbuf_lock); | 1293 | raw_spin_lock(&logbuf_lock); |
1294 | if (con_start != log_end) | 1294 | if (con_start != log_end) |
1295 | retry = 1; | 1295 | retry = 1; |
1296 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | ||
1297 | |||
1296 | if (retry && console_trylock()) | 1298 | if (retry && console_trylock()) |
1297 | goto again; | 1299 | goto again; |
1298 | 1300 | ||
1299 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | ||
1300 | if (wake_klogd) | 1301 | if (wake_klogd) |
1301 | wake_up_klogd(); | 1302 | wake_up_klogd(); |
1302 | } | 1303 | } |
diff --git a/kernel/sched.c b/kernel/sched.c index 0e9344a71be3..d6b149ccf925 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -71,6 +71,7 @@ | |||
71 | #include <linux/ctype.h> | 71 | #include <linux/ctype.h> |
72 | #include <linux/ftrace.h> | 72 | #include <linux/ftrace.h> |
73 | #include <linux/slab.h> | 73 | #include <linux/slab.h> |
74 | #include <linux/init_task.h> | ||
74 | 75 | ||
75 | #include <asm/tlb.h> | 76 | #include <asm/tlb.h> |
76 | #include <asm/irq_regs.h> | 77 | #include <asm/irq_regs.h> |
@@ -4810,6 +4811,9 @@ EXPORT_SYMBOL(wait_for_completion); | |||
4810 | * This waits for either a completion of a specific task to be signaled or for a | 4811 | * This waits for either a completion of a specific task to be signaled or for a |
4811 | * specified timeout to expire. The timeout is in jiffies. It is not | 4812 | * specified timeout to expire. The timeout is in jiffies. It is not |
4812 | * interruptible. | 4813 | * interruptible. |
4814 | * | ||
4815 | * The return value is 0 if timed out, and positive (at least 1, or number of | ||
4816 | * jiffies left till timeout) if completed. | ||
4813 | */ | 4817 | */ |
4814 | unsigned long __sched | 4818 | unsigned long __sched |
4815 | wait_for_completion_timeout(struct completion *x, unsigned long timeout) | 4819 | wait_for_completion_timeout(struct completion *x, unsigned long timeout) |
@@ -4824,6 +4828,8 @@ EXPORT_SYMBOL(wait_for_completion_timeout); | |||
4824 | * | 4828 | * |
4825 | * This waits for completion of a specific task to be signaled. It is | 4829 | * This waits for completion of a specific task to be signaled. It is |
4826 | * interruptible. | 4830 | * interruptible. |
4831 | * | ||
4832 | * The return value is -ERESTARTSYS if interrupted, 0 if completed. | ||
4827 | */ | 4833 | */ |
4828 | int __sched wait_for_completion_interruptible(struct completion *x) | 4834 | int __sched wait_for_completion_interruptible(struct completion *x) |
4829 | { | 4835 | { |
@@ -4841,6 +4847,9 @@ EXPORT_SYMBOL(wait_for_completion_interruptible); | |||
4841 | * | 4847 | * |
4842 | * This waits for either a completion of a specific task to be signaled or for a | 4848 | * This waits for either a completion of a specific task to be signaled or for a |
4843 | * specified timeout to expire. It is interruptible. The timeout is in jiffies. | 4849 | * specified timeout to expire. It is interruptible. The timeout is in jiffies. |
4850 | * | ||
4851 | * The return value is -ERESTARTSYS if interrupted, 0 if timed out, | ||
4852 | * positive (at least 1, or number of jiffies left till timeout) if completed. | ||
4844 | */ | 4853 | */ |
4845 | long __sched | 4854 | long __sched |
4846 | wait_for_completion_interruptible_timeout(struct completion *x, | 4855 | wait_for_completion_interruptible_timeout(struct completion *x, |
@@ -4856,6 +4865,8 @@ EXPORT_SYMBOL(wait_for_completion_interruptible_timeout); | |||
4856 | * | 4865 | * |
4857 | * This waits to be signaled for completion of a specific task. It can be | 4866 | * This waits to be signaled for completion of a specific task. It can be |
4858 | * interrupted by a kill signal. | 4867 | * interrupted by a kill signal. |
4868 | * | ||
4869 | * The return value is -ERESTARTSYS if interrupted, 0 if completed. | ||
4859 | */ | 4870 | */ |
4860 | int __sched wait_for_completion_killable(struct completion *x) | 4871 | int __sched wait_for_completion_killable(struct completion *x) |
4861 | { | 4872 | { |
@@ -4874,6 +4885,9 @@ EXPORT_SYMBOL(wait_for_completion_killable); | |||
4874 | * This waits for either a completion of a specific task to be | 4885 | * This waits for either a completion of a specific task to be |
4875 | * signaled or for a specified timeout to expire. It can be | 4886 | * signaled or for a specified timeout to expire. It can be |
4876 | * interrupted by a kill signal. The timeout is in jiffies. | 4887 | * interrupted by a kill signal. The timeout is in jiffies. |
4888 | * | ||
4889 | * The return value is -ERESTARTSYS if interrupted, 0 if timed out, | ||
4890 | * positive (at least 1, or number of jiffies left till timeout) if completed. | ||
4877 | */ | 4891 | */ |
4878 | long __sched | 4892 | long __sched |
4879 | wait_for_completion_killable_timeout(struct completion *x, | 4893 | wait_for_completion_killable_timeout(struct completion *x, |
@@ -6099,6 +6113,9 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu) | |||
6099 | */ | 6113 | */ |
6100 | idle->sched_class = &idle_sched_class; | 6114 | idle->sched_class = &idle_sched_class; |
6101 | ftrace_graph_init_idle_task(idle, cpu); | 6115 | ftrace_graph_init_idle_task(idle, cpu); |
6116 | #if defined(CONFIG_SMP) | ||
6117 | sprintf(idle->comm, "%s/%d", INIT_TASK_COMM, cpu); | ||
6118 | #endif | ||
6102 | } | 6119 | } |
6103 | 6120 | ||
6104 | /* | 6121 | /* |
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 5c9e67923b7c..a78ed2736ba7 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -772,19 +772,32 @@ static void update_cfs_load(struct cfs_rq *cfs_rq, int global_update) | |||
772 | list_del_leaf_cfs_rq(cfs_rq); | 772 | list_del_leaf_cfs_rq(cfs_rq); |
773 | } | 773 | } |
774 | 774 | ||
775 | static inline long calc_tg_weight(struct task_group *tg, struct cfs_rq *cfs_rq) | ||
776 | { | ||
777 | long tg_weight; | ||
778 | |||
779 | /* | ||
780 | * Use this CPU's actual weight instead of the last load_contribution | ||
781 | * to gain a more accurate current total weight. See | ||
782 | * update_cfs_rq_load_contribution(). | ||
783 | */ | ||
784 | tg_weight = atomic_read(&tg->load_weight); | ||
785 | tg_weight -= cfs_rq->load_contribution; | ||
786 | tg_weight += cfs_rq->load.weight; | ||
787 | |||
788 | return tg_weight; | ||
789 | } | ||
790 | |||
775 | static long calc_cfs_shares(struct cfs_rq *cfs_rq, struct task_group *tg) | 791 | static long calc_cfs_shares(struct cfs_rq *cfs_rq, struct task_group *tg) |
776 | { | 792 | { |
777 | long load_weight, load, shares; | 793 | long tg_weight, load, shares; |
778 | 794 | ||
795 | tg_weight = calc_tg_weight(tg, cfs_rq); | ||
779 | load = cfs_rq->load.weight; | 796 | load = cfs_rq->load.weight; |
780 | 797 | ||
781 | load_weight = atomic_read(&tg->load_weight); | ||
782 | load_weight += load; | ||
783 | load_weight -= cfs_rq->load_contribution; | ||
784 | |||
785 | shares = (tg->shares * load); | 798 | shares = (tg->shares * load); |
786 | if (load_weight) | 799 | if (tg_weight) |
787 | shares /= load_weight; | 800 | shares /= tg_weight; |
788 | 801 | ||
789 | if (shares < MIN_SHARES) | 802 | if (shares < MIN_SHARES) |
790 | shares = MIN_SHARES; | 803 | shares = MIN_SHARES; |
@@ -1743,7 +1756,7 @@ static void __return_cfs_rq_runtime(struct cfs_rq *cfs_rq) | |||
1743 | 1756 | ||
1744 | static __always_inline void return_cfs_rq_runtime(struct cfs_rq *cfs_rq) | 1757 | static __always_inline void return_cfs_rq_runtime(struct cfs_rq *cfs_rq) |
1745 | { | 1758 | { |
1746 | if (!cfs_rq->runtime_enabled || !cfs_rq->nr_running) | 1759 | if (!cfs_rq->runtime_enabled || cfs_rq->nr_running) |
1747 | return; | 1760 | return; |
1748 | 1761 | ||
1749 | __return_cfs_rq_runtime(cfs_rq); | 1762 | __return_cfs_rq_runtime(cfs_rq); |
@@ -2036,36 +2049,100 @@ static void task_waking_fair(struct task_struct *p) | |||
2036 | * Adding load to a group doesn't make a group heavier, but can cause movement | 2049 | * Adding load to a group doesn't make a group heavier, but can cause movement |
2037 | * of group shares between cpus. Assuming the shares were perfectly aligned one | 2050 | * of group shares between cpus. Assuming the shares were perfectly aligned one |
2038 | * can calculate the shift in shares. | 2051 | * can calculate the shift in shares. |
2052 | * | ||
2053 | * Calculate the effective load difference if @wl is added (subtracted) to @tg | ||
2054 | * on this @cpu and results in a total addition (subtraction) of @wg to the | ||
2055 | * total group weight. | ||
2056 | * | ||
2057 | * Given a runqueue weight distribution (rw_i) we can compute a shares | ||
2058 | * distribution (s_i) using: | ||
2059 | * | ||
2060 | * s_i = rw_i / \Sum rw_j (1) | ||
2061 | * | ||
2062 | * Suppose we have 4 CPUs and our @tg is a direct child of the root group and | ||
2063 | * has 7 equal weight tasks, distributed as below (rw_i), with the resulting | ||
2064 | * shares distribution (s_i): | ||
2065 | * | ||
2066 | * rw_i = { 2, 4, 1, 0 } | ||
2067 | * s_i = { 2/7, 4/7, 1/7, 0 } | ||
2068 | * | ||
2069 | * As per wake_affine() we're interested in the load of two CPUs (the CPU the | ||
2070 | * task used to run on and the CPU the waker is running on), we need to | ||
2071 | * compute the effect of waking a task on either CPU and, in case of a sync | ||
2072 | * wakeup, compute the effect of the current task going to sleep. | ||
2073 | * | ||
2074 | * So for a change of @wl to the local @cpu with an overall group weight change | ||
2075 | * of @wl we can compute the new shares distribution (s'_i) using: | ||
2076 | * | ||
2077 | * s'_i = (rw_i + @wl) / (@wg + \Sum rw_j) (2) | ||
2078 | * | ||
2079 | * Suppose we're interested in CPUs 0 and 1, and want to compute the load | ||
2080 | * differences in waking a task to CPU 0. The additional task changes the | ||
2081 | * weight and shares distributions like: | ||
2082 | * | ||
2083 | * rw'_i = { 3, 4, 1, 0 } | ||
2084 | * s'_i = { 3/8, 4/8, 1/8, 0 } | ||
2085 | * | ||
2086 | * We can then compute the difference in effective weight by using: | ||
2087 | * | ||
2088 | * dw_i = S * (s'_i - s_i) (3) | ||
2089 | * | ||
2090 | * Where 'S' is the group weight as seen by its parent. | ||
2091 | * | ||
2092 | * Therefore the effective change in loads on CPU 0 would be 5/56 (3/8 - 2/7) | ||
2093 | * times the weight of the group. The effect on CPU 1 would be -4/56 (4/8 - | ||
2094 | * 4/7) times the weight of the group. | ||
2039 | */ | 2095 | */ |
2040 | static long effective_load(struct task_group *tg, int cpu, long wl, long wg) | 2096 | static long effective_load(struct task_group *tg, int cpu, long wl, long wg) |
2041 | { | 2097 | { |
2042 | struct sched_entity *se = tg->se[cpu]; | 2098 | struct sched_entity *se = tg->se[cpu]; |
2043 | 2099 | ||
2044 | if (!tg->parent) | 2100 | if (!tg->parent) /* the trivial, non-cgroup case */ |
2045 | return wl; | 2101 | return wl; |
2046 | 2102 | ||
2047 | for_each_sched_entity(se) { | 2103 | for_each_sched_entity(se) { |
2048 | long lw, w; | 2104 | long w, W; |
2049 | 2105 | ||
2050 | tg = se->my_q->tg; | 2106 | tg = se->my_q->tg; |
2051 | w = se->my_q->load.weight; | ||
2052 | 2107 | ||
2053 | /* use this cpu's instantaneous contribution */ | 2108 | /* |
2054 | lw = atomic_read(&tg->load_weight); | 2109 | * W = @wg + \Sum rw_j |
2055 | lw -= se->my_q->load_contribution; | 2110 | */ |
2056 | lw += w + wg; | 2111 | W = wg + calc_tg_weight(tg, se->my_q); |
2057 | 2112 | ||
2058 | wl += w; | 2113 | /* |
2114 | * w = rw_i + @wl | ||
2115 | */ | ||
2116 | w = se->my_q->load.weight + wl; | ||
2059 | 2117 | ||
2060 | if (lw > 0 && wl < lw) | 2118 | /* |
2061 | wl = (wl * tg->shares) / lw; | 2119 | * wl = S * s'_i; see (2) |
2120 | */ | ||
2121 | if (W > 0 && w < W) | ||
2122 | wl = (w * tg->shares) / W; | ||
2062 | else | 2123 | else |
2063 | wl = tg->shares; | 2124 | wl = tg->shares; |
2064 | 2125 | ||
2065 | /* zero point is MIN_SHARES */ | 2126 | /* |
2127 | * Per the above, wl is the new se->load.weight value; since | ||
2128 | * those are clipped to [MIN_SHARES, ...) do so now. See | ||
2129 | * calc_cfs_shares(). | ||
2130 | */ | ||
2066 | if (wl < MIN_SHARES) | 2131 | if (wl < MIN_SHARES) |
2067 | wl = MIN_SHARES; | 2132 | wl = MIN_SHARES; |
2133 | |||
2134 | /* | ||
2135 | * wl = dw_i = S * (s'_i - s_i); see (3) | ||
2136 | */ | ||
2068 | wl -= se->load.weight; | 2137 | wl -= se->load.weight; |
2138 | |||
2139 | /* | ||
2140 | * Recursively apply this logic to all parent groups to compute | ||
2141 | * the final effective load change on the root group. Since | ||
2142 | * only the @tg group gets extra weight, all parent groups can | ||
2143 | * only redistribute existing shares. @wl is the shift in shares | ||
2144 | * resulting from this level per the above. | ||
2145 | */ | ||
2069 | wg = 0; | 2146 | wg = 0; |
2070 | } | 2147 | } |
2071 | 2148 | ||
@@ -2249,7 +2326,8 @@ static int select_idle_sibling(struct task_struct *p, int target) | |||
2249 | int cpu = smp_processor_id(); | 2326 | int cpu = smp_processor_id(); |
2250 | int prev_cpu = task_cpu(p); | 2327 | int prev_cpu = task_cpu(p); |
2251 | struct sched_domain *sd; | 2328 | struct sched_domain *sd; |
2252 | int i; | 2329 | struct sched_group *sg; |
2330 | int i, smt = 0; | ||
2253 | 2331 | ||
2254 | /* | 2332 | /* |
2255 | * If the task is going to be woken-up on this cpu and if it is | 2333 | * If the task is going to be woken-up on this cpu and if it is |
@@ -2269,25 +2347,38 @@ static int select_idle_sibling(struct task_struct *p, int target) | |||
2269 | * Otherwise, iterate the domains and find an elegible idle cpu. | 2347 | * Otherwise, iterate the domains and find an elegible idle cpu. |
2270 | */ | 2348 | */ |
2271 | rcu_read_lock(); | 2349 | rcu_read_lock(); |
2350 | again: | ||
2272 | for_each_domain(target, sd) { | 2351 | for_each_domain(target, sd) { |
2273 | if (!(sd->flags & SD_SHARE_PKG_RESOURCES)) | 2352 | if (!smt && (sd->flags & SD_SHARE_CPUPOWER)) |
2274 | break; | 2353 | continue; |
2275 | 2354 | ||
2276 | for_each_cpu_and(i, sched_domain_span(sd), tsk_cpus_allowed(p)) { | 2355 | if (!(sd->flags & SD_SHARE_PKG_RESOURCES)) { |
2277 | if (idle_cpu(i)) { | 2356 | if (!smt) { |
2278 | target = i; | 2357 | smt = 1; |
2279 | break; | 2358 | goto again; |
2280 | } | 2359 | } |
2360 | break; | ||
2281 | } | 2361 | } |
2282 | 2362 | ||
2283 | /* | 2363 | sg = sd->groups; |
2284 | * Lets stop looking for an idle sibling when we reached | 2364 | do { |
2285 | * the domain that spans the current cpu and prev_cpu. | 2365 | if (!cpumask_intersects(sched_group_cpus(sg), |
2286 | */ | 2366 | tsk_cpus_allowed(p))) |
2287 | if (cpumask_test_cpu(cpu, sched_domain_span(sd)) && | 2367 | goto next; |
2288 | cpumask_test_cpu(prev_cpu, sched_domain_span(sd))) | 2368 | |
2289 | break; | 2369 | for_each_cpu(i, sched_group_cpus(sg)) { |
2370 | if (!idle_cpu(i)) | ||
2371 | goto next; | ||
2372 | } | ||
2373 | |||
2374 | target = cpumask_first_and(sched_group_cpus(sg), | ||
2375 | tsk_cpus_allowed(p)); | ||
2376 | goto done; | ||
2377 | next: | ||
2378 | sg = sg->next; | ||
2379 | } while (sg != sd->groups); | ||
2290 | } | 2380 | } |
2381 | done: | ||
2291 | rcu_read_unlock(); | 2382 | rcu_read_unlock(); |
2292 | 2383 | ||
2293 | return target; | 2384 | return target; |
@@ -3511,7 +3602,7 @@ static bool update_sd_pick_busiest(struct sched_domain *sd, | |||
3511 | } | 3602 | } |
3512 | 3603 | ||
3513 | /** | 3604 | /** |
3514 | * update_sd_lb_stats - Update sched_group's statistics for load balancing. | 3605 | * update_sd_lb_stats - Update sched_domain's statistics for load balancing. |
3515 | * @sd: sched_domain whose statistics are to be updated. | 3606 | * @sd: sched_domain whose statistics are to be updated. |
3516 | * @this_cpu: Cpu for which load balance is currently performed. | 3607 | * @this_cpu: Cpu for which load balance is currently performed. |
3517 | * @idle: Idle status of this_cpu | 3608 | * @idle: Idle status of this_cpu |
diff --git a/kernel/sched_features.h b/kernel/sched_features.h index efa0a7b75dde..84802245abd2 100644 --- a/kernel/sched_features.h +++ b/kernel/sched_features.h | |||
@@ -67,3 +67,4 @@ SCHED_FEAT(NONTASK_POWER, 1) | |||
67 | SCHED_FEAT(TTWU_QUEUE, 1) | 67 | SCHED_FEAT(TTWU_QUEUE, 1) |
68 | 68 | ||
69 | SCHED_FEAT(FORCE_SD_OVERLAP, 0) | 69 | SCHED_FEAT(FORCE_SD_OVERLAP, 0) |
70 | SCHED_FEAT(RT_RUNTIME_SHARE, 1) | ||
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index 056cbd2e2a27..583a1368afe6 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c | |||
@@ -560,6 +560,9 @@ static int balance_runtime(struct rt_rq *rt_rq) | |||
560 | { | 560 | { |
561 | int more = 0; | 561 | int more = 0; |
562 | 562 | ||
563 | if (!sched_feat(RT_RUNTIME_SHARE)) | ||
564 | return more; | ||
565 | |||
563 | if (rt_rq->rt_time > rt_rq->rt_runtime) { | 566 | if (rt_rq->rt_time > rt_rq->rt_runtime) { |
564 | raw_spin_unlock(&rt_rq->rt_runtime_lock); | 567 | raw_spin_unlock(&rt_rq->rt_runtime_lock); |
565 | more = do_balance_runtime(rt_rq); | 568 | more = do_balance_runtime(rt_rq); |
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index c436e790b21b..8a46f5d64504 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c | |||
@@ -195,7 +195,7 @@ static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) | |||
195 | struct alarm *alarm; | 195 | struct alarm *alarm; |
196 | ktime_t expired = next->expires; | 196 | ktime_t expired = next->expires; |
197 | 197 | ||
198 | if (expired.tv64 >= now.tv64) | 198 | if (expired.tv64 > now.tv64) |
199 | break; | 199 | break; |
200 | 200 | ||
201 | alarm = container_of(next, struct alarm, node); | 201 | alarm = container_of(next, struct alarm, node); |
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 1ecd6ba36d6c..c4eb71c8b2ea 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
@@ -387,6 +387,7 @@ void clockevents_exchange_device(struct clock_event_device *old, | |||
387 | * released list and do a notify add later. | 387 | * released list and do a notify add later. |
388 | */ | 388 | */ |
389 | if (old) { | 389 | if (old) { |
390 | old->event_handler = clockevents_handle_noop; | ||
390 | clockevents_set_mode(old, CLOCK_EVT_MODE_UNUSED); | 391 | clockevents_set_mode(old, CLOCK_EVT_MODE_UNUSED); |
391 | list_del(&old->list); | 392 | list_del(&old->list); |
392 | list_add(&old->list, &clockevents_released); | 393 | list_add(&old->list, &clockevents_released); |
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index cfc65e1eb9fb..da2f760e780c 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
@@ -548,7 +548,7 @@ static u64 clocksource_max_deferment(struct clocksource *cs) | |||
548 | * note a margin of 12.5% is used because this can be computed with | 548 | * note a margin of 12.5% is used because this can be computed with |
549 | * a shift, versus say 10% which would require division. | 549 | * a shift, versus say 10% which would require division. |
550 | */ | 550 | */ |
551 | return max_nsecs - (max_nsecs >> 5); | 551 | return max_nsecs - (max_nsecs >> 3); |
552 | } | 552 | } |
553 | 553 | ||
554 | #ifndef CONFIG_ARCH_USES_GETTIMEOFFSET | 554 | #ifndef CONFIG_ARCH_USES_GETTIMEOFFSET |
@@ -669,7 +669,7 @@ void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq) | |||
669 | * ~ 0.06ppm granularity for NTP. We apply the same 12.5% | 669 | * ~ 0.06ppm granularity for NTP. We apply the same 12.5% |
670 | * margin as we do in clocksource_max_deferment() | 670 | * margin as we do in clocksource_max_deferment() |
671 | */ | 671 | */ |
672 | sec = (cs->mask - (cs->mask >> 5)); | 672 | sec = (cs->mask - (cs->mask >> 3)); |
673 | do_div(sec, freq); | 673 | do_div(sec, freq); |
674 | do_div(sec, scale); | 674 | do_div(sec, scale); |
675 | if (!sec) | 675 | if (!sec) |
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index f954282d9a82..fd4a7b1625a2 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
@@ -71,7 +71,7 @@ int tick_check_broadcast_device(struct clock_event_device *dev) | |||
71 | (dev->features & CLOCK_EVT_FEAT_C3STOP)) | 71 | (dev->features & CLOCK_EVT_FEAT_C3STOP)) |
72 | return 0; | 72 | return 0; |
73 | 73 | ||
74 | clockevents_exchange_device(NULL, dev); | 74 | clockevents_exchange_device(tick_broadcast_device.evtdev, dev); |
75 | tick_broadcast_device.evtdev = dev; | 75 | tick_broadcast_device.evtdev = dev; |
76 | if (!cpumask_empty(tick_get_broadcast_mask())) | 76 | if (!cpumask_empty(tick_get_broadcast_mask())) |
77 | tick_broadcast_start_periodic(dev); | 77 | tick_broadcast_start_periodic(dev); |
diff --git a/kernel/timer.c b/kernel/timer.c index dbaa62422b13..9c3c62b0c4bc 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -1368,7 +1368,7 @@ SYSCALL_DEFINE0(getppid) | |||
1368 | int pid; | 1368 | int pid; |
1369 | 1369 | ||
1370 | rcu_read_lock(); | 1370 | rcu_read_lock(); |
1371 | pid = task_tgid_vnr(current->real_parent); | 1371 | pid = task_tgid_vnr(rcu_dereference(current->real_parent)); |
1372 | rcu_read_unlock(); | 1372 | rcu_read_unlock(); |
1373 | 1373 | ||
1374 | return pid; | 1374 | return pid; |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 900b409543db..b1e8943fed1d 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -152,7 +152,6 @@ void clear_ftrace_function(void) | |||
152 | ftrace_pid_function = ftrace_stub; | 152 | ftrace_pid_function = ftrace_stub; |
153 | } | 153 | } |
154 | 154 | ||
155 | #undef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST | ||
156 | #ifndef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST | 155 | #ifndef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST |
157 | /* | 156 | /* |
158 | * For those archs that do not test ftrace_trace_stop in their | 157 | * For those archs that do not test ftrace_trace_stop in their |
@@ -1212,7 +1211,9 @@ ftrace_hash_move(struct ftrace_ops *ops, int enable, | |||
1212 | if (!src->count) { | 1211 | if (!src->count) { |
1213 | free_ftrace_hash_rcu(*dst); | 1212 | free_ftrace_hash_rcu(*dst); |
1214 | rcu_assign_pointer(*dst, EMPTY_HASH); | 1213 | rcu_assign_pointer(*dst, EMPTY_HASH); |
1215 | return 0; | 1214 | /* still need to update the function records */ |
1215 | ret = 0; | ||
1216 | goto out; | ||
1216 | } | 1217 | } |
1217 | 1218 | ||
1218 | /* | 1219 | /* |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 581876f9f387..c212a7f934ec 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -1078,7 +1078,6 @@ event_subsystem_dir(const char *name, struct dentry *d_events) | |||
1078 | /* First see if we did not already create this dir */ | 1078 | /* First see if we did not already create this dir */ |
1079 | list_for_each_entry(system, &event_subsystems, list) { | 1079 | list_for_each_entry(system, &event_subsystems, list) { |
1080 | if (strcmp(system->name, name) == 0) { | 1080 | if (strcmp(system->name, name) == 0) { |
1081 | __get_system(system); | ||
1082 | system->nr_events++; | 1081 | system->nr_events++; |
1083 | return system->entry; | 1082 | return system->entry; |
1084 | } | 1083 | } |
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 816d3d074979..95dc31efd6dd 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
@@ -1649,7 +1649,9 @@ static int replace_system_preds(struct event_subsystem *system, | |||
1649 | */ | 1649 | */ |
1650 | err = replace_preds(call, NULL, ps, filter_string, true); | 1650 | err = replace_preds(call, NULL, ps, filter_string, true); |
1651 | if (err) | 1651 | if (err) |
1652 | goto fail; | 1652 | call->flags |= TRACE_EVENT_FL_NO_SET_FILTER; |
1653 | else | ||
1654 | call->flags &= ~TRACE_EVENT_FL_NO_SET_FILTER; | ||
1653 | } | 1655 | } |
1654 | 1656 | ||
1655 | list_for_each_entry(call, &ftrace_events, list) { | 1657 | list_for_each_entry(call, &ftrace_events, list) { |
@@ -1658,6 +1660,9 @@ static int replace_system_preds(struct event_subsystem *system, | |||
1658 | if (strcmp(call->class->system, system->name) != 0) | 1660 | if (strcmp(call->class->system, system->name) != 0) |
1659 | continue; | 1661 | continue; |
1660 | 1662 | ||
1663 | if (call->flags & TRACE_EVENT_FL_NO_SET_FILTER) | ||
1664 | continue; | ||
1665 | |||
1661 | filter_item = kzalloc(sizeof(*filter_item), GFP_KERNEL); | 1666 | filter_item = kzalloc(sizeof(*filter_item), GFP_KERNEL); |
1662 | if (!filter_item) | 1667 | if (!filter_item) |
1663 | goto fail_mem; | 1668 | goto fail_mem; |
@@ -1686,7 +1691,7 @@ static int replace_system_preds(struct event_subsystem *system, | |||
1686 | * replace the filter for the call. | 1691 | * replace the filter for the call. |
1687 | */ | 1692 | */ |
1688 | filter = call->filter; | 1693 | filter = call->filter; |
1689 | call->filter = filter_item->filter; | 1694 | rcu_assign_pointer(call->filter, filter_item->filter); |
1690 | filter_item->filter = filter; | 1695 | filter_item->filter = filter; |
1691 | 1696 | ||
1692 | fail = false; | 1697 | fail = false; |
@@ -1741,7 +1746,7 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string) | |||
1741 | filter = call->filter; | 1746 | filter = call->filter; |
1742 | if (!filter) | 1747 | if (!filter) |
1743 | goto out_unlock; | 1748 | goto out_unlock; |
1744 | call->filter = NULL; | 1749 | RCU_INIT_POINTER(call->filter, NULL); |
1745 | /* Make sure the filter is not being used */ | 1750 | /* Make sure the filter is not being used */ |
1746 | synchronize_sched(); | 1751 | synchronize_sched(); |
1747 | __free_filter(filter); | 1752 | __free_filter(filter); |
@@ -1782,7 +1787,7 @@ out: | |||
1782 | * string | 1787 | * string |
1783 | */ | 1788 | */ |
1784 | tmp = call->filter; | 1789 | tmp = call->filter; |
1785 | call->filter = filter; | 1790 | rcu_assign_pointer(call->filter, filter); |
1786 | if (tmp) { | 1791 | if (tmp) { |
1787 | /* Make sure the call is done with the filter */ | 1792 | /* Make sure the call is done with the filter */ |
1788 | synchronize_sched(); | 1793 | synchronize_sched(); |
diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 74c6c7fce749..fea790a2b176 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c | |||
@@ -245,7 +245,7 @@ static void put_hash_bucket(struct hash_bucket *bucket, | |||
245 | 245 | ||
246 | static bool exact_match(struct dma_debug_entry *a, struct dma_debug_entry *b) | 246 | static bool exact_match(struct dma_debug_entry *a, struct dma_debug_entry *b) |
247 | { | 247 | { |
248 | return ((a->dev_addr == a->dev_addr) && | 248 | return ((a->dev_addr == b->dev_addr) && |
249 | (a->dev == b->dev)) ? true : false; | 249 | (a->dev == b->dev)) ? true : false; |
250 | } | 250 | } |
251 | 251 | ||
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 4298abaae153..36b3d988b4ef 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -2259,12 +2259,8 @@ static void khugepaged_do_scan(struct page **hpage) | |||
2259 | 2259 | ||
2260 | static void khugepaged_alloc_sleep(void) | 2260 | static void khugepaged_alloc_sleep(void) |
2261 | { | 2261 | { |
2262 | DEFINE_WAIT(wait); | 2262 | wait_event_freezable_timeout(khugepaged_wait, false, |
2263 | add_wait_queue(&khugepaged_wait, &wait); | 2263 | msecs_to_jiffies(khugepaged_alloc_sleep_millisecs)); |
2264 | schedule_timeout_interruptible( | ||
2265 | msecs_to_jiffies( | ||
2266 | khugepaged_alloc_sleep_millisecs)); | ||
2267 | remove_wait_queue(&khugepaged_wait, &wait); | ||
2268 | } | 2264 | } |
2269 | 2265 | ||
2270 | #ifndef CONFIG_NUMA | 2266 | #ifndef CONFIG_NUMA |
@@ -2313,14 +2309,10 @@ static void khugepaged_loop(void) | |||
2313 | if (unlikely(kthread_should_stop())) | 2309 | if (unlikely(kthread_should_stop())) |
2314 | break; | 2310 | break; |
2315 | if (khugepaged_has_work()) { | 2311 | if (khugepaged_has_work()) { |
2316 | DEFINE_WAIT(wait); | ||
2317 | if (!khugepaged_scan_sleep_millisecs) | 2312 | if (!khugepaged_scan_sleep_millisecs) |
2318 | continue; | 2313 | continue; |
2319 | add_wait_queue(&khugepaged_wait, &wait); | 2314 | wait_event_freezable_timeout(khugepaged_wait, false, |
2320 | schedule_timeout_interruptible( | 2315 | msecs_to_jiffies(khugepaged_scan_sleep_millisecs)); |
2321 | msecs_to_jiffies( | ||
2322 | khugepaged_scan_sleep_millisecs)); | ||
2323 | remove_wait_queue(&khugepaged_wait, &wait); | ||
2324 | } else if (khugepaged_enabled()) | 2316 | } else if (khugepaged_enabled()) |
2325 | wait_event_freezable(khugepaged_wait, | 2317 | wait_event_freezable(khugepaged_wait, |
2326 | khugepaged_wait_event()); | 2318 | khugepaged_wait_event()); |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index bb28a5f9db8d..73f17c0293c0 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -576,6 +576,7 @@ static void prep_compound_gigantic_page(struct page *page, unsigned long order) | |||
576 | __SetPageHead(page); | 576 | __SetPageHead(page); |
577 | for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) { | 577 | for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) { |
578 | __SetPageTail(p); | 578 | __SetPageTail(p); |
579 | set_page_count(p, 0); | ||
579 | p->first_page = page; | 580 | p->first_page = page; |
580 | } | 581 | } |
581 | } | 582 | } |
diff --git a/mm/migrate.c b/mm/migrate.c index 578e29174fa6..177aca424a06 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -871,9 +871,9 @@ static int unmap_and_move_huge_page(new_page_t get_new_page, | |||
871 | 871 | ||
872 | if (anon_vma) | 872 | if (anon_vma) |
873 | put_anon_vma(anon_vma); | 873 | put_anon_vma(anon_vma); |
874 | out: | ||
875 | unlock_page(hpage); | 874 | unlock_page(hpage); |
876 | 875 | ||
876 | out: | ||
877 | if (rc != -EAGAIN) { | 877 | if (rc != -EAGAIN) { |
878 | list_del(&hpage->lru); | 878 | list_del(&hpage->lru); |
879 | put_page(hpage); | 879 | put_page(hpage); |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 9dd443d89d8b..2b8ba3aebf6e 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -356,8 +356,8 @@ void prep_compound_page(struct page *page, unsigned long order) | |||
356 | __SetPageHead(page); | 356 | __SetPageHead(page); |
357 | for (i = 1; i < nr_pages; i++) { | 357 | for (i = 1; i < nr_pages; i++) { |
358 | struct page *p = page + i; | 358 | struct page *p = page + i; |
359 | |||
360 | __SetPageTail(p); | 359 | __SetPageTail(p); |
360 | set_page_count(p, 0); | ||
361 | p->first_page = page; | 361 | p->first_page = page; |
362 | } | 362 | } |
363 | } | 363 | } |
@@ -3377,9 +3377,15 @@ static void setup_zone_migrate_reserve(struct zone *zone) | |||
3377 | unsigned long block_migratetype; | 3377 | unsigned long block_migratetype; |
3378 | int reserve; | 3378 | int reserve; |
3379 | 3379 | ||
3380 | /* Get the start pfn, end pfn and the number of blocks to reserve */ | 3380 | /* |
3381 | * Get the start pfn, end pfn and the number of blocks to reserve | ||
3382 | * We have to be careful to be aligned to pageblock_nr_pages to | ||
3383 | * make sure that we always check pfn_valid for the first page in | ||
3384 | * the block. | ||
3385 | */ | ||
3381 | start_pfn = zone->zone_start_pfn; | 3386 | start_pfn = zone->zone_start_pfn; |
3382 | end_pfn = start_pfn + zone->spanned_pages; | 3387 | end_pfn = start_pfn + zone->spanned_pages; |
3388 | start_pfn = roundup(start_pfn, pageblock_nr_pages); | ||
3383 | reserve = roundup(min_wmark_pages(zone), pageblock_nr_pages) >> | 3389 | reserve = roundup(min_wmark_pages(zone), pageblock_nr_pages) >> |
3384 | pageblock_order; | 3390 | pageblock_order; |
3385 | 3391 | ||
@@ -595,6 +595,7 @@ static enum { | |||
595 | PARTIAL_AC, | 595 | PARTIAL_AC, |
596 | PARTIAL_L3, | 596 | PARTIAL_L3, |
597 | EARLY, | 597 | EARLY, |
598 | LATE, | ||
598 | FULL | 599 | FULL |
599 | } g_cpucache_up; | 600 | } g_cpucache_up; |
600 | 601 | ||
@@ -671,7 +672,7 @@ static void init_node_lock_keys(int q) | |||
671 | { | 672 | { |
672 | struct cache_sizes *s = malloc_sizes; | 673 | struct cache_sizes *s = malloc_sizes; |
673 | 674 | ||
674 | if (g_cpucache_up != FULL) | 675 | if (g_cpucache_up < LATE) |
675 | return; | 676 | return; |
676 | 677 | ||
677 | for (s = malloc_sizes; s->cs_size != ULONG_MAX; s++) { | 678 | for (s = malloc_sizes; s->cs_size != ULONG_MAX; s++) { |
@@ -1666,6 +1667,8 @@ void __init kmem_cache_init_late(void) | |||
1666 | { | 1667 | { |
1667 | struct kmem_cache *cachep; | 1668 | struct kmem_cache *cachep; |
1668 | 1669 | ||
1670 | g_cpucache_up = LATE; | ||
1671 | |||
1669 | /* Annotate slab for lockdep -- annotate the malloc caches */ | 1672 | /* Annotate slab for lockdep -- annotate the malloc caches */ |
1670 | init_lock_keys(); | 1673 | init_lock_keys(); |
1671 | 1674 | ||
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 3231bf332878..1d8b32f07139 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c | |||
@@ -1633,6 +1633,8 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align, | |||
1633 | goto fail; | 1633 | goto fail; |
1634 | 1634 | ||
1635 | addr = __vmalloc_area_node(area, gfp_mask, prot, node, caller); | 1635 | addr = __vmalloc_area_node(area, gfp_mask, prot, node, caller); |
1636 | if (!addr) | ||
1637 | return NULL; | ||
1636 | 1638 | ||
1637 | /* | 1639 | /* |
1638 | * In this function, newly allocated vm_struct is not added | 1640 | * In this function, newly allocated vm_struct is not added |
diff --git a/mm/vmscan.c b/mm/vmscan.c index a1893c050795..f54a05b7a61d 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -183,7 +183,7 @@ static unsigned long zone_nr_lru_pages(struct zone *zone, | |||
183 | */ | 183 | */ |
184 | void register_shrinker(struct shrinker *shrinker) | 184 | void register_shrinker(struct shrinker *shrinker) |
185 | { | 185 | { |
186 | shrinker->nr = 0; | 186 | atomic_long_set(&shrinker->nr_in_batch, 0); |
187 | down_write(&shrinker_rwsem); | 187 | down_write(&shrinker_rwsem); |
188 | list_add_tail(&shrinker->list, &shrinker_list); | 188 | list_add_tail(&shrinker->list, &shrinker_list); |
189 | up_write(&shrinker_rwsem); | 189 | up_write(&shrinker_rwsem); |
@@ -247,25 +247,26 @@ unsigned long shrink_slab(struct shrink_control *shrink, | |||
247 | 247 | ||
248 | list_for_each_entry(shrinker, &shrinker_list, list) { | 248 | list_for_each_entry(shrinker, &shrinker_list, list) { |
249 | unsigned long long delta; | 249 | unsigned long long delta; |
250 | unsigned long total_scan; | 250 | long total_scan; |
251 | unsigned long max_pass; | 251 | long max_pass; |
252 | int shrink_ret = 0; | 252 | int shrink_ret = 0; |
253 | long nr; | 253 | long nr; |
254 | long new_nr; | 254 | long new_nr; |
255 | long batch_size = shrinker->batch ? shrinker->batch | 255 | long batch_size = shrinker->batch ? shrinker->batch |
256 | : SHRINK_BATCH; | 256 | : SHRINK_BATCH; |
257 | 257 | ||
258 | max_pass = do_shrinker_shrink(shrinker, shrink, 0); | ||
259 | if (max_pass <= 0) | ||
260 | continue; | ||
261 | |||
258 | /* | 262 | /* |
259 | * copy the current shrinker scan count into a local variable | 263 | * copy the current shrinker scan count into a local variable |
260 | * and zero it so that other concurrent shrinker invocations | 264 | * and zero it so that other concurrent shrinker invocations |
261 | * don't also do this scanning work. | 265 | * don't also do this scanning work. |
262 | */ | 266 | */ |
263 | do { | 267 | nr = atomic_long_xchg(&shrinker->nr_in_batch, 0); |
264 | nr = shrinker->nr; | ||
265 | } while (cmpxchg(&shrinker->nr, nr, 0) != nr); | ||
266 | 268 | ||
267 | total_scan = nr; | 269 | total_scan = nr; |
268 | max_pass = do_shrinker_shrink(shrinker, shrink, 0); | ||
269 | delta = (4 * nr_pages_scanned) / shrinker->seeks; | 270 | delta = (4 * nr_pages_scanned) / shrinker->seeks; |
270 | delta *= max_pass; | 271 | delta *= max_pass; |
271 | do_div(delta, lru_pages + 1); | 272 | do_div(delta, lru_pages + 1); |
@@ -325,12 +326,11 @@ unsigned long shrink_slab(struct shrink_control *shrink, | |||
325 | * manner that handles concurrent updates. If we exhausted the | 326 | * manner that handles concurrent updates. If we exhausted the |
326 | * scan, there is no need to do an update. | 327 | * scan, there is no need to do an update. |
327 | */ | 328 | */ |
328 | do { | 329 | if (total_scan > 0) |
329 | nr = shrinker->nr; | 330 | new_nr = atomic_long_add_return(total_scan, |
330 | new_nr = total_scan + nr; | 331 | &shrinker->nr_in_batch); |
331 | if (total_scan <= 0) | 332 | else |
332 | break; | 333 | new_nr = atomic_long_read(&shrinker->nr_in_batch); |
333 | } while (cmpxchg(&shrinker->nr, nr, new_nr) != nr); | ||
334 | 334 | ||
335 | trace_mm_shrink_slab_end(shrinker, shrink_ret, nr, new_nr); | 335 | trace_mm_shrink_slab_end(shrinker, shrink_ret, nr, new_nr); |
336 | } | 336 | } |
diff --git a/net/core/request_sock.c b/net/core/request_sock.c index 182236b2510a..9b570a6a33c5 100644 --- a/net/core/request_sock.c +++ b/net/core/request_sock.c | |||
@@ -26,10 +26,11 @@ | |||
26 | * but then some measure against one socket starving all other sockets | 26 | * but then some measure against one socket starving all other sockets |
27 | * would be needed. | 27 | * would be needed. |
28 | * | 28 | * |
29 | * It was 128 by default. Experiments with real servers show, that | 29 | * The minimum value of it is 128. Experiments with real servers show that |
30 | * it is absolutely not enough even at 100conn/sec. 256 cures most | 30 | * it is absolutely not enough even at 100conn/sec. 256 cures most |
31 | * of problems. This value is adjusted to 128 for very small machines | 31 | * of problems. |
32 | * (<=32Mb of memory) and to 1024 on normal or better ones (>=256Mb). | 32 | * This value is adjusted to 128 for low memory machines, |
33 | * and it will increase in proportion to the memory of machine. | ||
33 | * Note : Dont forget somaxconn that may limit backlog too. | 34 | * Note : Dont forget somaxconn that may limit backlog too. |
34 | */ | 35 | */ |
35 | int sysctl_max_syn_backlog = 256; | 36 | int sysctl_max_syn_backlog = 256; |
diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c index 025233de25f9..925991ae6f52 100644 --- a/net/core/secure_seq.c +++ b/net/core/secure_seq.c | |||
@@ -19,6 +19,7 @@ static int __init net_secret_init(void) | |||
19 | } | 19 | } |
20 | late_initcall(net_secret_init); | 20 | late_initcall(net_secret_init); |
21 | 21 | ||
22 | #ifdef CONFIG_INET | ||
22 | static u32 seq_scale(u32 seq) | 23 | static u32 seq_scale(u32 seq) |
23 | { | 24 | { |
24 | /* | 25 | /* |
@@ -33,6 +34,7 @@ static u32 seq_scale(u32 seq) | |||
33 | */ | 34 | */ |
34 | return seq + (ktime_to_ns(ktime_get_real()) >> 6); | 35 | return seq + (ktime_to_ns(ktime_get_real()) >> 6); |
35 | } | 36 | } |
37 | #endif | ||
36 | 38 | ||
37 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 39 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
38 | __u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr, | 40 | __u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr, |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index ca5e237df029..46af62363b8c 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -112,7 +112,7 @@ | |||
112 | #include <net/secure_seq.h> | 112 | #include <net/secure_seq.h> |
113 | 113 | ||
114 | #define RT_FL_TOS(oldflp4) \ | 114 | #define RT_FL_TOS(oldflp4) \ |
115 | ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) | 115 | ((oldflp4)->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK)) |
116 | 116 | ||
117 | #define IP_MAX_MTU 0xFFF0 | 117 | #define IP_MAX_MTU 0xFFF0 |
118 | 118 | ||
@@ -1310,7 +1310,7 @@ static void rt_del(unsigned hash, struct rtable *rt) | |||
1310 | spin_unlock_bh(rt_hash_lock_addr(hash)); | 1310 | spin_unlock_bh(rt_hash_lock_addr(hash)); |
1311 | } | 1311 | } |
1312 | 1312 | ||
1313 | static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) | 1313 | static void check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) |
1314 | { | 1314 | { |
1315 | struct rtable *rt = (struct rtable *) dst; | 1315 | struct rtable *rt = (struct rtable *) dst; |
1316 | __be32 orig_gw = rt->rt_gateway; | 1316 | __be32 orig_gw = rt->rt_gateway; |
@@ -1321,21 +1321,19 @@ static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) | |||
1321 | rt->rt_gateway = peer->redirect_learned.a4; | 1321 | rt->rt_gateway = peer->redirect_learned.a4; |
1322 | 1322 | ||
1323 | n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway); | 1323 | n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway); |
1324 | if (IS_ERR(n)) | 1324 | if (IS_ERR(n)) { |
1325 | return PTR_ERR(n); | 1325 | rt->rt_gateway = orig_gw; |
1326 | return; | ||
1327 | } | ||
1326 | old_n = xchg(&rt->dst._neighbour, n); | 1328 | old_n = xchg(&rt->dst._neighbour, n); |
1327 | if (old_n) | 1329 | if (old_n) |
1328 | neigh_release(old_n); | 1330 | neigh_release(old_n); |
1329 | if (!n || !(n->nud_state & NUD_VALID)) { | 1331 | if (!(n->nud_state & NUD_VALID)) { |
1330 | if (n) | 1332 | neigh_event_send(n, NULL); |
1331 | neigh_event_send(n, NULL); | ||
1332 | rt->rt_gateway = orig_gw; | ||
1333 | return -EAGAIN; | ||
1334 | } else { | 1333 | } else { |
1335 | rt->rt_flags |= RTCF_REDIRECTED; | 1334 | rt->rt_flags |= RTCF_REDIRECTED; |
1336 | call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); | 1335 | call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); |
1337 | } | 1336 | } |
1338 | return 0; | ||
1339 | } | 1337 | } |
1340 | 1338 | ||
1341 | /* called in rcu_read_lock() section */ | 1339 | /* called in rcu_read_lock() section */ |
@@ -1693,7 +1691,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
1693 | } | 1691 | } |
1694 | 1692 | ||
1695 | 1693 | ||
1696 | static struct rtable *ipv4_validate_peer(struct rtable *rt) | 1694 | static void ipv4_validate_peer(struct rtable *rt) |
1697 | { | 1695 | { |
1698 | if (rt->rt_peer_genid != rt_peer_genid()) { | 1696 | if (rt->rt_peer_genid != rt_peer_genid()) { |
1699 | struct inet_peer *peer; | 1697 | struct inet_peer *peer; |
@@ -1708,15 +1706,12 @@ static struct rtable *ipv4_validate_peer(struct rtable *rt) | |||
1708 | if (peer->redirect_genid != redirect_genid) | 1706 | if (peer->redirect_genid != redirect_genid) |
1709 | peer->redirect_learned.a4 = 0; | 1707 | peer->redirect_learned.a4 = 0; |
1710 | if (peer->redirect_learned.a4 && | 1708 | if (peer->redirect_learned.a4 && |
1711 | peer->redirect_learned.a4 != rt->rt_gateway) { | 1709 | peer->redirect_learned.a4 != rt->rt_gateway) |
1712 | if (check_peer_redir(&rt->dst, peer)) | 1710 | check_peer_redir(&rt->dst, peer); |
1713 | return NULL; | ||
1714 | } | ||
1715 | } | 1711 | } |
1716 | 1712 | ||
1717 | rt->rt_peer_genid = rt_peer_genid(); | 1713 | rt->rt_peer_genid = rt_peer_genid(); |
1718 | } | 1714 | } |
1719 | return rt; | ||
1720 | } | 1715 | } |
1721 | 1716 | ||
1722 | static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) | 1717 | static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) |
@@ -1725,7 +1720,7 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) | |||
1725 | 1720 | ||
1726 | if (rt_is_expired(rt)) | 1721 | if (rt_is_expired(rt)) |
1727 | return NULL; | 1722 | return NULL; |
1728 | dst = (struct dst_entry *) ipv4_validate_peer(rt); | 1723 | ipv4_validate_peer(rt); |
1729 | return dst; | 1724 | return dst; |
1730 | } | 1725 | } |
1731 | 1726 | ||
@@ -2380,9 +2375,7 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
2380 | rth->rt_mark == skb->mark && | 2375 | rth->rt_mark == skb->mark && |
2381 | net_eq(dev_net(rth->dst.dev), net) && | 2376 | net_eq(dev_net(rth->dst.dev), net) && |
2382 | !rt_is_expired(rth)) { | 2377 | !rt_is_expired(rth)) { |
2383 | rth = ipv4_validate_peer(rth); | 2378 | ipv4_validate_peer(rth); |
2384 | if (!rth) | ||
2385 | continue; | ||
2386 | if (noref) { | 2379 | if (noref) { |
2387 | dst_use_noref(&rth->dst, jiffies); | 2380 | dst_use_noref(&rth->dst, jiffies); |
2388 | skb_dst_set_noref(skb, &rth->dst); | 2381 | skb_dst_set_noref(skb, &rth->dst); |
@@ -2441,11 +2434,11 @@ EXPORT_SYMBOL(ip_route_input_common); | |||
2441 | static struct rtable *__mkroute_output(const struct fib_result *res, | 2434 | static struct rtable *__mkroute_output(const struct fib_result *res, |
2442 | const struct flowi4 *fl4, | 2435 | const struct flowi4 *fl4, |
2443 | __be32 orig_daddr, __be32 orig_saddr, | 2436 | __be32 orig_daddr, __be32 orig_saddr, |
2444 | int orig_oif, struct net_device *dev_out, | 2437 | int orig_oif, __u8 orig_rtos, |
2438 | struct net_device *dev_out, | ||
2445 | unsigned int flags) | 2439 | unsigned int flags) |
2446 | { | 2440 | { |
2447 | struct fib_info *fi = res->fi; | 2441 | struct fib_info *fi = res->fi; |
2448 | u32 tos = RT_FL_TOS(fl4); | ||
2449 | struct in_device *in_dev; | 2442 | struct in_device *in_dev; |
2450 | u16 type = res->type; | 2443 | u16 type = res->type; |
2451 | struct rtable *rth; | 2444 | struct rtable *rth; |
@@ -2496,7 +2489,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
2496 | rth->rt_genid = rt_genid(dev_net(dev_out)); | 2489 | rth->rt_genid = rt_genid(dev_net(dev_out)); |
2497 | rth->rt_flags = flags; | 2490 | rth->rt_flags = flags; |
2498 | rth->rt_type = type; | 2491 | rth->rt_type = type; |
2499 | rth->rt_key_tos = tos; | 2492 | rth->rt_key_tos = orig_rtos; |
2500 | rth->rt_dst = fl4->daddr; | 2493 | rth->rt_dst = fl4->daddr; |
2501 | rth->rt_src = fl4->saddr; | 2494 | rth->rt_src = fl4->saddr; |
2502 | rth->rt_route_iif = 0; | 2495 | rth->rt_route_iif = 0; |
@@ -2546,7 +2539,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
2546 | static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4) | 2539 | static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4) |
2547 | { | 2540 | { |
2548 | struct net_device *dev_out = NULL; | 2541 | struct net_device *dev_out = NULL; |
2549 | u32 tos = RT_FL_TOS(fl4); | 2542 | __u8 tos = RT_FL_TOS(fl4); |
2550 | unsigned int flags = 0; | 2543 | unsigned int flags = 0; |
2551 | struct fib_result res; | 2544 | struct fib_result res; |
2552 | struct rtable *rth; | 2545 | struct rtable *rth; |
@@ -2722,7 +2715,7 @@ static struct rtable *ip_route_output_slow(struct net *net, struct flowi4 *fl4) | |||
2722 | 2715 | ||
2723 | make_route: | 2716 | make_route: |
2724 | rth = __mkroute_output(&res, fl4, orig_daddr, orig_saddr, orig_oif, | 2717 | rth = __mkroute_output(&res, fl4, orig_daddr, orig_saddr, orig_oif, |
2725 | dev_out, flags); | 2718 | tos, dev_out, flags); |
2726 | if (!IS_ERR(rth)) { | 2719 | if (!IS_ERR(rth)) { |
2727 | unsigned int hash; | 2720 | unsigned int hash; |
2728 | 2721 | ||
@@ -2758,9 +2751,7 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *flp4) | |||
2758 | (IPTOS_RT_MASK | RTO_ONLINK)) && | 2751 | (IPTOS_RT_MASK | RTO_ONLINK)) && |
2759 | net_eq(dev_net(rth->dst.dev), net) && | 2752 | net_eq(dev_net(rth->dst.dev), net) && |
2760 | !rt_is_expired(rth)) { | 2753 | !rt_is_expired(rth)) { |
2761 | rth = ipv4_validate_peer(rth); | 2754 | ipv4_validate_peer(rth); |
2762 | if (!rth) | ||
2763 | continue; | ||
2764 | dst_use(&rth->dst, jiffies); | 2755 | dst_use(&rth->dst, jiffies); |
2765 | RT_CACHE_STAT_INC(out_hit); | 2756 | RT_CACHE_STAT_INC(out_hit); |
2766 | rcu_read_unlock_bh(); | 2757 | rcu_read_unlock_bh(); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index d999bf3b84e1..cae443563ec9 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -757,6 +757,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
757 | if (!local->int_scan_req) | 757 | if (!local->int_scan_req) |
758 | return -ENOMEM; | 758 | return -ENOMEM; |
759 | 759 | ||
760 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
761 | if (!local->hw.wiphy->bands[band]) | ||
762 | continue; | ||
763 | local->int_scan_req->rates[band] = (u32) -1; | ||
764 | } | ||
765 | |||
760 | /* if low-level driver supports AP, we also support VLAN */ | 766 | /* if low-level driver supports AP, we also support VLAN */ |
761 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { | 767 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { |
762 | hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); | 768 | hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index eca0fad09709..d5230ecc784d 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1039,7 +1039,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1039 | struct ieee80211_sub_if_data, | 1039 | struct ieee80211_sub_if_data, |
1040 | u.ap); | 1040 | u.ap); |
1041 | 1041 | ||
1042 | memset(&sta->sta.drv_priv, 0, hw->sta_data_size); | ||
1043 | WARN_ON(drv_sta_add(local, sdata, &sta->sta)); | 1042 | WARN_ON(drv_sta_add(local, sdata, &sta->sta)); |
1044 | } | 1043 | } |
1045 | } | 1044 | } |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 77e926738014..3302c56f60d1 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -57,8 +57,17 @@ | |||
57 | #define REG_DBG_PRINT(args...) | 57 | #define REG_DBG_PRINT(args...) |
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | static struct regulatory_request core_request_world = { | ||
61 | .initiator = NL80211_REGDOM_SET_BY_CORE, | ||
62 | .alpha2[0] = '0', | ||
63 | .alpha2[1] = '0', | ||
64 | .intersect = false, | ||
65 | .processed = true, | ||
66 | .country_ie_env = ENVIRON_ANY, | ||
67 | }; | ||
68 | |||
60 | /* Receipt of information from last regulatory request */ | 69 | /* Receipt of information from last regulatory request */ |
61 | static struct regulatory_request *last_request; | 70 | static struct regulatory_request *last_request = &core_request_world; |
62 | 71 | ||
63 | /* To trigger userspace events */ | 72 | /* To trigger userspace events */ |
64 | static struct platform_device *reg_pdev; | 73 | static struct platform_device *reg_pdev; |
@@ -150,7 +159,7 @@ static char user_alpha2[2]; | |||
150 | module_param(ieee80211_regdom, charp, 0444); | 159 | module_param(ieee80211_regdom, charp, 0444); |
151 | MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); | 160 | MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); |
152 | 161 | ||
153 | static void reset_regdomains(void) | 162 | static void reset_regdomains(bool full_reset) |
154 | { | 163 | { |
155 | /* avoid freeing static information or freeing something twice */ | 164 | /* avoid freeing static information or freeing something twice */ |
156 | if (cfg80211_regdomain == cfg80211_world_regdom) | 165 | if (cfg80211_regdomain == cfg80211_world_regdom) |
@@ -165,6 +174,13 @@ static void reset_regdomains(void) | |||
165 | 174 | ||
166 | cfg80211_world_regdom = &world_regdom; | 175 | cfg80211_world_regdom = &world_regdom; |
167 | cfg80211_regdomain = NULL; | 176 | cfg80211_regdomain = NULL; |
177 | |||
178 | if (!full_reset) | ||
179 | return; | ||
180 | |||
181 | if (last_request != &core_request_world) | ||
182 | kfree(last_request); | ||
183 | last_request = &core_request_world; | ||
168 | } | 184 | } |
169 | 185 | ||
170 | /* | 186 | /* |
@@ -175,7 +191,7 @@ static void update_world_regdomain(const struct ieee80211_regdomain *rd) | |||
175 | { | 191 | { |
176 | BUG_ON(!last_request); | 192 | BUG_ON(!last_request); |
177 | 193 | ||
178 | reset_regdomains(); | 194 | reset_regdomains(false); |
179 | 195 | ||
180 | cfg80211_world_regdom = rd; | 196 | cfg80211_world_regdom = rd; |
181 | cfg80211_regdomain = rd; | 197 | cfg80211_regdomain = rd; |
@@ -1407,7 +1423,8 @@ static int __regulatory_hint(struct wiphy *wiphy, | |||
1407 | } | 1423 | } |
1408 | 1424 | ||
1409 | new_request: | 1425 | new_request: |
1410 | kfree(last_request); | 1426 | if (last_request != &core_request_world) |
1427 | kfree(last_request); | ||
1411 | 1428 | ||
1412 | last_request = pending_request; | 1429 | last_request = pending_request; |
1413 | last_request->intersect = intersect; | 1430 | last_request->intersect = intersect; |
@@ -1577,9 +1594,6 @@ static int regulatory_hint_core(const char *alpha2) | |||
1577 | { | 1594 | { |
1578 | struct regulatory_request *request; | 1595 | struct regulatory_request *request; |
1579 | 1596 | ||
1580 | kfree(last_request); | ||
1581 | last_request = NULL; | ||
1582 | |||
1583 | request = kzalloc(sizeof(struct regulatory_request), | 1597 | request = kzalloc(sizeof(struct regulatory_request), |
1584 | GFP_KERNEL); | 1598 | GFP_KERNEL); |
1585 | if (!request) | 1599 | if (!request) |
@@ -1777,7 +1791,7 @@ static void restore_regulatory_settings(bool reset_user) | |||
1777 | mutex_lock(&cfg80211_mutex); | 1791 | mutex_lock(&cfg80211_mutex); |
1778 | mutex_lock(®_mutex); | 1792 | mutex_lock(®_mutex); |
1779 | 1793 | ||
1780 | reset_regdomains(); | 1794 | reset_regdomains(true); |
1781 | restore_alpha2(alpha2, reset_user); | 1795 | restore_alpha2(alpha2, reset_user); |
1782 | 1796 | ||
1783 | /* | 1797 | /* |
@@ -2037,8 +2051,10 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2037 | } | 2051 | } |
2038 | 2052 | ||
2039 | request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); | 2053 | request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); |
2040 | if (!request_wiphy) { | 2054 | if (!request_wiphy && |
2041 | reg_set_request_processed(); | 2055 | (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER || |
2056 | last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)) { | ||
2057 | schedule_delayed_work(®_timeout, 0); | ||
2042 | return -ENODEV; | 2058 | return -ENODEV; |
2043 | } | 2059 | } |
2044 | 2060 | ||
@@ -2046,7 +2062,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2046 | int r; | 2062 | int r; |
2047 | 2063 | ||
2048 | if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) { | 2064 | if (last_request->initiator != NL80211_REGDOM_SET_BY_DRIVER) { |
2049 | reset_regdomains(); | 2065 | reset_regdomains(false); |
2050 | cfg80211_regdomain = rd; | 2066 | cfg80211_regdomain = rd; |
2051 | return 0; | 2067 | return 0; |
2052 | } | 2068 | } |
@@ -2067,7 +2083,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2067 | if (r) | 2083 | if (r) |
2068 | return r; | 2084 | return r; |
2069 | 2085 | ||
2070 | reset_regdomains(); | 2086 | reset_regdomains(false); |
2071 | cfg80211_regdomain = rd; | 2087 | cfg80211_regdomain = rd; |
2072 | return 0; | 2088 | return 0; |
2073 | } | 2089 | } |
@@ -2092,7 +2108,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2092 | 2108 | ||
2093 | rd = NULL; | 2109 | rd = NULL; |
2094 | 2110 | ||
2095 | reset_regdomains(); | 2111 | reset_regdomains(false); |
2096 | cfg80211_regdomain = intersected_rd; | 2112 | cfg80211_regdomain = intersected_rd; |
2097 | 2113 | ||
2098 | return 0; | 2114 | return 0; |
@@ -2112,7 +2128,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2112 | kfree(rd); | 2128 | kfree(rd); |
2113 | rd = NULL; | 2129 | rd = NULL; |
2114 | 2130 | ||
2115 | reset_regdomains(); | 2131 | reset_regdomains(false); |
2116 | cfg80211_regdomain = intersected_rd; | 2132 | cfg80211_regdomain = intersected_rd; |
2117 | 2133 | ||
2118 | return 0; | 2134 | return 0; |
@@ -2265,11 +2281,8 @@ void /* __init_or_exit */ regulatory_exit(void) | |||
2265 | mutex_lock(&cfg80211_mutex); | 2281 | mutex_lock(&cfg80211_mutex); |
2266 | mutex_lock(®_mutex); | 2282 | mutex_lock(®_mutex); |
2267 | 2283 | ||
2268 | reset_regdomains(); | 2284 | reset_regdomains(true); |
2269 | |||
2270 | kfree(last_request); | ||
2271 | 2285 | ||
2272 | last_request = NULL; | ||
2273 | dev_set_uevent_suppress(®_pdev->dev, true); | 2286 | dev_set_uevent_suppress(®_pdev->dev, true); |
2274 | 2287 | ||
2275 | platform_device_unregister(reg_pdev); | 2288 | platform_device_unregister(reg_pdev); |
diff --git a/security/apparmor/path.c b/security/apparmor/path.c index 36cc0cc39e78..b566eba4a65c 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c | |||
@@ -57,23 +57,44 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen) | |||
57 | static int d_namespace_path(struct path *path, char *buf, int buflen, | 57 | static int d_namespace_path(struct path *path, char *buf, int buflen, |
58 | char **name, int flags) | 58 | char **name, int flags) |
59 | { | 59 | { |
60 | struct path root, tmp; | ||
61 | char *res; | 60 | char *res; |
62 | int connected, error = 0; | 61 | int error = 0; |
62 | int connected = 1; | ||
63 | |||
64 | if (path->mnt->mnt_flags & MNT_INTERNAL) { | ||
65 | /* it's not mounted anywhere */ | ||
66 | res = dentry_path(path->dentry, buf, buflen); | ||
67 | *name = res; | ||
68 | if (IS_ERR(res)) { | ||
69 | *name = buf; | ||
70 | return PTR_ERR(res); | ||
71 | } | ||
72 | if (path->dentry->d_sb->s_magic == PROC_SUPER_MAGIC && | ||
73 | strncmp(*name, "/sys/", 5) == 0) { | ||
74 | /* TODO: convert over to using a per namespace | ||
75 | * control instead of hard coded /proc | ||
76 | */ | ||
77 | return prepend(name, *name - buf, "/proc", 5); | ||
78 | } | ||
79 | return 0; | ||
80 | } | ||
63 | 81 | ||
64 | /* Get the root we want to resolve too, released below */ | 82 | /* resolve paths relative to chroot?*/ |
65 | if (flags & PATH_CHROOT_REL) { | 83 | if (flags & PATH_CHROOT_REL) { |
66 | /* resolve paths relative to chroot */ | 84 | struct path root; |
67 | get_fs_root(current->fs, &root); | 85 | get_fs_root(current->fs, &root); |
68 | } else { | 86 | res = __d_path(path, &root, buf, buflen); |
69 | /* resolve paths relative to namespace */ | 87 | if (res && !IS_ERR(res)) { |
70 | root.mnt = current->nsproxy->mnt_ns->root; | 88 | /* everything's fine */ |
71 | root.dentry = root.mnt->mnt_root; | 89 | *name = res; |
72 | path_get(&root); | 90 | path_put(&root); |
91 | goto ok; | ||
92 | } | ||
93 | path_put(&root); | ||
94 | connected = 0; | ||
73 | } | 95 | } |
74 | 96 | ||
75 | tmp = root; | 97 | res = d_absolute_path(path, buf, buflen); |
76 | res = __d_path(path, &tmp, buf, buflen); | ||
77 | 98 | ||
78 | *name = res; | 99 | *name = res; |
79 | /* handle error conditions - and still allow a partial path to | 100 | /* handle error conditions - and still allow a partial path to |
@@ -84,7 +105,10 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, | |||
84 | *name = buf; | 105 | *name = buf; |
85 | goto out; | 106 | goto out; |
86 | } | 107 | } |
108 | if (!our_mnt(path->mnt)) | ||
109 | connected = 0; | ||
87 | 110 | ||
111 | ok: | ||
88 | /* Handle two cases: | 112 | /* Handle two cases: |
89 | * 1. A deleted dentry && profile is not allowing mediation of deleted | 113 | * 1. A deleted dentry && profile is not allowing mediation of deleted |
90 | * 2. On some filesystems, newly allocated dentries appear to the | 114 | * 2. On some filesystems, newly allocated dentries appear to the |
@@ -97,10 +121,7 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, | |||
97 | goto out; | 121 | goto out; |
98 | } | 122 | } |
99 | 123 | ||
100 | /* Determine if the path is connected to the expected root */ | 124 | /* If the path is not connected to the expected root, |
101 | connected = tmp.dentry == root.dentry && tmp.mnt == root.mnt; | ||
102 | |||
103 | /* If the path is not connected, | ||
104 | * check if it is a sysctl and handle specially else remove any | 125 | * check if it is a sysctl and handle specially else remove any |
105 | * leading / that __d_path may have returned. | 126 | * leading / that __d_path may have returned. |
106 | * Unless | 127 | * Unless |
@@ -112,17 +133,9 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, | |||
112 | * namespace root. | 133 | * namespace root. |
113 | */ | 134 | */ |
114 | if (!connected) { | 135 | if (!connected) { |
115 | /* is the disconnect path a sysctl? */ | 136 | if (!(flags & PATH_CONNECT_PATH) && |
116 | if (tmp.dentry->d_sb->s_magic == PROC_SUPER_MAGIC && | ||
117 | strncmp(*name, "/sys/", 5) == 0) { | ||
118 | /* TODO: convert over to using a per namespace | ||
119 | * control instead of hard coded /proc | ||
120 | */ | ||
121 | error = prepend(name, *name - buf, "/proc", 5); | ||
122 | } else if (!(flags & PATH_CONNECT_PATH) && | ||
123 | !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) && | 137 | !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) && |
124 | (tmp.mnt == current->nsproxy->mnt_ns->root && | 138 | our_mnt(path->mnt))) { |
125 | tmp.dentry == tmp.mnt->mnt_root))) { | ||
126 | /* disconnected path, don't return pathname starting | 139 | /* disconnected path, don't return pathname starting |
127 | * with '/' | 140 | * with '/' |
128 | */ | 141 | */ |
@@ -133,8 +146,6 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, | |||
133 | } | 146 | } |
134 | 147 | ||
135 | out: | 148 | out: |
136 | path_put(&root); | ||
137 | |||
138 | return error; | 149 | return error; |
139 | } | 150 | } |
140 | 151 | ||
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c index 738bbdf8d4c7..d9f3ced8756e 100644 --- a/security/tomoyo/realpath.c +++ b/security/tomoyo/realpath.c | |||
@@ -101,9 +101,8 @@ static char *tomoyo_get_absolute_path(struct path *path, char * const buffer, | |||
101 | { | 101 | { |
102 | char *pos = ERR_PTR(-ENOMEM); | 102 | char *pos = ERR_PTR(-ENOMEM); |
103 | if (buflen >= 256) { | 103 | if (buflen >= 256) { |
104 | struct path ns_root = { }; | ||
105 | /* go to whatever namespace root we are under */ | 104 | /* go to whatever namespace root we are under */ |
106 | pos = __d_path(path, &ns_root, buffer, buflen - 1); | 105 | pos = d_absolute_path(path, buffer, buflen - 1); |
107 | if (!IS_ERR(pos) && *pos == '/' && pos[1]) { | 106 | if (!IS_ERR(pos) && *pos == '/' && pos[1]) { |
108 | struct inode *inode = path->dentry->d_inode; | 107 | struct inode *inode = path->dentry->d_inode; |
109 | if (inode && S_ISDIR(inode->i_mode)) { | 108 | if (inode && S_ISDIR(inode->i_mode)) { |
@@ -294,8 +293,16 @@ char *tomoyo_realpath_from_path(struct path *path) | |||
294 | pos = tomoyo_get_local_path(path->dentry, buf, | 293 | pos = tomoyo_get_local_path(path->dentry, buf, |
295 | buf_len - 1); | 294 | buf_len - 1); |
296 | /* Get absolute name for the rest. */ | 295 | /* Get absolute name for the rest. */ |
297 | else | 296 | else { |
298 | pos = tomoyo_get_absolute_path(path, buf, buf_len - 1); | 297 | pos = tomoyo_get_absolute_path(path, buf, buf_len - 1); |
298 | /* | ||
299 | * Fall back to local name if absolute name is not | ||
300 | * available. | ||
301 | */ | ||
302 | if (pos == ERR_PTR(-EINVAL)) | ||
303 | pos = tomoyo_get_local_path(path->dentry, buf, | ||
304 | buf_len - 1); | ||
305 | } | ||
299 | encode: | 306 | encode: |
300 | if (IS_ERR(pos)) | 307 | if (IS_ERR(pos)) |
301 | continue; | 308 | continue; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cbde019d3d52..1d07e8fa2433 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -297,6 +297,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
297 | imux = &spec->input_mux[mux_idx]; | 297 | imux = &spec->input_mux[mux_idx]; |
298 | if (!imux->num_items && mux_idx > 0) | 298 | if (!imux->num_items && mux_idx > 0) |
299 | imux = &spec->input_mux[0]; | 299 | imux = &spec->input_mux[0]; |
300 | if (!imux->num_items) | ||
301 | return 0; | ||
300 | 302 | ||
301 | if (idx >= imux->num_items) | 303 | if (idx >= imux->num_items) |
302 | idx = imux->num_items - 1; | 304 | idx = imux->num_items - 1; |
@@ -2629,6 +2631,8 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, | |||
2629 | case AUTO_PIN_SPEAKER_OUT: | 2631 | case AUTO_PIN_SPEAKER_OUT: |
2630 | if (cfg->line_outs == 1) | 2632 | if (cfg->line_outs == 1) |
2631 | return "Speaker"; | 2633 | return "Speaker"; |
2634 | if (cfg->line_outs == 2) | ||
2635 | return ch ? "Bass Speaker" : "Speaker"; | ||
2632 | break; | 2636 | break; |
2633 | case AUTO_PIN_HP_OUT: | 2637 | case AUTO_PIN_HP_OUT: |
2634 | /* for multi-io case, only the primary out */ | 2638 | /* for multi-io case, only the primary out */ |
@@ -2902,7 +2906,7 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) | |||
2902 | if (!nid) | 2906 | if (!nid) |
2903 | continue; | 2907 | continue; |
2904 | if (found_in_nid_list(nid, spec->multiout.dac_nids, | 2908 | if (found_in_nid_list(nid, spec->multiout.dac_nids, |
2905 | spec->multiout.num_dacs)) | 2909 | ARRAY_SIZE(spec->private_dac_nids))) |
2906 | continue; | 2910 | continue; |
2907 | if (found_in_nid_list(nid, spec->multiout.hp_out_nid, | 2911 | if (found_in_nid_list(nid, spec->multiout.hp_out_nid, |
2908 | ARRAY_SIZE(spec->multiout.hp_out_nid))) | 2912 | ARRAY_SIZE(spec->multiout.hp_out_nid))) |
@@ -2923,6 +2927,7 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) | |||
2923 | return 0; | 2927 | return 0; |
2924 | } | 2928 | } |
2925 | 2929 | ||
2930 | /* return 0 if no possible DAC is found, 1 if one or more found */ | ||
2926 | static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, | 2931 | static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, |
2927 | const hda_nid_t *pins, hda_nid_t *dacs) | 2932 | const hda_nid_t *pins, hda_nid_t *dacs) |
2928 | { | 2933 | { |
@@ -2940,7 +2945,7 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, | |||
2940 | if (!dacs[i]) | 2945 | if (!dacs[i]) |
2941 | dacs[i] = alc_auto_look_for_dac(codec, pins[i]); | 2946 | dacs[i] = alc_auto_look_for_dac(codec, pins[i]); |
2942 | } | 2947 | } |
2943 | return 0; | 2948 | return 1; |
2944 | } | 2949 | } |
2945 | 2950 | ||
2946 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, | 2951 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, |
@@ -2950,7 +2955,7 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec, | |||
2950 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) | 2955 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) |
2951 | { | 2956 | { |
2952 | struct alc_spec *spec = codec->spec; | 2957 | struct alc_spec *spec = codec->spec; |
2953 | const struct auto_pin_cfg *cfg = &spec->autocfg; | 2958 | struct auto_pin_cfg *cfg = &spec->autocfg; |
2954 | bool redone = false; | 2959 | bool redone = false; |
2955 | int i; | 2960 | int i; |
2956 | 2961 | ||
@@ -2961,6 +2966,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
2961 | spec->multiout.extra_out_nid[0] = 0; | 2966 | spec->multiout.extra_out_nid[0] = 0; |
2962 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); | 2967 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); |
2963 | spec->multiout.dac_nids = spec->private_dac_nids; | 2968 | spec->multiout.dac_nids = spec->private_dac_nids; |
2969 | spec->multi_ios = 0; | ||
2964 | 2970 | ||
2965 | /* fill hard-wired DACs first */ | 2971 | /* fill hard-wired DACs first */ |
2966 | if (!redone) { | 2972 | if (!redone) { |
@@ -2994,10 +3000,12 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
2994 | for (i = 0; i < cfg->line_outs; i++) { | 3000 | for (i = 0; i < cfg->line_outs; i++) { |
2995 | if (spec->private_dac_nids[i]) | 3001 | if (spec->private_dac_nids[i]) |
2996 | spec->multiout.num_dacs++; | 3002 | spec->multiout.num_dacs++; |
2997 | else | 3003 | else { |
2998 | memmove(spec->private_dac_nids + i, | 3004 | memmove(spec->private_dac_nids + i, |
2999 | spec->private_dac_nids + i + 1, | 3005 | spec->private_dac_nids + i + 1, |
3000 | sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); | 3006 | sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); |
3007 | spec->private_dac_nids[cfg->line_outs - 1] = 0; | ||
3008 | } | ||
3001 | } | 3009 | } |
3002 | 3010 | ||
3003 | if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | 3011 | if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
@@ -3019,9 +3027,28 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
3019 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) | 3027 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) |
3020 | alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, | 3028 | alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, |
3021 | spec->multiout.hp_out_nid); | 3029 | spec->multiout.hp_out_nid); |
3022 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) | 3030 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
3023 | alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins, | 3031 | int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, |
3024 | spec->multiout.extra_out_nid); | 3032 | cfg->speaker_pins, |
3033 | spec->multiout.extra_out_nid); | ||
3034 | /* if no speaker volume is assigned, try again as the primary | ||
3035 | * output | ||
3036 | */ | ||
3037 | if (!err && cfg->speaker_outs > 0 && | ||
3038 | cfg->line_out_type == AUTO_PIN_HP_OUT) { | ||
3039 | cfg->hp_outs = cfg->line_outs; | ||
3040 | memcpy(cfg->hp_pins, cfg->line_out_pins, | ||
3041 | sizeof(cfg->hp_pins)); | ||
3042 | cfg->line_outs = cfg->speaker_outs; | ||
3043 | memcpy(cfg->line_out_pins, cfg->speaker_pins, | ||
3044 | sizeof(cfg->speaker_pins)); | ||
3045 | cfg->speaker_outs = 0; | ||
3046 | memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); | ||
3047 | cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; | ||
3048 | redone = false; | ||
3049 | goto again; | ||
3050 | } | ||
3051 | } | ||
3025 | 3052 | ||
3026 | return 0; | 3053 | return 0; |
3027 | } | 3054 | } |
@@ -3171,7 +3198,8 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3171 | } | 3198 | } |
3172 | 3199 | ||
3173 | static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | 3200 | static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, |
3174 | hda_nid_t dac, const char *pfx) | 3201 | hda_nid_t dac, const char *pfx, |
3202 | int cidx) | ||
3175 | { | 3203 | { |
3176 | struct alc_spec *spec = codec->spec; | 3204 | struct alc_spec *spec = codec->spec; |
3177 | hda_nid_t sw, vol; | 3205 | hda_nid_t sw, vol; |
@@ -3187,15 +3215,15 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | |||
3187 | if (is_ctl_used(spec->sw_ctls, val)) | 3215 | if (is_ctl_used(spec->sw_ctls, val)) |
3188 | return 0; /* already created */ | 3216 | return 0; /* already created */ |
3189 | mark_ctl_usage(spec->sw_ctls, val); | 3217 | mark_ctl_usage(spec->sw_ctls, val); |
3190 | return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); | 3218 | return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val); |
3191 | } | 3219 | } |
3192 | 3220 | ||
3193 | sw = alc_look_for_out_mute_nid(codec, pin, dac); | 3221 | sw = alc_look_for_out_mute_nid(codec, pin, dac); |
3194 | vol = alc_look_for_out_vol_nid(codec, pin, dac); | 3222 | vol = alc_look_for_out_vol_nid(codec, pin, dac); |
3195 | err = alc_auto_add_stereo_vol(codec, pfx, 0, vol); | 3223 | err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol); |
3196 | if (err < 0) | 3224 | if (err < 0) |
3197 | return err; | 3225 | return err; |
3198 | err = alc_auto_add_stereo_sw(codec, pfx, 0, sw); | 3226 | err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw); |
3199 | if (err < 0) | 3227 | if (err < 0) |
3200 | return err; | 3228 | return err; |
3201 | return 0; | 3229 | return 0; |
@@ -3236,16 +3264,21 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins, | |||
3236 | hda_nid_t dac = *dacs; | 3264 | hda_nid_t dac = *dacs; |
3237 | if (!dac) | 3265 | if (!dac) |
3238 | dac = spec->multiout.dac_nids[0]; | 3266 | dac = spec->multiout.dac_nids[0]; |
3239 | return alc_auto_create_extra_out(codec, *pins, dac, pfx); | 3267 | return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); |
3240 | } | 3268 | } |
3241 | 3269 | ||
3242 | if (dacs[num_pins - 1]) { | 3270 | if (dacs[num_pins - 1]) { |
3243 | /* OK, we have a multi-output system with individual volumes */ | 3271 | /* OK, we have a multi-output system with individual volumes */ |
3244 | for (i = 0; i < num_pins; i++) { | 3272 | for (i = 0; i < num_pins; i++) { |
3245 | snprintf(name, sizeof(name), "%s %s", | 3273 | if (num_pins >= 3) { |
3246 | pfx, channel_name[i]); | 3274 | snprintf(name, sizeof(name), "%s %s", |
3247 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], | 3275 | pfx, channel_name[i]); |
3248 | name); | 3276 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], |
3277 | name, 0); | ||
3278 | } else { | ||
3279 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], | ||
3280 | pfx, i); | ||
3281 | } | ||
3249 | if (err < 0) | 3282 | if (err < 0) |
3250 | return err; | 3283 | return err; |
3251 | } | 3284 | } |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index d8d2f9dccd9b..eeb25d529e30 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -215,6 +215,7 @@ struct sigmatel_spec { | |||
215 | unsigned int gpio_mute; | 215 | unsigned int gpio_mute; |
216 | unsigned int gpio_led; | 216 | unsigned int gpio_led; |
217 | unsigned int gpio_led_polarity; | 217 | unsigned int gpio_led_polarity; |
218 | unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */ | ||
218 | unsigned int vref_led; | 219 | unsigned int vref_led; |
219 | 220 | ||
220 | /* stream */ | 221 | /* stream */ |
@@ -4318,12 +4319,10 @@ static void stac_store_hints(struct hda_codec *codec) | |||
4318 | spec->eapd_switch = val; | 4319 | spec->eapd_switch = val; |
4319 | get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); | 4320 | get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); |
4320 | if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { | 4321 | if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { |
4321 | if (spec->gpio_led <= 8) { | 4322 | spec->gpio_mask |= spec->gpio_led; |
4322 | spec->gpio_mask |= spec->gpio_led; | 4323 | spec->gpio_dir |= spec->gpio_led; |
4323 | spec->gpio_dir |= spec->gpio_led; | 4324 | if (spec->gpio_led_polarity) |
4324 | if (spec->gpio_led_polarity) | 4325 | spec->gpio_data |= spec->gpio_led; |
4325 | spec->gpio_data |= spec->gpio_led; | ||
4326 | } | ||
4327 | } | 4326 | } |
4328 | } | 4327 | } |
4329 | 4328 | ||
@@ -4443,7 +4442,7 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4443 | /* power on when no jack detection is available */ | 4442 | /* power on when no jack detection is available */ |
4444 | /* or when the VREF is used for controlling LED */ | 4443 | /* or when the VREF is used for controlling LED */ |
4445 | if (!spec->hp_detect || | 4444 | if (!spec->hp_detect || |
4446 | (spec->gpio_led > 8 && spec->gpio_led == nid)) { | 4445 | spec->vref_mute_led_nid == nid) { |
4447 | stac_toggle_power_map(codec, nid, 1); | 4446 | stac_toggle_power_map(codec, nid, 1); |
4448 | continue; | 4447 | continue; |
4449 | } | 4448 | } |
@@ -4915,8 +4914,14 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity) | |||
4915 | if (sscanf(dev->name, "HP_Mute_LED_%d_%x", | 4914 | if (sscanf(dev->name, "HP_Mute_LED_%d_%x", |
4916 | &spec->gpio_led_polarity, | 4915 | &spec->gpio_led_polarity, |
4917 | &spec->gpio_led) == 2) { | 4916 | &spec->gpio_led) == 2) { |
4918 | if (spec->gpio_led < 4) | 4917 | unsigned int max_gpio; |
4918 | max_gpio = snd_hda_param_read(codec, codec->afg, | ||
4919 | AC_PAR_GPIO_CAP); | ||
4920 | max_gpio &= AC_GPIO_IO_COUNT; | ||
4921 | if (spec->gpio_led < max_gpio) | ||
4919 | spec->gpio_led = 1 << spec->gpio_led; | 4922 | spec->gpio_led = 1 << spec->gpio_led; |
4923 | else | ||
4924 | spec->vref_mute_led_nid = spec->gpio_led; | ||
4920 | return 1; | 4925 | return 1; |
4921 | } | 4926 | } |
4922 | if (sscanf(dev->name, "HP_Mute_LED_%d", | 4927 | if (sscanf(dev->name, "HP_Mute_LED_%d", |
@@ -5045,15 +5050,12 @@ static int stac92xx_pre_resume(struct hda_codec *codec) | |||
5045 | struct sigmatel_spec *spec = codec->spec; | 5050 | struct sigmatel_spec *spec = codec->spec; |
5046 | 5051 | ||
5047 | /* sync mute LED */ | 5052 | /* sync mute LED */ |
5048 | if (spec->gpio_led) { | 5053 | if (spec->vref_mute_led_nid) |
5049 | if (spec->gpio_led <= 8) { | 5054 | stac_vrefout_set(codec, spec->vref_mute_led_nid, |
5050 | stac_gpio_set(codec, spec->gpio_mask, | 5055 | spec->vref_led); |
5051 | spec->gpio_dir, spec->gpio_data); | 5056 | else if (spec->gpio_led) |
5052 | } else { | 5057 | stac_gpio_set(codec, spec->gpio_mask, |
5053 | stac_vrefout_set(codec, | 5058 | spec->gpio_dir, spec->gpio_data); |
5054 | spec->gpio_led, spec->vref_led); | ||
5055 | } | ||
5056 | } | ||
5057 | return 0; | 5059 | return 0; |
5058 | } | 5060 | } |
5059 | 5061 | ||
@@ -5064,7 +5066,7 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg, | |||
5064 | struct sigmatel_spec *spec = codec->spec; | 5066 | struct sigmatel_spec *spec = codec->spec; |
5065 | 5067 | ||
5066 | if (power_state == AC_PWRST_D3) { | 5068 | if (power_state == AC_PWRST_D3) { |
5067 | if (spec->gpio_led > 8) { | 5069 | if (spec->vref_mute_led_nid) { |
5068 | /* with vref-out pin used for mute led control | 5070 | /* with vref-out pin used for mute led control |
5069 | * codec AFG is prevented from D3 state | 5071 | * codec AFG is prevented from D3 state |
5070 | */ | 5072 | */ |
@@ -5117,7 +5119,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec) | |||
5117 | } | 5119 | } |
5118 | } | 5120 | } |
5119 | /*polarity defines *not* muted state level*/ | 5121 | /*polarity defines *not* muted state level*/ |
5120 | if (spec->gpio_led <= 8) { | 5122 | if (!spec->vref_mute_led_nid) { |
5121 | if (muted) | 5123 | if (muted) |
5122 | spec->gpio_data &= ~spec->gpio_led; /* orange */ | 5124 | spec->gpio_data &= ~spec->gpio_led; /* orange */ |
5123 | else | 5125 | else |
@@ -5135,7 +5137,8 @@ static int stac92xx_update_led_status(struct hda_codec *codec) | |||
5135 | muted_lvl = spec->gpio_led_polarity ? | 5137 | muted_lvl = spec->gpio_led_polarity ? |
5136 | AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; | 5138 | AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; |
5137 | spec->vref_led = muted ? muted_lvl : notmtd_lvl; | 5139 | spec->vref_led = muted ? muted_lvl : notmtd_lvl; |
5138 | stac_vrefout_set(codec, spec->gpio_led, spec->vref_led); | 5140 | stac_vrefout_set(codec, spec->vref_mute_led_nid, |
5141 | spec->vref_led); | ||
5139 | } | 5142 | } |
5140 | return 0; | 5143 | return 0; |
5141 | } | 5144 | } |
@@ -5649,7 +5652,7 @@ again: | |||
5649 | 5652 | ||
5650 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5653 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5651 | if (spec->gpio_led) { | 5654 | if (spec->gpio_led) { |
5652 | if (spec->gpio_led <= 8) { | 5655 | if (!spec->vref_mute_led_nid) { |
5653 | spec->gpio_mask |= spec->gpio_led; | 5656 | spec->gpio_mask |= spec->gpio_led; |
5654 | spec->gpio_dir |= spec->gpio_led; | 5657 | spec->gpio_dir |= spec->gpio_led; |
5655 | spec->gpio_data |= spec->gpio_led; | 5658 | spec->gpio_data |= spec->gpio_led; |
@@ -5962,7 +5965,7 @@ again: | |||
5962 | 5965 | ||
5963 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5966 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5964 | if (spec->gpio_led) { | 5967 | if (spec->gpio_led) { |
5965 | if (spec->gpio_led <= 8) { | 5968 | if (!spec->vref_mute_led_nid) { |
5966 | spec->gpio_mask |= spec->gpio_led; | 5969 | spec->gpio_mask |= spec->gpio_led; |
5967 | spec->gpio_dir |= spec->gpio_led; | 5970 | spec->gpio_dir |= spec->gpio_led; |
5968 | spec->gpio_data |= spec->gpio_led; | 5971 | spec->gpio_data |= spec->gpio_led; |
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index a391e622a192..28dfafb56dd1 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c | |||
@@ -41,6 +41,7 @@ MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}"); | |||
41 | static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ | 41 | static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ |
42 | static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ | 42 | static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ |
43 | static int enable = 1; | 43 | static int enable = 1; |
44 | static int codecs = 1; | ||
44 | 45 | ||
45 | module_param(index, int, 0444); | 46 | module_param(index, int, 0444); |
46 | MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator."); | 47 | MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator."); |
@@ -48,6 +49,8 @@ module_param(id, charp, 0444); | |||
48 | MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator."); | 49 | MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator."); |
49 | module_param(enable, bool, 0444); | 50 | module_param(enable, bool, 0444); |
50 | MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); | 51 | MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); |
52 | module_param(codecs, int, 0444); | ||
53 | MODULE_PARM_DESC(codecs, "Set bit to indicate that codec number is expected to be present (default 1)"); | ||
51 | 54 | ||
52 | static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = { | 55 | static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = { |
53 | { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, | 56 | { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, |
@@ -140,6 +143,9 @@ struct sis7019 { | |||
140 | dma_addr_t silence_dma_addr; | 143 | dma_addr_t silence_dma_addr; |
141 | }; | 144 | }; |
142 | 145 | ||
146 | /* These values are also used by the module param 'codecs' to indicate | ||
147 | * which codecs should be present. | ||
148 | */ | ||
143 | #define SIS_PRIMARY_CODEC_PRESENT 0x0001 | 149 | #define SIS_PRIMARY_CODEC_PRESENT 0x0001 |
144 | #define SIS_SECONDARY_CODEC_PRESENT 0x0002 | 150 | #define SIS_SECONDARY_CODEC_PRESENT 0x0002 |
145 | #define SIS_TERTIARY_CODEC_PRESENT 0x0004 | 151 | #define SIS_TERTIARY_CODEC_PRESENT 0x0004 |
@@ -1078,6 +1084,7 @@ static int sis_chip_init(struct sis7019 *sis) | |||
1078 | { | 1084 | { |
1079 | unsigned long io = sis->ioport; | 1085 | unsigned long io = sis->ioport; |
1080 | void __iomem *ioaddr = sis->ioaddr; | 1086 | void __iomem *ioaddr = sis->ioaddr; |
1087 | unsigned long timeout; | ||
1081 | u16 status; | 1088 | u16 status; |
1082 | int count; | 1089 | int count; |
1083 | int i; | 1090 | int i; |
@@ -1104,21 +1111,45 @@ static int sis_chip_init(struct sis7019 *sis) | |||
1104 | while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) | 1111 | while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) |
1105 | udelay(1); | 1112 | udelay(1); |
1106 | 1113 | ||
1114 | /* Command complete, we can let go of the semaphore now. | ||
1115 | */ | ||
1116 | outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); | ||
1117 | if (!count) | ||
1118 | return -EIO; | ||
1119 | |||
1107 | /* Now that we've finished the reset, find out what's attached. | 1120 | /* Now that we've finished the reset, find out what's attached. |
1121 | * There are some codec/board combinations that take an extremely | ||
1122 | * long time to come up. 350+ ms has been observed in the field, | ||
1123 | * so we'll give them up to 500ms. | ||
1108 | */ | 1124 | */ |
1109 | status = inl(io + SIS_AC97_STATUS); | 1125 | sis->codecs_present = 0; |
1110 | if (status & SIS_AC97_STATUS_CODEC_READY) | 1126 | timeout = msecs_to_jiffies(500) + jiffies; |
1111 | sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; | 1127 | while (time_before_eq(jiffies, timeout)) { |
1112 | if (status & SIS_AC97_STATUS_CODEC2_READY) | 1128 | status = inl(io + SIS_AC97_STATUS); |
1113 | sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; | 1129 | if (status & SIS_AC97_STATUS_CODEC_READY) |
1114 | if (status & SIS_AC97_STATUS_CODEC3_READY) | 1130 | sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; |
1115 | sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; | 1131 | if (status & SIS_AC97_STATUS_CODEC2_READY) |
1116 | 1132 | sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; | |
1117 | /* All done, let go of the semaphore, and check for errors | 1133 | if (status & SIS_AC97_STATUS_CODEC3_READY) |
1134 | sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; | ||
1135 | |||
1136 | if (sis->codecs_present == codecs) | ||
1137 | break; | ||
1138 | |||
1139 | msleep(1); | ||
1140 | } | ||
1141 | |||
1142 | /* All done, check for errors. | ||
1118 | */ | 1143 | */ |
1119 | outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); | 1144 | if (!sis->codecs_present) { |
1120 | if (!sis->codecs_present || !count) | 1145 | printk(KERN_ERR "sis7019: could not find any codecs\n"); |
1121 | return -EIO; | 1146 | return -EIO; |
1147 | } | ||
1148 | |||
1149 | if (sis->codecs_present != codecs) { | ||
1150 | printk(KERN_WARNING "sis7019: missing codecs, found %0x, expected %0x\n", | ||
1151 | sis->codecs_present, codecs); | ||
1152 | } | ||
1122 | 1153 | ||
1123 | /* Let the hardware know that the audio driver is alive, | 1154 | /* Let the hardware know that the audio driver is alive, |
1124 | * and enable PCM slots on the AC-link for L/R playback (3 & 4) and | 1155 | * and enable PCM slots on the AC-link for L/R playback (3 & 4) and |
@@ -1390,6 +1421,17 @@ static int __devinit snd_sis7019_probe(struct pci_dev *pci, | |||
1390 | if (!enable) | 1421 | if (!enable) |
1391 | goto error_out; | 1422 | goto error_out; |
1392 | 1423 | ||
1424 | /* The user can specify which codecs should be present so that we | ||
1425 | * can wait for them to show up if they are slow to recover from | ||
1426 | * the AC97 cold reset. We default to a single codec, the primary. | ||
1427 | * | ||
1428 | * We assume that SIS_PRIMARY_*_PRESENT matches bits 0-2. | ||
1429 | */ | ||
1430 | codecs &= SIS_PRIMARY_CODEC_PRESENT | SIS_SECONDARY_CODEC_PRESENT | | ||
1431 | SIS_TERTIARY_CODEC_PRESENT; | ||
1432 | if (!codecs) | ||
1433 | codecs = SIS_PRIMARY_CODEC_PRESENT; | ||
1434 | |||
1393 | rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card); | 1435 | rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card); |
1394 | if (rc < 0) | 1436 | if (rc < 0) |
1395 | goto error_out; | 1437 | goto error_out; |
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index c5ca8cfea60f..0441893e270e 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c | |||
@@ -863,13 +863,13 @@ static struct i2c_driver uda1380_i2c_driver = { | |||
863 | 863 | ||
864 | static int __init uda1380_modinit(void) | 864 | static int __init uda1380_modinit(void) |
865 | { | 865 | { |
866 | int ret; | 866 | int ret = 0; |
867 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 867 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
868 | ret = i2c_add_driver(&uda1380_i2c_driver); | 868 | ret = i2c_add_driver(&uda1380_i2c_driver); |
869 | if (ret != 0) | 869 | if (ret != 0) |
870 | pr_err("Failed to register UDA1380 I2C driver: %d\n", ret); | 870 | pr_err("Failed to register UDA1380 I2C driver: %d\n", ret); |
871 | #endif | 871 | #endif |
872 | return 0; | 872 | return ret; |
873 | } | 873 | } |
874 | module_init(uda1380_modinit); | 874 | module_init(uda1380_modinit); |
875 | 875 | ||
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6c2988549003..d0c545b73d78 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -1325,15 +1325,15 @@ SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0), | |||
1325 | }; | 1325 | }; |
1326 | 1326 | ||
1327 | static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = { | 1327 | static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = { |
1328 | SND_SOC_DAPM_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, | 1328 | SND_SOC_DAPM_VIRT_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, |
1329 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), | 1329 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), |
1330 | SND_SOC_DAPM_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, | 1330 | SND_SOC_DAPM_VIRT_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, |
1331 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), | 1331 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), |
1332 | }; | 1332 | }; |
1333 | 1333 | ||
1334 | static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = { | 1334 | static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = { |
1335 | SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), | 1335 | SND_SOC_DAPM_VIRT_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), |
1336 | SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), | 1336 | SND_SOC_DAPM_VIRT_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), |
1337 | }; | 1337 | }; |
1338 | 1338 | ||
1339 | static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { | 1339 | static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { |
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig index b133bfcc5848..738391757f2c 100644 --- a/sound/soc/imx/Kconfig +++ b/sound/soc/imx/Kconfig | |||
@@ -28,7 +28,7 @@ config SND_MXC_SOC_WM1133_EV1 | |||
28 | 28 | ||
29 | config SND_SOC_MX27VIS_AIC32X4 | 29 | config SND_SOC_MX27VIS_AIC32X4 |
30 | tristate "SoC audio support for Visstrim M10 boards" | 30 | tristate "SoC audio support for Visstrim M10 boards" |
31 | depends on MACH_IMX27_VISSTRIM_M10 | 31 | depends on MACH_IMX27_VISSTRIM_M10 && I2C |
32 | select SND_SOC_TLV320AIC32X4 | 32 | select SND_SOC_TLV320AIC32X4 |
33 | select SND_MXC_SOC_MX2 | 33 | select SND_MXC_SOC_MX2 |
34 | help | 34 | help |
diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig index 8f49e165f4d1..c62d715235e2 100644 --- a/sound/soc/kirkwood/Kconfig +++ b/sound/soc/kirkwood/Kconfig | |||
@@ -12,6 +12,7 @@ config SND_KIRKWOOD_SOC_I2S | |||
12 | config SND_KIRKWOOD_SOC_OPENRD | 12 | config SND_KIRKWOOD_SOC_OPENRD |
13 | tristate "SoC Audio support for Kirkwood Openrd Client" | 13 | tristate "SoC Audio support for Kirkwood Openrd Client" |
14 | depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE) | 14 | depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE) |
15 | depends on I2C | ||
15 | select SND_KIRKWOOD_SOC_I2S | 16 | select SND_KIRKWOOD_SOC_I2S |
16 | select SND_SOC_CS42L51 | 17 | select SND_SOC_CS42L51 |
17 | help | 18 | help |
@@ -20,7 +21,7 @@ config SND_KIRKWOOD_SOC_OPENRD | |||
20 | 21 | ||
21 | config SND_KIRKWOOD_SOC_T5325 | 22 | config SND_KIRKWOOD_SOC_T5325 |
22 | tristate "SoC Audio support for HP t5325" | 23 | tristate "SoC Audio support for HP t5325" |
23 | depends on SND_KIRKWOOD_SOC && MACH_T5325 | 24 | depends on SND_KIRKWOOD_SOC && MACH_T5325 && I2C |
24 | select SND_KIRKWOOD_SOC_I2S | 25 | select SND_KIRKWOOD_SOC_I2S |
25 | select SND_SOC_ALC5623 | 26 | select SND_SOC_ALC5623 |
26 | help | 27 | help |
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index ffd2242e305f..a0f7d3cfa470 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig | |||
@@ -151,6 +151,7 @@ config SND_SOC_ZYLONITE | |||
151 | config SND_SOC_RAUMFELD | 151 | config SND_SOC_RAUMFELD |
152 | tristate "SoC Audio support Raumfeld audio adapter" | 152 | tristate "SoC Audio support Raumfeld audio adapter" |
153 | depends on SND_PXA2XX_SOC && (MACH_RAUMFELD_SPEAKER || MACH_RAUMFELD_CONNECTOR) | 153 | depends on SND_PXA2XX_SOC && (MACH_RAUMFELD_SPEAKER || MACH_RAUMFELD_CONNECTOR) |
154 | depends on I2C && SPI_MASTER | ||
154 | select SND_PXA_SOC_SSP | 155 | select SND_PXA_SOC_SSP |
155 | select SND_SOC_CS4270 | 156 | select SND_SOC_CS4270 |
156 | select SND_SOC_AK4104 | 157 | select SND_SOC_AK4104 |
@@ -159,7 +160,7 @@ config SND_SOC_RAUMFELD | |||
159 | 160 | ||
160 | config SND_PXA2XX_SOC_HX4700 | 161 | config SND_PXA2XX_SOC_HX4700 |
161 | tristate "SoC Audio support for HP iPAQ hx4700" | 162 | tristate "SoC Audio support for HP iPAQ hx4700" |
162 | depends on SND_PXA2XX_SOC && MACH_H4700 | 163 | depends on SND_PXA2XX_SOC && MACH_H4700 && I2C |
163 | select SND_PXA2XX_SOC_I2S | 164 | select SND_PXA2XX_SOC_I2S |
164 | select SND_SOC_AK4641 | 165 | select SND_SOC_AK4641 |
165 | help | 166 | help |
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 0c12b98484bd..4220bb0f2730 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c | |||
@@ -58,7 +58,36 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *params) | |||
58 | } | 58 | } |
59 | EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk); | 59 | EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk); |
60 | 60 | ||
61 | static struct snd_soc_platform_driver dummy_platform; | 61 | static const struct snd_pcm_hardware dummy_dma_hardware = { |
62 | .formats = 0xffffffff, | ||
63 | .channels_min = 1, | ||
64 | .channels_max = UINT_MAX, | ||
65 | |||
66 | /* Random values to keep userspace happy when checking constraints */ | ||
67 | .info = SNDRV_PCM_INFO_INTERLEAVED | | ||
68 | SNDRV_PCM_INFO_BLOCK_TRANSFER, | ||
69 | .buffer_bytes_max = 128*1024, | ||
70 | .period_bytes_min = PAGE_SIZE, | ||
71 | .period_bytes_max = PAGE_SIZE*2, | ||
72 | .periods_min = 2, | ||
73 | .periods_max = 128, | ||
74 | }; | ||
75 | |||
76 | static int dummy_dma_open(struct snd_pcm_substream *substream) | ||
77 | { | ||
78 | snd_soc_set_runtime_hwparams(substream, &dummy_dma_hardware); | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static struct snd_pcm_ops dummy_dma_ops = { | ||
84 | .open = dummy_dma_open, | ||
85 | .ioctl = snd_pcm_lib_ioctl, | ||
86 | }; | ||
87 | |||
88 | static struct snd_soc_platform_driver dummy_platform = { | ||
89 | .ops = &dummy_dma_ops, | ||
90 | }; | ||
62 | 91 | ||
63 | static __devinit int snd_soc_dummy_probe(struct platform_device *pdev) | 92 | static __devinit int snd_soc_dummy_probe(struct platform_device *pdev) |
64 | { | 93 | { |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 7d98676808d8..955930e0a5c3 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -463,7 +463,8 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
463 | 463 | ||
464 | list_for_each_entry(counter, &evsel_list->entries, node) { | 464 | list_for_each_entry(counter, &evsel_list->entries, node) { |
465 | if (create_perf_stat_counter(counter, first) < 0) { | 465 | if (create_perf_stat_counter(counter, first) < 0) { |
466 | if (errno == EINVAL || errno == ENOSYS || errno == ENOENT) { | 466 | if (errno == EINVAL || errno == ENOSYS || |
467 | errno == ENOENT || errno == EOPNOTSUPP) { | ||
467 | if (verbose) | 468 | if (verbose) |
468 | ui__warning("%s event is not supported by the kernel.\n", | 469 | ui__warning("%s event is not supported by the kernel.\n", |
469 | event_name(counter)); | 470 | event_name(counter)); |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index e42626422587..d7915d4e77cb 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -34,6 +34,16 @@ int __perf_evsel__sample_size(u64 sample_type) | |||
34 | return size; | 34 | return size; |
35 | } | 35 | } |
36 | 36 | ||
37 | static void hists__init(struct hists *hists) | ||
38 | { | ||
39 | memset(hists, 0, sizeof(*hists)); | ||
40 | hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT; | ||
41 | hists->entries_in = &hists->entries_in_array[0]; | ||
42 | hists->entries_collapsed = RB_ROOT; | ||
43 | hists->entries = RB_ROOT; | ||
44 | pthread_mutex_init(&hists->lock, NULL); | ||
45 | } | ||
46 | |||
37 | void perf_evsel__init(struct perf_evsel *evsel, | 47 | void perf_evsel__init(struct perf_evsel *evsel, |
38 | struct perf_event_attr *attr, int idx) | 48 | struct perf_event_attr *attr, int idx) |
39 | { | 49 | { |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index bcd05d05b4f0..33c17a2b2a81 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -388,7 +388,7 @@ static int write_event_desc(int fd, struct perf_header *h __used, | |||
388 | /* | 388 | /* |
389 | * write event string as passed on cmdline | 389 | * write event string as passed on cmdline |
390 | */ | 390 | */ |
391 | ret = do_write_string(fd, attr->name); | 391 | ret = do_write_string(fd, event_name(attr)); |
392 | if (ret < 0) | 392 | if (ret < 0) |
393 | return ret; | 393 | return ret; |
394 | /* | 394 | /* |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index a36a3fa81ffb..abef2703cd24 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -1211,13 +1211,3 @@ size_t hists__fprintf_nr_events(struct hists *hists, FILE *fp) | |||
1211 | 1211 | ||
1212 | return ret; | 1212 | return ret; |
1213 | } | 1213 | } |
1214 | |||
1215 | void hists__init(struct hists *hists) | ||
1216 | { | ||
1217 | memset(hists, 0, sizeof(*hists)); | ||
1218 | hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT; | ||
1219 | hists->entries_in = &hists->entries_in_array[0]; | ||
1220 | hists->entries_collapsed = RB_ROOT; | ||
1221 | hists->entries = RB_ROOT; | ||
1222 | pthread_mutex_init(&hists->lock, NULL); | ||
1223 | } | ||
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index c86c1d27bd1e..89289c8e935e 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -63,8 +63,6 @@ struct hists { | |||
63 | struct callchain_cursor callchain_cursor; | 63 | struct callchain_cursor callchain_cursor; |
64 | }; | 64 | }; |
65 | 65 | ||
66 | void hists__init(struct hists *hists); | ||
67 | |||
68 | struct hist_entry *__hists__add_entry(struct hists *self, | 66 | struct hist_entry *__hists__add_entry(struct hists *self, |
69 | struct addr_location *al, | 67 | struct addr_location *al, |
70 | struct symbol *parent, u64 period); | 68 | struct symbol *parent, u64 period); |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 85c1e6b76f0a..0f4555ce9063 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -1333,6 +1333,10 @@ int perf_session__cpu_bitmap(struct perf_session *session, | |||
1333 | } | 1333 | } |
1334 | 1334 | ||
1335 | map = cpu_map__new(cpu_list); | 1335 | map = cpu_map__new(cpu_list); |
1336 | if (map == NULL) { | ||
1337 | pr_err("Invalid cpu_list\n"); | ||
1338 | return -1; | ||
1339 | } | ||
1336 | 1340 | ||
1337 | for (i = 0; i < map->nr; i++) { | 1341 | for (i = 0; i < map->nr; i++) { |
1338 | int cpu = map->map[i]; | 1342 | int cpu = map->map[i]; |
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index 0a7ed5b5e281..6c164dc9ee95 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c | |||
@@ -1537,6 +1537,8 @@ process_flags(struct event *event, struct print_arg *arg, char **tok) | |||
1537 | field = malloc_or_die(sizeof(*field)); | 1537 | field = malloc_or_die(sizeof(*field)); |
1538 | 1538 | ||
1539 | type = process_arg(event, field, &token); | 1539 | type = process_arg(event, field, &token); |
1540 | while (type == EVENT_OP) | ||
1541 | type = process_op(event, field, &token); | ||
1540 | if (test_type_token(type, token, EVENT_DELIM, ",")) | 1542 | if (test_type_token(type, token, EVENT_DELIM, ",")) |
1541 | goto out_free; | 1543 | goto out_free; |
1542 | 1544 | ||
diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c index a195c07fa829..304d7e5717e9 100644 --- a/virt/kvm/iommu.c +++ b/virt/kvm/iommu.c | |||
@@ -113,7 +113,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot) | |||
113 | 113 | ||
114 | /* Map into IO address space */ | 114 | /* Map into IO address space */ |
115 | r = iommu_map(domain, gfn_to_gpa(gfn), pfn_to_hpa(pfn), | 115 | r = iommu_map(domain, gfn_to_gpa(gfn), pfn_to_hpa(pfn), |
116 | get_order(page_size), flags); | 116 | page_size, flags); |
117 | if (r) { | 117 | if (r) { |
118 | printk(KERN_ERR "kvm_iommu_map_address:" | 118 | printk(KERN_ERR "kvm_iommu_map_address:" |
119 | "iommu failed to map pfn=%llx\n", pfn); | 119 | "iommu failed to map pfn=%llx\n", pfn); |
@@ -292,15 +292,15 @@ static void kvm_iommu_put_pages(struct kvm *kvm, | |||
292 | 292 | ||
293 | while (gfn < end_gfn) { | 293 | while (gfn < end_gfn) { |
294 | unsigned long unmap_pages; | 294 | unsigned long unmap_pages; |
295 | int order; | 295 | size_t size; |
296 | 296 | ||
297 | /* Get physical address */ | 297 | /* Get physical address */ |
298 | phys = iommu_iova_to_phys(domain, gfn_to_gpa(gfn)); | 298 | phys = iommu_iova_to_phys(domain, gfn_to_gpa(gfn)); |
299 | pfn = phys >> PAGE_SHIFT; | 299 | pfn = phys >> PAGE_SHIFT; |
300 | 300 | ||
301 | /* Unmap address from IO address space */ | 301 | /* Unmap address from IO address space */ |
302 | order = iommu_unmap(domain, gfn_to_gpa(gfn), 0); | 302 | size = iommu_unmap(domain, gfn_to_gpa(gfn), PAGE_SIZE); |
303 | unmap_pages = 1ULL << order; | 303 | unmap_pages = 1ULL << get_order(size); |
304 | 304 | ||
305 | /* Unpin all pages we just unmapped to not leak any memory */ | 305 | /* Unpin all pages we just unmapped to not leak any memory */ |
306 | kvm_unpin_pages(kvm, pfn, unmap_pages); | 306 | kvm_unpin_pages(kvm, pfn, unmap_pages); |