diff options
384 files changed, 3436 insertions, 2548 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index a91f3089001..b6426f15b4a 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
| @@ -173,12 +173,13 @@ prototypes: | |||
| 173 | sector_t (*bmap)(struct address_space *, sector_t); | 173 | sector_t (*bmap)(struct address_space *, sector_t); |
| 174 | int (*invalidatepage) (struct page *, unsigned long); | 174 | int (*invalidatepage) (struct page *, unsigned long); |
| 175 | int (*releasepage) (struct page *, int); | 175 | int (*releasepage) (struct page *, int); |
| 176 | void (*freepage)(struct page *); | ||
| 176 | int (*direct_IO)(int, struct kiocb *, const struct iovec *iov, | 177 | int (*direct_IO)(int, struct kiocb *, const struct iovec *iov, |
| 177 | loff_t offset, unsigned long nr_segs); | 178 | loff_t offset, unsigned long nr_segs); |
| 178 | int (*launder_page) (struct page *); | 179 | int (*launder_page) (struct page *); |
| 179 | 180 | ||
| 180 | locking rules: | 181 | locking rules: |
| 181 | All except set_page_dirty may block | 182 | All except set_page_dirty and freepage may block |
| 182 | 183 | ||
| 183 | BKL PageLocked(page) i_mutex | 184 | BKL PageLocked(page) i_mutex |
| 184 | writepage: no yes, unlocks (see below) | 185 | writepage: no yes, unlocks (see below) |
| @@ -193,6 +194,7 @@ perform_write: no n/a yes | |||
| 193 | bmap: no | 194 | bmap: no |
| 194 | invalidatepage: no yes | 195 | invalidatepage: no yes |
| 195 | releasepage: no yes | 196 | releasepage: no yes |
| 197 | freepage: no yes | ||
| 196 | direct_IO: no | 198 | direct_IO: no |
| 197 | launder_page: no yes | 199 | launder_page: no yes |
| 198 | 200 | ||
| @@ -288,6 +290,9 @@ buffers from the page in preparation for freeing it. It returns zero to | |||
| 288 | indicate that the buffers are (or may be) freeable. If ->releasepage is zero, | 290 | indicate that the buffers are (or may be) freeable. If ->releasepage is zero, |
| 289 | the kernel assumes that the fs has no private interest in the buffers. | 291 | the kernel assumes that the fs has no private interest in the buffers. |
| 290 | 292 | ||
| 293 | ->freepage() is called when the kernel is done dropping the page | ||
| 294 | from the page cache. | ||
| 295 | |||
| 291 | ->launder_page() may be called prior to releasing a page if | 296 | ->launder_page() may be called prior to releasing a page if |
| 292 | it is still found to be dirty. It returns zero if the page was successfully | 297 | it is still found to be dirty. It returns zero if the page was successfully |
| 293 | cleaned, or an error value if not. Note that in order to prevent the page | 298 | cleaned, or an error value if not. Note that in order to prevent the page |
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 55c28b79d8d..20899e095e7 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
| @@ -534,6 +534,7 @@ struct address_space_operations { | |||
| 534 | sector_t (*bmap)(struct address_space *, sector_t); | 534 | sector_t (*bmap)(struct address_space *, sector_t); |
| 535 | int (*invalidatepage) (struct page *, unsigned long); | 535 | int (*invalidatepage) (struct page *, unsigned long); |
| 536 | int (*releasepage) (struct page *, int); | 536 | int (*releasepage) (struct page *, int); |
| 537 | void (*freepage)(struct page *); | ||
| 537 | ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov, | 538 | ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov, |
| 538 | loff_t offset, unsigned long nr_segs); | 539 | loff_t offset, unsigned long nr_segs); |
| 539 | struct page* (*get_xip_page)(struct address_space *, sector_t, | 540 | struct page* (*get_xip_page)(struct address_space *, sector_t, |
| @@ -678,6 +679,12 @@ struct address_space_operations { | |||
| 678 | need to ensure this. Possibly it can clear the PageUptodate | 679 | need to ensure this. Possibly it can clear the PageUptodate |
| 679 | bit if it cannot free private data yet. | 680 | bit if it cannot free private data yet. |
| 680 | 681 | ||
| 682 | freepage: freepage is called once the page is no longer visible in | ||
| 683 | the page cache in order to allow the cleanup of any private | ||
| 684 | data. Since it may be called by the memory reclaimer, it | ||
| 685 | should not assume that the original address_space mapping still | ||
| 686 | exists, and it should not block. | ||
| 687 | |||
| 681 | direct_IO: called by the generic read/write routines to perform | 688 | direct_IO: called by the generic read/write routines to perform |
| 682 | direct_IO - that is IO requests which bypass the page cache | 689 | direct_IO - that is IO requests which bypass the page cache |
| 683 | and transfer data directly between the storage and the | 690 | and transfer data directly between the storage and the |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index cdd2a6e8a3b..8b61c936099 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -2175,11 +2175,6 @@ and is between 256 and 4096 characters. It is defined in the file | |||
| 2175 | reset_devices [KNL] Force drivers to reset the underlying device | 2175 | reset_devices [KNL] Force drivers to reset the underlying device |
| 2176 | during initialization. | 2176 | during initialization. |
| 2177 | 2177 | ||
| 2178 | resource_alloc_from_bottom | ||
| 2179 | Allocate new resources from the beginning of available | ||
| 2180 | space, not the end. If you need to use this, please | ||
| 2181 | report a bug. | ||
| 2182 | |||
| 2183 | resume= [SWSUSP] | 2178 | resume= [SWSUSP] |
| 2184 | Specify the partition device for software suspend | 2179 | Specify the partition device for software suspend |
| 2185 | 2180 | ||
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 489e9bacd16..41cc7b30d7d 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt | |||
| @@ -379,8 +379,8 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: | |||
| 379 | zero) | 379 | zero) |
| 380 | 380 | ||
| 381 | bool pm_runtime_suspended(struct device *dev); | 381 | bool pm_runtime_suspended(struct device *dev); |
| 382 | - return true if the device's runtime PM status is 'suspended', or false | 382 | - return true if the device's runtime PM status is 'suspended' and its |
| 383 | otherwise | 383 | 'power.disable_depth' field is equal to zero, or false otherwise |
| 384 | 384 | ||
| 385 | void pm_runtime_allow(struct device *dev); | 385 | void pm_runtime_allow(struct device *dev); |
| 386 | - set the power.runtime_auto flag for the device and decrease its usage | 386 | - set the power.runtime_auto flag for the device and decrease its usage |
diff --git a/MAINTAINERS b/MAINTAINERS index 1a1c27b9c55..6a588873cf8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -559,14 +559,14 @@ W: http://maxim.org.za/at91_26.html | |||
| 559 | S: Maintained | 559 | S: Maintained |
| 560 | 560 | ||
| 561 | ARM/BCMRING ARM ARCHITECTURE | 561 | ARM/BCMRING ARM ARCHITECTURE |
| 562 | M: Leo Chen <leochen@broadcom.com> | 562 | M: Jiandong Zheng <jdzheng@broadcom.com> |
| 563 | M: Scott Branden <sbranden@broadcom.com> | 563 | M: Scott Branden <sbranden@broadcom.com> |
| 564 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 564 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 565 | S: Maintained | 565 | S: Maintained |
| 566 | F: arch/arm/mach-bcmring | 566 | F: arch/arm/mach-bcmring |
| 567 | 567 | ||
| 568 | ARM/BCMRING MTD NAND DRIVER | 568 | ARM/BCMRING MTD NAND DRIVER |
| 569 | M: Leo Chen <leochen@broadcom.com> | 569 | M: Jiandong Zheng <jdzheng@broadcom.com> |
| 570 | M: Scott Branden <sbranden@broadcom.com> | 570 | M: Scott Branden <sbranden@broadcom.com> |
| 571 | L: linux-mtd@lists.infradead.org | 571 | L: linux-mtd@lists.infradead.org |
| 572 | S: Maintained | 572 | S: Maintained |
| @@ -815,7 +815,7 @@ F: drivers/mmc/host/msm_sdcc.c | |||
| 815 | F: drivers/mmc/host/msm_sdcc.h | 815 | F: drivers/mmc/host/msm_sdcc.h |
| 816 | F: drivers/serial/msm_serial.h | 816 | F: drivers/serial/msm_serial.h |
| 817 | F: drivers/serial/msm_serial.c | 817 | F: drivers/serial/msm_serial.c |
| 818 | T: git git://codeaurora.org/quic/kernel/dwalker/linux-msm.git | 818 | T: git git://codeaurora.org/quic/kernel/davidb/linux-msm.git |
| 819 | S: Maintained | 819 | S: Maintained |
| 820 | 820 | ||
| 821 | ARM/TOSA MACHINE SUPPORT | 821 | ARM/TOSA MACHINE SUPPORT |
| @@ -5932,7 +5932,6 @@ F: include/linux/tty.h | |||
| 5932 | 5932 | ||
| 5933 | TULIP NETWORK DRIVERS | 5933 | TULIP NETWORK DRIVERS |
| 5934 | M: Grant Grundler <grundler@parisc-linux.org> | 5934 | M: Grant Grundler <grundler@parisc-linux.org> |
| 5935 | M: Kyle McMartin <kyle@mcmartin.ca> | ||
| 5936 | L: netdev@vger.kernel.org | 5935 | L: netdev@vger.kernel.org |
| 5937 | S: Maintained | 5936 | S: Maintained |
| 5938 | F: drivers/net/tulip/ | 5937 | F: drivers/net/tulip/ |
| @@ -6584,6 +6583,15 @@ F: include/linux/mfd/wm8400* | |||
| 6584 | F: include/sound/wm????.h | 6583 | F: include/sound/wm????.h |
| 6585 | F: sound/soc/codecs/wm* | 6584 | F: sound/soc/codecs/wm* |
| 6586 | 6585 | ||
| 6586 | WORKQUEUE | ||
| 6587 | M: Tejun Heo <tj@kernel.org> | ||
| 6588 | L: linux-kernel@vger.kernel.org | ||
| 6589 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git | ||
| 6590 | S: Maintained | ||
| 6591 | F: include/linux/workqueue.h | ||
| 6592 | F: kernel/workqueue.c | ||
| 6593 | F: Documentation/workqueue.txt | ||
| 6594 | |||
| 6587 | X.25 NETWORK LAYER | 6595 | X.25 NETWORK LAYER |
| 6588 | M: Andrew Hendry <andrew.hendry@gmail.com> | 6596 | M: Andrew Hendry <andrew.hendry@gmail.com> |
| 6589 | L: linux-x25@vger.kernel.org | 6597 | L: linux-x25@vger.kernel.org |
| @@ -1,7 +1,7 @@ | |||
| 1 | VERSION = 2 | 1 | VERSION = 2 |
| 2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
| 3 | SUBLEVEL = 37 | 3 | SUBLEVEL = 37 |
| 4 | EXTRAVERSION = -rc5 | 4 | EXTRAVERSION = -rc6 |
| 5 | NAME = Flesh-Eating Bats with Fangs | 5 | NAME = Flesh-Eating Bats with Fangs |
| 6 | 6 | ||
| 7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f1d9297b105..d56d21c0573 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -1311,7 +1311,7 @@ config HZ | |||
| 1311 | 1311 | ||
| 1312 | config THUMB2_KERNEL | 1312 | config THUMB2_KERNEL |
| 1313 | bool "Compile the kernel in Thumb-2 mode" | 1313 | bool "Compile the kernel in Thumb-2 mode" |
| 1314 | depends on CPU_V7 && EXPERIMENTAL | 1314 | depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL |
| 1315 | select AEABI | 1315 | select AEABI |
| 1316 | select ARM_ASM_UNIFIED | 1316 | select ARM_ASM_UNIFIED |
| 1317 | help | 1317 | help |
| @@ -1759,7 +1759,7 @@ comment "At least one emulation must be selected" | |||
| 1759 | 1759 | ||
| 1760 | config FPE_NWFPE | 1760 | config FPE_NWFPE |
| 1761 | bool "NWFPE math emulation" | 1761 | bool "NWFPE math emulation" |
| 1762 | depends on !AEABI || OABI_COMPAT | 1762 | depends on (!AEABI || OABI_COMPAT) && !THUMB2_KERNEL |
| 1763 | ---help--- | 1763 | ---help--- |
| 1764 | Say Y to include the NWFPE floating point emulator in the kernel. | 1764 | Say Y to include the NWFPE floating point emulator in the kernel. |
| 1765 | This is necessary to run most binaries. Linux does not currently | 1765 | This is necessary to run most binaries. Linux does not currently |
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 62d686f0b42..d13add71f72 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile | |||
| @@ -65,7 +65,7 @@ obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o | |||
| 65 | obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o | 65 | obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o |
| 66 | obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o | 66 | obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o |
| 67 | obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o | 67 | obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o |
| 68 | obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o | 68 | obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o board-stamp9g20.o |
| 69 | 69 | ||
| 70 | # AT91SAM9260/AT91SAM9G20 board-specific support | 70 | # AT91SAM9260/AT91SAM9G20 board-specific support |
| 71 | obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o | 71 | obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o |
diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c index bba5a560e02..feb65787c30 100644 --- a/arch/arm/mach-at91/board-pcontrol-g20.c +++ b/arch/arm/mach-at91/board-pcontrol-g20.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | 31 | ||
| 32 | #include <mach/board.h> | 32 | #include <mach/board.h> |
| 33 | #include <mach/at91sam9_smc.h> | 33 | #include <mach/at91sam9_smc.h> |
| 34 | #include <mach/stamp9g20.h> | ||
| 34 | 35 | ||
| 35 | #include "sam9_smc.h" | 36 | #include "sam9_smc.h" |
| 36 | #include "generic.h" | 37 | #include "generic.h" |
| @@ -38,11 +39,7 @@ | |||
| 38 | 39 | ||
| 39 | static void __init pcontrol_g20_map_io(void) | 40 | static void __init pcontrol_g20_map_io(void) |
| 40 | { | 41 | { |
| 41 | /* Initialize processor: 18.432 MHz crystal */ | 42 | stamp9g20_map_io(); |
| 42 | at91sam9260_initialize(18432000); | ||
| 43 | |||
| 44 | /* DGBU on ttyS0. (Rx, Tx) only TTL -> JTAG connector X7 17,19 ) */ | ||
| 45 | at91_register_uart(0, 0, 0); | ||
| 46 | 43 | ||
| 47 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */ | 44 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */ |
| 48 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | 45 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS |
| @@ -54,9 +51,6 @@ static void __init pcontrol_g20_map_io(void) | |||
| 54 | 51 | ||
| 55 | /* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */ | 52 | /* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */ |
| 56 | at91_register_uart(AT91SAM9260_ID_US4, 3, 0); | 53 | at91_register_uart(AT91SAM9260_ID_US4, 3, 0); |
| 57 | |||
| 58 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
| 59 | at91_set_serial_console(0); | ||
| 60 | } | 54 | } |
| 61 | 55 | ||
| 62 | 56 | ||
| @@ -66,38 +60,6 @@ static void __init init_irq(void) | |||
| 66 | } | 60 | } |
| 67 | 61 | ||
| 68 | 62 | ||
| 69 | /* | ||
| 70 | * NAND flash 512MiB 1,8V 8-bit, sector size 128 KiB | ||
| 71 | */ | ||
| 72 | static struct atmel_nand_data __initdata nand_data = { | ||
| 73 | .ale = 21, | ||
| 74 | .cle = 22, | ||
| 75 | .rdy_pin = AT91_PIN_PC13, | ||
| 76 | .enable_pin = AT91_PIN_PC14, | ||
| 77 | }; | ||
| 78 | |||
| 79 | /* | ||
| 80 | * Bus timings; unit = 7.57ns | ||
| 81 | */ | ||
| 82 | static struct sam9_smc_config __initdata nand_smc_config = { | ||
| 83 | .ncs_read_setup = 0, | ||
| 84 | .nrd_setup = 2, | ||
| 85 | .ncs_write_setup = 0, | ||
| 86 | .nwe_setup = 2, | ||
| 87 | |||
| 88 | .ncs_read_pulse = 4, | ||
| 89 | .nrd_pulse = 4, | ||
| 90 | .ncs_write_pulse = 4, | ||
| 91 | .nwe_pulse = 4, | ||
| 92 | |||
| 93 | .read_cycle = 7, | ||
| 94 | .write_cycle = 7, | ||
| 95 | |||
| 96 | .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | ||
| 97 | | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, | ||
| 98 | .tdf_cycles = 3, | ||
| 99 | }; | ||
| 100 | |||
| 101 | static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { | 63 | static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { |
| 102 | .ncs_read_setup = 16, | 64 | .ncs_read_setup = 16, |
| 103 | .nrd_setup = 18, | 65 | .nrd_setup = 18, |
| @@ -138,14 +100,6 @@ static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { | |||
| 138 | .tdf_cycles = 1, | 100 | .tdf_cycles = 1, |
| 139 | } }; | 101 | } }; |
| 140 | 102 | ||
| 141 | static void __init add_device_nand(void) | ||
| 142 | { | ||
| 143 | /* configure chip-select 3 (NAND) */ | ||
| 144 | sam9_smc_configure(3, &nand_smc_config); | ||
| 145 | at91_add_device_nand(&nand_data); | ||
| 146 | } | ||
| 147 | |||
| 148 | |||
| 149 | static void __init add_device_pcontrol(void) | 103 | static void __init add_device_pcontrol(void) |
| 150 | { | 104 | { |
| 151 | /* configure chip-select 4 (IO compatible to 8051 X4 ) */ | 105 | /* configure chip-select 4 (IO compatible to 8051 X4 ) */ |
| @@ -156,23 +110,6 @@ static void __init add_device_pcontrol(void) | |||
| 156 | 110 | ||
| 157 | 111 | ||
| 158 | /* | 112 | /* |
| 159 | * MCI (SD/MMC) | ||
| 160 | * det_pin, wp_pin and vcc_pin are not connected | ||
| 161 | */ | ||
| 162 | #if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) | ||
| 163 | static struct mci_platform_data __initdata mmc_data = { | ||
| 164 | .slot[0] = { | ||
| 165 | .bus_width = 4, | ||
| 166 | }, | ||
| 167 | }; | ||
| 168 | #else | ||
| 169 | static struct at91_mmc_data __initdata mmc_data = { | ||
| 170 | .wire4 = 1, | ||
| 171 | }; | ||
| 172 | #endif | ||
| 173 | |||
| 174 | |||
| 175 | /* | ||
| 176 | * USB Host port | 113 | * USB Host port |
| 177 | */ | 114 | */ |
| 178 | static struct at91_usbh_data __initdata usbh_data = { | 115 | static struct at91_usbh_data __initdata usbh_data = { |
| @@ -265,42 +202,13 @@ static struct spi_board_info pcontrol_g20_spi_devices[] = { | |||
| 265 | }; | 202 | }; |
| 266 | 203 | ||
| 267 | 204 | ||
| 268 | /* | ||
| 269 | * Dallas 1-Wire DS2431 | ||
| 270 | */ | ||
| 271 | static struct w1_gpio_platform_data w1_gpio_pdata = { | ||
| 272 | .pin = AT91_PIN_PA29, | ||
| 273 | .is_open_drain = 1, | ||
| 274 | }; | ||
| 275 | |||
| 276 | static struct platform_device w1_device = { | ||
| 277 | .name = "w1-gpio", | ||
| 278 | .id = -1, | ||
| 279 | .dev.platform_data = &w1_gpio_pdata, | ||
| 280 | }; | ||
| 281 | |||
| 282 | static void add_wire1(void) | ||
| 283 | { | ||
| 284 | at91_set_GPIO_periph(w1_gpio_pdata.pin, 1); | ||
| 285 | at91_set_multi_drive(w1_gpio_pdata.pin, 1); | ||
| 286 | platform_device_register(&w1_device); | ||
| 287 | } | ||
| 288 | |||
| 289 | |||
| 290 | static void __init pcontrol_g20_board_init(void) | 205 | static void __init pcontrol_g20_board_init(void) |
| 291 | { | 206 | { |
| 292 | at91_add_device_serial(); | 207 | stamp9g20_board_init(); |
| 293 | add_device_nand(); | ||
| 294 | #if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) | ||
| 295 | at91_add_device_mci(0, &mmc_data); | ||
| 296 | #else | ||
| 297 | at91_add_device_mmc(0, &mmc_data); | ||
| 298 | #endif | ||
| 299 | at91_add_device_usbh(&usbh_data); | 208 | at91_add_device_usbh(&usbh_data); |
| 300 | at91_add_device_eth(&macb_data); | 209 | at91_add_device_eth(&macb_data); |
| 301 | at91_add_device_i2c(pcontrol_g20_i2c_devices, | 210 | at91_add_device_i2c(pcontrol_g20_i2c_devices, |
| 302 | ARRAY_SIZE(pcontrol_g20_i2c_devices)); | 211 | ARRAY_SIZE(pcontrol_g20_i2c_devices)); |
| 303 | add_wire1(); | ||
| 304 | add_device_pcontrol(); | 212 | add_device_pcontrol(); |
| 305 | at91_add_device_spi(pcontrol_g20_spi_devices, | 213 | at91_add_device_spi(pcontrol_g20_spi_devices, |
| 306 | ARRAY_SIZE(pcontrol_g20_spi_devices)); | 214 | ARRAY_SIZE(pcontrol_g20_spi_devices)); |
diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c index 5206eef4a67..f8902b11896 100644 --- a/arch/arm/mach-at91/board-stamp9g20.c +++ b/arch/arm/mach-at91/board-stamp9g20.c | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | #include "generic.h" | 32 | #include "generic.h" |
| 33 | 33 | ||
| 34 | 34 | ||
| 35 | static void __init portuxg20_map_io(void) | 35 | void __init stamp9g20_map_io(void) |
| 36 | { | 36 | { |
| 37 | /* Initialize processor: 18.432 MHz crystal */ | 37 | /* Initialize processor: 18.432 MHz crystal */ |
| 38 | at91sam9260_initialize(18432000); | 38 | at91sam9260_initialize(18432000); |
| @@ -40,6 +40,24 @@ static void __init portuxg20_map_io(void) | |||
| 40 | /* DGBU on ttyS0. (Rx & Tx only) */ | 40 | /* DGBU on ttyS0. (Rx & Tx only) */ |
| 41 | at91_register_uart(0, 0, 0); | 41 | at91_register_uart(0, 0, 0); |
| 42 | 42 | ||
| 43 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
| 44 | at91_set_serial_console(0); | ||
| 45 | } | ||
| 46 | |||
| 47 | static void __init stamp9g20evb_map_io(void) | ||
| 48 | { | ||
| 49 | stamp9g20_map_io(); | ||
| 50 | |||
| 51 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ | ||
| 52 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS | ||
| 53 | | ATMEL_UART_DTR | ATMEL_UART_DSR | ||
| 54 | | ATMEL_UART_DCD | ATMEL_UART_RI); | ||
| 55 | } | ||
| 56 | |||
| 57 | static void __init portuxg20_map_io(void) | ||
| 58 | { | ||
| 59 | stamp9g20_map_io(); | ||
| 60 | |||
| 43 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ | 61 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ |
| 44 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS | 62 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS |
| 45 | | ATMEL_UART_DTR | ATMEL_UART_DSR | 63 | | ATMEL_UART_DTR | ATMEL_UART_DSR |
| @@ -56,26 +74,6 @@ static void __init portuxg20_map_io(void) | |||
| 56 | 74 | ||
| 57 | /* USART5 on ttyS6. (Rx, Tx only) */ | 75 | /* USART5 on ttyS6. (Rx, Tx only) */ |
| 58 | at91_register_uart(AT91SAM9260_ID_US5, 6, 0); | 76 | at91_register_uart(AT91SAM9260_ID_US5, 6, 0); |
| 59 | |||
| 60 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
| 61 | at91_set_serial_console(0); | ||
| 62 | } | ||
| 63 | |||
| 64 | static void __init stamp9g20_map_io(void) | ||
| 65 | { | ||
| 66 | /* Initialize processor: 18.432 MHz crystal */ | ||
| 67 | at91sam9260_initialize(18432000); | ||
| 68 | |||
| 69 | /* DGBU on ttyS0. (Rx & Tx only) */ | ||
| 70 | at91_register_uart(0, 0, 0); | ||
| 71 | |||
| 72 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ | ||
| 73 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS | ||
| 74 | | ATMEL_UART_DTR | ATMEL_UART_DSR | ||
| 75 | | ATMEL_UART_DCD | ATMEL_UART_RI); | ||
| 76 | |||
| 77 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
| 78 | at91_set_serial_console(0); | ||
| 79 | } | 77 | } |
| 80 | 78 | ||
| 81 | static void __init init_irq(void) | 79 | static void __init init_irq(void) |
| @@ -156,7 +154,7 @@ static struct at91_udc_data __initdata portuxg20_udc_data = { | |||
| 156 | .pullup_pin = 0, /* pull-up driven by UDC */ | 154 | .pullup_pin = 0, /* pull-up driven by UDC */ |
| 157 | }; | 155 | }; |
| 158 | 156 | ||
| 159 | static struct at91_udc_data __initdata stamp9g20_udc_data = { | 157 | static struct at91_udc_data __initdata stamp9g20evb_udc_data = { |
| 160 | .vbus_pin = AT91_PIN_PA22, | 158 | .vbus_pin = AT91_PIN_PA22, |
| 161 | .pullup_pin = 0, /* pull-up driven by UDC */ | 159 | .pullup_pin = 0, /* pull-up driven by UDC */ |
| 162 | }; | 160 | }; |
| @@ -190,7 +188,7 @@ static struct gpio_led portuxg20_leds[] = { | |||
| 190 | } | 188 | } |
| 191 | }; | 189 | }; |
| 192 | 190 | ||
| 193 | static struct gpio_led stamp9g20_leds[] = { | 191 | static struct gpio_led stamp9g20evb_leds[] = { |
| 194 | { | 192 | { |
| 195 | .name = "D8", | 193 | .name = "D8", |
| 196 | .gpio = AT91_PIN_PB18, | 194 | .gpio = AT91_PIN_PB18, |
| @@ -250,7 +248,7 @@ void add_w1(void) | |||
| 250 | } | 248 | } |
| 251 | 249 | ||
| 252 | 250 | ||
| 253 | static void __init generic_board_init(void) | 251 | void __init stamp9g20_board_init(void) |
| 254 | { | 252 | { |
| 255 | /* Serial */ | 253 | /* Serial */ |
| 256 | at91_add_device_serial(); | 254 | at91_add_device_serial(); |
| @@ -262,34 +260,40 @@ static void __init generic_board_init(void) | |||
| 262 | #else | 260 | #else |
| 263 | at91_add_device_mmc(0, &mmc_data); | 261 | at91_add_device_mmc(0, &mmc_data); |
| 264 | #endif | 262 | #endif |
| 265 | /* USB Host */ | ||
| 266 | at91_add_device_usbh(&usbh_data); | ||
| 267 | /* Ethernet */ | ||
| 268 | at91_add_device_eth(&macb_data); | ||
| 269 | /* I2C */ | ||
| 270 | at91_add_device_i2c(NULL, 0); | ||
| 271 | /* W1 */ | 263 | /* W1 */ |
| 272 | add_w1(); | 264 | add_w1(); |
| 273 | } | 265 | } |
| 274 | 266 | ||
| 275 | static void __init portuxg20_board_init(void) | 267 | static void __init portuxg20_board_init(void) |
| 276 | { | 268 | { |
| 277 | generic_board_init(); | 269 | stamp9g20_board_init(); |
| 278 | /* SPI */ | 270 | /* USB Host */ |
| 279 | at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices)); | 271 | at91_add_device_usbh(&usbh_data); |
| 280 | /* USB Device */ | 272 | /* USB Device */ |
| 281 | at91_add_device_udc(&portuxg20_udc_data); | 273 | at91_add_device_udc(&portuxg20_udc_data); |
| 274 | /* Ethernet */ | ||
| 275 | at91_add_device_eth(&macb_data); | ||
| 276 | /* I2C */ | ||
| 277 | at91_add_device_i2c(NULL, 0); | ||
| 278 | /* SPI */ | ||
| 279 | at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices)); | ||
| 282 | /* LEDs */ | 280 | /* LEDs */ |
| 283 | at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds)); | 281 | at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds)); |
| 284 | } | 282 | } |
| 285 | 283 | ||
| 286 | static void __init stamp9g20_board_init(void) | 284 | static void __init stamp9g20evb_board_init(void) |
| 287 | { | 285 | { |
| 288 | generic_board_init(); | 286 | stamp9g20_board_init(); |
| 287 | /* USB Host */ | ||
| 288 | at91_add_device_usbh(&usbh_data); | ||
| 289 | /* USB Device */ | 289 | /* USB Device */ |
| 290 | at91_add_device_udc(&stamp9g20_udc_data); | 290 | at91_add_device_udc(&stamp9g20evb_udc_data); |
| 291 | /* Ethernet */ | ||
| 292 | at91_add_device_eth(&macb_data); | ||
| 293 | /* I2C */ | ||
| 294 | at91_add_device_i2c(NULL, 0); | ||
| 291 | /* LEDs */ | 295 | /* LEDs */ |
| 292 | at91_gpio_leds(stamp9g20_leds, ARRAY_SIZE(stamp9g20_leds)); | 296 | at91_gpio_leds(stamp9g20evb_leds, ARRAY_SIZE(stamp9g20evb_leds)); |
| 293 | } | 297 | } |
| 294 | 298 | ||
| 295 | MACHINE_START(PORTUXG20, "taskit PortuxG20") | 299 | MACHINE_START(PORTUXG20, "taskit PortuxG20") |
| @@ -305,7 +309,7 @@ MACHINE_START(STAMP9G20, "taskit Stamp9G20") | |||
| 305 | /* Maintainer: taskit GmbH */ | 309 | /* Maintainer: taskit GmbH */ |
| 306 | .boot_params = AT91_SDRAM_BASE + 0x100, | 310 | .boot_params = AT91_SDRAM_BASE + 0x100, |
| 307 | .timer = &at91sam926x_timer, | 311 | .timer = &at91sam926x_timer, |
| 308 | .map_io = stamp9g20_map_io, | 312 | .map_io = stamp9g20evb_map_io, |
| 309 | .init_irq = init_irq, | 313 | .init_irq = init_irq, |
| 310 | .init_machine = stamp9g20_board_init, | 314 | .init_machine = stamp9g20evb_board_init, |
| 311 | MACHINE_END | 315 | MACHINE_END |
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 7525cee3983..9113da6845f 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c | |||
| @@ -658,7 +658,7 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock) | |||
| 658 | /* Now set uhpck values */ | 658 | /* Now set uhpck values */ |
| 659 | uhpck.parent = &utmi_clk; | 659 | uhpck.parent = &utmi_clk; |
| 660 | uhpck.pmc_mask = AT91SAM926x_PMC_UHP; | 660 | uhpck.pmc_mask = AT91SAM926x_PMC_UHP; |
| 661 | uhpck.rate_hz = utmi_clk.parent->rate_hz; | 661 | uhpck.rate_hz = utmi_clk.rate_hz; |
| 662 | uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8); | 662 | uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8); |
| 663 | } | 663 | } |
| 664 | 664 | ||
diff --git a/arch/arm/mach-at91/include/mach/stamp9g20.h b/arch/arm/mach-at91/include/mach/stamp9g20.h new file mode 100644 index 00000000000..6120f9c46d5 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/stamp9g20.h | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | #ifndef __MACH_STAMP9G20_H | ||
| 2 | #define __MACH_STAMP9G20_H | ||
| 3 | |||
| 4 | void stamp9g20_map_io(void); | ||
| 5 | void stamp9g20_board_init(void); | ||
| 6 | |||
| 7 | #endif | ||
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c index daf3993349f..2e3dd08ccc3 100644 --- a/arch/arm/mach-mmp/mmp2.c +++ b/arch/arm/mach-mmp/mmp2.c | |||
| @@ -126,7 +126,6 @@ static APBC_CLK(twsi3, MMP2_TWSI3, 0, 26000000); | |||
| 126 | static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000); | 126 | static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000); |
| 127 | static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000); | 127 | static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000); |
| 128 | static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000); | 128 | static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000); |
| 129 | static APBC_CLK(rtc, MMP2_RTC, 0, 32768); | ||
| 130 | 129 | ||
| 131 | static APMU_CLK(nand, NAND, 0xbf, 100000000); | 130 | static APMU_CLK(nand, NAND, 0xbf, 100000000); |
| 132 | 131 | ||
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index 86c9b210295..9db9203667d 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c | |||
| @@ -216,7 +216,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = { | |||
| 216 | { | 216 | { |
| 217 | .name = "wl1271", | 217 | .name = "wl1271", |
| 218 | .mmc = 3, | 218 | .mmc = 3, |
| 219 | .caps = MMC_CAP_4_BIT_DATA, | 219 | .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, |
| 220 | .gpio_wp = -EINVAL, | 220 | .gpio_wp = -EINVAL, |
| 221 | .gpio_cd = -EINVAL, | 221 | .gpio_cd = -EINVAL, |
| 222 | .nonremovable = true, | 222 | .nonremovable = true, |
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 40562ddd3ee..a1939b1e6f8 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c | |||
| @@ -297,7 +297,7 @@ static int __init _omap2_init_reprogram_sdrc(void) | |||
| 297 | return 0; | 297 | return 0; |
| 298 | 298 | ||
| 299 | dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck"); | 299 | dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck"); |
| 300 | if (!dpll3_m2_ck) | 300 | if (IS_ERR(dpll3_m2_ck)) |
| 301 | return -EINVAL; | 301 | return -EINVAL; |
| 302 | 302 | ||
| 303 | rate = clk_get_rate(dpll3_m2_ck); | 303 | rate = clk_get_rate(dpll3_m2_ck); |
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 5e81517a7af..a8afb610c7d 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c | |||
| @@ -161,6 +161,23 @@ void omap2_pm_dump(int mode, int resume, unsigned int us) | |||
| 161 | printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val); | 161 | printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val); |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds) | ||
| 165 | { | ||
| 166 | u32 tick_rate, cycles; | ||
| 167 | |||
| 168 | if (!seconds && !milliseconds) | ||
| 169 | return; | ||
| 170 | |||
| 171 | tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); | ||
| 172 | cycles = tick_rate * seconds + tick_rate * milliseconds / 1000; | ||
| 173 | omap_dm_timer_stop(gptimer_wakeup); | ||
| 174 | omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); | ||
| 175 | |||
| 176 | pr_info("PM: Resume timer in %u.%03u secs" | ||
| 177 | " (%d ticks at %d ticks/sec.)\n", | ||
| 178 | seconds, milliseconds, cycles, tick_rate); | ||
| 179 | } | ||
| 180 | |||
| 164 | #ifdef CONFIG_DEBUG_FS | 181 | #ifdef CONFIG_DEBUG_FS |
| 165 | #include <linux/debugfs.h> | 182 | #include <linux/debugfs.h> |
| 166 | #include <linux/seq_file.h> | 183 | #include <linux/seq_file.h> |
| @@ -354,23 +371,6 @@ void pm_dbg_update_time(struct powerdomain *pwrdm, int prev) | |||
| 354 | pwrdm->timer = t; | 371 | pwrdm->timer = t; |
| 355 | } | 372 | } |
| 356 | 373 | ||
| 357 | void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds) | ||
| 358 | { | ||
| 359 | u32 tick_rate, cycles; | ||
| 360 | |||
| 361 | if (!seconds && !milliseconds) | ||
| 362 | return; | ||
| 363 | |||
| 364 | tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); | ||
| 365 | cycles = tick_rate * seconds + tick_rate * milliseconds / 1000; | ||
| 366 | omap_dm_timer_stop(gptimer_wakeup); | ||
| 367 | omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); | ||
| 368 | |||
| 369 | pr_info("PM: Resume timer in %u.%03u secs" | ||
| 370 | " (%d ticks at %d ticks/sec.)\n", | ||
| 371 | seconds, milliseconds, cycles, tick_rate); | ||
| 372 | } | ||
| 373 | |||
| 374 | static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user) | 374 | static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user) |
| 375 | { | 375 | { |
| 376 | struct seq_file *s = (struct seq_file *)user; | 376 | struct seq_file *s = (struct seq_file *)user; |
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index c85923e56b8..aaeea49b9bd 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c | |||
| @@ -53,6 +53,19 @@ | |||
| 53 | #include <plat/powerdomain.h> | 53 | #include <plat/powerdomain.h> |
| 54 | #include <plat/clockdomain.h> | 54 | #include <plat/clockdomain.h> |
| 55 | 55 | ||
| 56 | #ifdef CONFIG_SUSPEND | ||
| 57 | static suspend_state_t suspend_state = PM_SUSPEND_ON; | ||
| 58 | static inline bool is_suspending(void) | ||
| 59 | { | ||
| 60 | return (suspend_state != PM_SUSPEND_ON); | ||
| 61 | } | ||
| 62 | #else | ||
| 63 | static inline bool is_suspending(void) | ||
| 64 | { | ||
| 65 | return false; | ||
| 66 | } | ||
| 67 | #endif | ||
| 68 | |||
| 56 | static void (*omap2_sram_idle)(void); | 69 | static void (*omap2_sram_idle)(void); |
| 57 | static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl, | 70 | static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl, |
| 58 | void __iomem *sdrc_power); | 71 | void __iomem *sdrc_power); |
| @@ -120,8 +133,9 @@ static void omap2_enter_full_retention(void) | |||
| 120 | goto no_sleep; | 133 | goto no_sleep; |
| 121 | 134 | ||
| 122 | /* Block console output in case it is on one of the OMAP UARTs */ | 135 | /* Block console output in case it is on one of the OMAP UARTs */ |
| 123 | if (try_acquire_console_sem()) | 136 | if (!is_suspending()) |
| 124 | goto no_sleep; | 137 | if (try_acquire_console_sem()) |
| 138 | goto no_sleep; | ||
| 125 | 139 | ||
| 126 | omap_uart_prepare_idle(0); | 140 | omap_uart_prepare_idle(0); |
| 127 | omap_uart_prepare_idle(1); | 141 | omap_uart_prepare_idle(1); |
| @@ -136,7 +150,8 @@ static void omap2_enter_full_retention(void) | |||
| 136 | omap_uart_resume_idle(1); | 150 | omap_uart_resume_idle(1); |
| 137 | omap_uart_resume_idle(0); | 151 | omap_uart_resume_idle(0); |
| 138 | 152 | ||
| 139 | release_console_sem(); | 153 | if (!is_suspending()) |
| 154 | release_console_sem(); | ||
| 140 | 155 | ||
| 141 | no_sleep: | 156 | no_sleep: |
| 142 | if (omap2_pm_debug) { | 157 | if (omap2_pm_debug) { |
| @@ -284,6 +299,12 @@ out: | |||
| 284 | local_irq_enable(); | 299 | local_irq_enable(); |
| 285 | } | 300 | } |
| 286 | 301 | ||
| 302 | static int omap2_pm_begin(suspend_state_t state) | ||
| 303 | { | ||
| 304 | suspend_state = state; | ||
| 305 | return 0; | ||
| 306 | } | ||
| 307 | |||
| 287 | static int omap2_pm_prepare(void) | 308 | static int omap2_pm_prepare(void) |
| 288 | { | 309 | { |
| 289 | /* We cannot sleep in idle until we have resumed */ | 310 | /* We cannot sleep in idle until we have resumed */ |
| @@ -333,10 +354,17 @@ static void omap2_pm_finish(void) | |||
| 333 | enable_hlt(); | 354 | enable_hlt(); |
| 334 | } | 355 | } |
| 335 | 356 | ||
| 357 | static void omap2_pm_end(void) | ||
| 358 | { | ||
| 359 | suspend_state = PM_SUSPEND_ON; | ||
| 360 | } | ||
| 361 | |||
| 336 | static struct platform_suspend_ops omap_pm_ops = { | 362 | static struct platform_suspend_ops omap_pm_ops = { |
| 363 | .begin = omap2_pm_begin, | ||
| 337 | .prepare = omap2_pm_prepare, | 364 | .prepare = omap2_pm_prepare, |
| 338 | .enter = omap2_pm_enter, | 365 | .enter = omap2_pm_enter, |
| 339 | .finish = omap2_pm_finish, | 366 | .finish = omap2_pm_finish, |
| 367 | .end = omap2_pm_end, | ||
| 340 | .valid = suspend_valid_only_mem, | 368 | .valid = suspend_valid_only_mem, |
| 341 | }; | 369 | }; |
| 342 | 370 | ||
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 0ec8a04b747..648b8c50d02 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
| @@ -50,6 +50,19 @@ | |||
| 50 | #include "sdrc.h" | 50 | #include "sdrc.h" |
| 51 | #include "control.h" | 51 | #include "control.h" |
| 52 | 52 | ||
| 53 | #ifdef CONFIG_SUSPEND | ||
| 54 | static suspend_state_t suspend_state = PM_SUSPEND_ON; | ||
| 55 | static inline bool is_suspending(void) | ||
| 56 | { | ||
| 57 | return (suspend_state != PM_SUSPEND_ON); | ||
| 58 | } | ||
| 59 | #else | ||
| 60 | static inline bool is_suspending(void) | ||
| 61 | { | ||
| 62 | return false; | ||
| 63 | } | ||
| 64 | #endif | ||
| 65 | |||
| 53 | /* Scratchpad offsets */ | 66 | /* Scratchpad offsets */ |
| 54 | #define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4 | 67 | #define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4 |
| 55 | #define OMAP343X_TABLE_VALUE_OFFSET 0xc0 | 68 | #define OMAP343X_TABLE_VALUE_OFFSET 0xc0 |
| @@ -387,10 +400,11 @@ void omap_sram_idle(void) | |||
| 387 | } | 400 | } |
| 388 | 401 | ||
| 389 | /* Block console output in case it is on one of the OMAP UARTs */ | 402 | /* Block console output in case it is on one of the OMAP UARTs */ |
| 390 | if (per_next_state < PWRDM_POWER_ON || | 403 | if (!is_suspending()) |
| 391 | core_next_state < PWRDM_POWER_ON) | 404 | if (per_next_state < PWRDM_POWER_ON || |
| 392 | if (try_acquire_console_sem()) | 405 | core_next_state < PWRDM_POWER_ON) |
| 393 | goto console_still_active; | 406 | if (try_acquire_console_sem()) |
| 407 | goto console_still_active; | ||
| 394 | 408 | ||
| 395 | /* PER */ | 409 | /* PER */ |
| 396 | if (per_next_state < PWRDM_POWER_ON) { | 410 | if (per_next_state < PWRDM_POWER_ON) { |
| @@ -470,7 +484,8 @@ void omap_sram_idle(void) | |||
| 470 | omap_uart_resume_idle(3); | 484 | omap_uart_resume_idle(3); |
| 471 | } | 485 | } |
| 472 | 486 | ||
| 473 | release_console_sem(); | 487 | if (!is_suspending()) |
| 488 | release_console_sem(); | ||
| 474 | 489 | ||
| 475 | console_still_active: | 490 | console_still_active: |
| 476 | /* Disable IO-PAD and IO-CHAIN wakeup */ | 491 | /* Disable IO-PAD and IO-CHAIN wakeup */ |
| @@ -514,8 +529,6 @@ out: | |||
| 514 | } | 529 | } |
| 515 | 530 | ||
| 516 | #ifdef CONFIG_SUSPEND | 531 | #ifdef CONFIG_SUSPEND |
| 517 | static suspend_state_t suspend_state; | ||
| 518 | |||
| 519 | static int omap3_pm_prepare(void) | 532 | static int omap3_pm_prepare(void) |
| 520 | { | 533 | { |
| 521 | disable_hlt(); | 534 | disable_hlt(); |
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index 298a22a754e..f81acee4738 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h | |||
| @@ -243,13 +243,14 @@ | |||
| 243 | #define OMAP24XX_EN_GPT1_MASK (1 << 0) | 243 | #define OMAP24XX_EN_GPT1_MASK (1 << 0) |
| 244 | 244 | ||
| 245 | /* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */ | 245 | /* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */ |
| 246 | #define OMAP24XX_ST_GPIOS_SHIFT (1 << 2) | 246 | #define OMAP24XX_ST_GPIOS_SHIFT 2 |
| 247 | #define OMAP24XX_ST_GPIOS_MASK 2 | 247 | #define OMAP24XX_ST_GPIOS_MASK (1 << 2) |
| 248 | #define OMAP24XX_ST_GPT1_SHIFT (1 << 0) | 248 | #define OMAP24XX_ST_GPT1_SHIFT 0 |
| 249 | #define OMAP24XX_ST_GPT1_MASK 0 | 249 | #define OMAP24XX_ST_GPT1_MASK (1 << 0) |
| 250 | 250 | ||
| 251 | /* CM_IDLEST_MDM and PM_WKST_MDM shared bits */ | 251 | /* CM_IDLEST_MDM and PM_WKST_MDM shared bits */ |
| 252 | #define OMAP2430_ST_MDM_SHIFT (1 << 0) | 252 | #define OMAP2430_ST_MDM_SHIFT 0 |
| 253 | #define OMAP2430_ST_MDM_MASK (1 << 0) | ||
| 253 | 254 | ||
| 254 | 255 | ||
| 255 | /* 3430 register bits shared between CM & PRM registers */ | 256 | /* 3430 register bits shared between CM & PRM registers */ |
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index d2060a1d1d6..e5c9932b758 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c | |||
| @@ -241,7 +241,8 @@ static inline void palmtx_keys_init(void) {} | |||
| 241 | /****************************************************************************** | 241 | /****************************************************************************** |
| 242 | * NAND Flash | 242 | * NAND Flash |
| 243 | ******************************************************************************/ | 243 | ******************************************************************************/ |
| 244 | #if defined(CONFIG_MTD_NAND_GPIO) || defined(CONFIG_MTD_NAND_GPIO_MODULE) | 244 | #if defined(CONFIG_MTD_NAND_PLATFORM) || \ |
| 245 | defined(CONFIG_MTD_NAND_PLATFORM_MODULE) | ||
| 245 | static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd, | 246 | static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd, |
| 246 | unsigned int ctrl) | 247 | unsigned int ctrl) |
| 247 | { | 248 | { |
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 99fa688dfad..c96fa1b3f49 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S | |||
| @@ -203,6 +203,10 @@ ENTRY(v6_flush_kern_dcache_area) | |||
| 203 | * - end - virtual end address of region | 203 | * - end - virtual end address of region |
| 204 | */ | 204 | */ |
| 205 | v6_dma_inv_range: | 205 | v6_dma_inv_range: |
| 206 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
| 207 | ldrb r2, [r0] @ read for ownership | ||
| 208 | strb r2, [r0] @ write for ownership | ||
| 209 | #endif | ||
| 206 | tst r0, #D_CACHE_LINE_SIZE - 1 | 210 | tst r0, #D_CACHE_LINE_SIZE - 1 |
| 207 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | 211 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 |
| 208 | #ifdef HARVARD_CACHE | 212 | #ifdef HARVARD_CACHE |
| @@ -211,6 +215,10 @@ v6_dma_inv_range: | |||
| 211 | mcrne p15, 0, r0, c7, c11, 1 @ clean unified line | 215 | mcrne p15, 0, r0, c7, c11, 1 @ clean unified line |
| 212 | #endif | 216 | #endif |
| 213 | tst r1, #D_CACHE_LINE_SIZE - 1 | 217 | tst r1, #D_CACHE_LINE_SIZE - 1 |
| 218 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
| 219 | ldrneb r2, [r1, #-1] @ read for ownership | ||
| 220 | strneb r2, [r1, #-1] @ write for ownership | ||
| 221 | #endif | ||
| 214 | bic r1, r1, #D_CACHE_LINE_SIZE - 1 | 222 | bic r1, r1, #D_CACHE_LINE_SIZE - 1 |
| 215 | #ifdef HARVARD_CACHE | 223 | #ifdef HARVARD_CACHE |
| 216 | mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line | 224 | mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line |
| @@ -218,10 +226,6 @@ v6_dma_inv_range: | |||
| 218 | mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line | 226 | mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line |
| 219 | #endif | 227 | #endif |
| 220 | 1: | 228 | 1: |
| 221 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
| 222 | ldr r2, [r0] @ read for ownership | ||
| 223 | str r2, [r0] @ write for ownership | ||
| 224 | #endif | ||
| 225 | #ifdef HARVARD_CACHE | 229 | #ifdef HARVARD_CACHE |
| 226 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D line | 230 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D line |
| 227 | #else | 231 | #else |
| @@ -229,6 +233,10 @@ v6_dma_inv_range: | |||
| 229 | #endif | 233 | #endif |
| 230 | add r0, r0, #D_CACHE_LINE_SIZE | 234 | add r0, r0, #D_CACHE_LINE_SIZE |
| 231 | cmp r0, r1 | 235 | cmp r0, r1 |
| 236 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
| 237 | ldrlo r2, [r0] @ read for ownership | ||
| 238 | strlo r2, [r0] @ write for ownership | ||
| 239 | #endif | ||
| 232 | blo 1b | 240 | blo 1b |
| 233 | mov r0, #0 | 241 | mov r0, #0 |
| 234 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | 242 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer |
| @@ -263,12 +271,12 @@ v6_dma_clean_range: | |||
| 263 | * - end - virtual end address of region | 271 | * - end - virtual end address of region |
| 264 | */ | 272 | */ |
| 265 | ENTRY(v6_dma_flush_range) | 273 | ENTRY(v6_dma_flush_range) |
| 266 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | ||
| 267 | 1: | ||
| 268 | #ifdef CONFIG_DMA_CACHE_RWFO | 274 | #ifdef CONFIG_DMA_CACHE_RWFO |
| 269 | ldr r2, [r0] @ read for ownership | 275 | ldrb r2, [r0] @ read for ownership |
| 270 | str r2, [r0] @ write for ownership | 276 | strb r2, [r0] @ write for ownership |
| 271 | #endif | 277 | #endif |
| 278 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | ||
| 279 | 1: | ||
| 272 | #ifdef HARVARD_CACHE | 280 | #ifdef HARVARD_CACHE |
| 273 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line | 281 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line |
| 274 | #else | 282 | #else |
| @@ -276,6 +284,10 @@ ENTRY(v6_dma_flush_range) | |||
| 276 | #endif | 284 | #endif |
| 277 | add r0, r0, #D_CACHE_LINE_SIZE | 285 | add r0, r0, #D_CACHE_LINE_SIZE |
| 278 | cmp r0, r1 | 286 | cmp r0, r1 |
| 287 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
| 288 | ldrlob r2, [r0] @ read for ownership | ||
| 289 | strlob r2, [r0] @ write for ownership | ||
| 290 | #endif | ||
| 279 | blo 1b | 291 | blo 1b |
| 280 | mov r0, #0 | 292 | mov r0, #0 |
| 281 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | 293 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer |
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index a3ebf7a4f49..6136e68ce95 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S | |||
| @@ -173,15 +173,22 @@ ENTRY(v7_coherent_user_range) | |||
| 173 | UNWIND(.fnstart ) | 173 | UNWIND(.fnstart ) |
| 174 | dcache_line_size r2, r3 | 174 | dcache_line_size r2, r3 |
| 175 | sub r3, r2, #1 | 175 | sub r3, r2, #1 |
| 176 | bic r0, r0, r3 | 176 | bic r12, r0, r3 |
| 177 | 1: | 177 | 1: |
| 178 | USER( mcr p15, 0, r0, c7, c11, 1 ) @ clean D line to the point of unification | 178 | USER( mcr p15, 0, r12, c7, c11, 1 ) @ clean D line to the point of unification |
| 179 | add r12, r12, r2 | ||
| 180 | cmp r12, r1 | ||
| 181 | blo 1b | ||
| 179 | dsb | 182 | dsb |
| 180 | USER( mcr p15, 0, r0, c7, c5, 1 ) @ invalidate I line | 183 | icache_line_size r2, r3 |
| 181 | add r0, r0, r2 | 184 | sub r3, r2, #1 |
| 185 | bic r12, r0, r3 | ||
| 182 | 2: | 186 | 2: |
| 183 | cmp r0, r1 | 187 | USER( mcr p15, 0, r12, c7, c5, 1 ) @ invalidate I line |
| 184 | blo 1b | 188 | add r12, r12, r2 |
| 189 | cmp r12, r1 | ||
| 190 | blo 2b | ||
| 191 | 3: | ||
| 185 | mov r0, #0 | 192 | mov r0, #0 |
| 186 | ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable | 193 | ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable |
| 187 | ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB | 194 | ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB |
| @@ -194,10 +201,10 @@ ENTRY(v7_coherent_user_range) | |||
| 194 | * isn't mapped, just try the next page. | 201 | * isn't mapped, just try the next page. |
| 195 | */ | 202 | */ |
| 196 | 9001: | 203 | 9001: |
| 197 | mov r0, r0, lsr #12 | 204 | mov r12, r12, lsr #12 |
| 198 | mov r0, r0, lsl #12 | 205 | mov r12, r12, lsl #12 |
| 199 | add r0, r0, #4096 | 206 | add r12, r12, #4096 |
| 200 | b 2b | 207 | b 3b |
| 201 | UNWIND(.fnend ) | 208 | UNWIND(.fnend ) |
| 202 | ENDPROC(v7_coherent_kern_range) | 209 | ENDPROC(v7_coherent_kern_range) |
| 203 | ENDPROC(v7_coherent_user_range) | 210 | ENDPROC(v7_coherent_user_range) |
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index 7d63beaf974..b795afd0a2c 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S | |||
| @@ -61,17 +61,27 @@ | |||
| 61 | .endm | 61 | .endm |
| 62 | 62 | ||
| 63 | /* | 63 | /* |
| 64 | * cache_line_size - get the cache line size from the CSIDR register | 64 | * dcache_line_size - get the minimum D-cache line size from the CTR register |
| 65 | * (available on ARMv7+). It assumes that the CSSR register was configured | 65 | * on ARMv7. |
| 66 | * to access the L1 data cache CSIDR. | ||
| 67 | */ | 66 | */ |
| 68 | .macro dcache_line_size, reg, tmp | 67 | .macro dcache_line_size, reg, tmp |
| 69 | mrc p15, 1, \tmp, c0, c0, 0 @ read CSIDR | 68 | mrc p15, 0, \tmp, c0, c0, 1 @ read ctr |
| 70 | and \tmp, \tmp, #7 @ cache line size encoding | 69 | lsr \tmp, \tmp, #16 |
| 71 | mov \reg, #16 @ size offset | 70 | and \tmp, \tmp, #0xf @ cache line size encoding |
| 71 | mov \reg, #4 @ bytes per word | ||
| 72 | mov \reg, \reg, lsl \tmp @ actual cache line size | 72 | mov \reg, \reg, lsl \tmp @ actual cache line size |
| 73 | .endm | 73 | .endm |
| 74 | 74 | ||
| 75 | /* | ||
| 76 | * icache_line_size - get the minimum I-cache line size from the CTR register | ||
| 77 | * on ARMv7. | ||
| 78 | */ | ||
| 79 | .macro icache_line_size, reg, tmp | ||
| 80 | mrc p15, 0, \tmp, c0, c0, 1 @ read ctr | ||
| 81 | and \tmp, \tmp, #0xf @ cache line size encoding | ||
| 82 | mov \reg, #4 @ bytes per word | ||
| 83 | mov \reg, \reg, lsl \tmp @ actual cache line size | ||
| 84 | .endm | ||
| 75 | 85 | ||
| 76 | /* | 86 | /* |
| 77 | * Sanity check the PTE configuration for the code below - which makes | 87 | * Sanity check the PTE configuration for the code below - which makes |
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c index 155fe43a672..8722a136f3a 100644 --- a/arch/arm/plat-omap/counter_32k.c +++ b/arch/arm/plat-omap/counter_32k.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
| 17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
| 18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
| 19 | #include <linux/err.h> | ||
| 19 | 20 | ||
| 20 | #include <plat/common.h> | 21 | #include <plat/common.h> |
| 21 | #include <plat/board.h> | 22 | #include <plat/board.h> |
| @@ -164,7 +165,7 @@ static int __init omap_init_clocksource_32k(void) | |||
| 164 | return -ENODEV; | 165 | return -ENODEV; |
| 165 | 166 | ||
| 166 | sync_32k_ick = clk_get(NULL, "omap_32ksync_ick"); | 167 | sync_32k_ick = clk_get(NULL, "omap_32ksync_ick"); |
| 167 | if (sync_32k_ick) | 168 | if (!IS_ERR(sync_32k_ick)) |
| 168 | clk_enable(sync_32k_ick); | 169 | clk_enable(sync_32k_ick); |
| 169 | 170 | ||
| 170 | clocksource_32k.mult = clocksource_hz2mult(32768, | 171 | clocksource_32k.mult = clocksource_hz2mult(32768, |
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index e2c8eebe6b3..74dac419d32 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c | |||
| @@ -166,7 +166,7 @@ static void __init omap_detect_sram(void) | |||
| 166 | cpu_is_omap1710()) | 166 | cpu_is_omap1710()) |
| 167 | omap_sram_size = 0x4000; /* 16K */ | 167 | omap_sram_size = 0x4000; /* 16K */ |
| 168 | else if (cpu_is_omap1611()) | 168 | else if (cpu_is_omap1611()) |
| 169 | omap_sram_size = 0x3e800; /* 250K */ | 169 | omap_sram_size = SZ_256K; |
| 170 | else { | 170 | else { |
| 171 | printk(KERN_ERR "Could not detect SRAM size\n"); | 171 | printk(KERN_ERR "Could not detect SRAM size\n"); |
| 172 | omap_sram_size = 0x4000; | 172 | omap_sram_size = 0x4000; |
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 55590a4d87c..2fea897ebeb 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | # | 12 | # |
| 13 | # http://www.arm.linux.org.uk/developer/machines/?action=new | 13 | # http://www.arm.linux.org.uk/developer/machines/?action=new |
| 14 | # | 14 | # |
| 15 | # Last update: Thu Sep 9 22:43:01 2010 | 15 | # Last update: Sun Dec 12 23:24:27 2010 |
| 16 | # | 16 | # |
| 17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number | 17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number |
| 18 | # | 18 | # |
| @@ -2321,7 +2321,7 @@ mx31txtr MACH_MX31TXTR MX31TXTR 2332 | |||
| 2321 | u380 MACH_U380 U380 2333 | 2321 | u380 MACH_U380 U380 2333 |
| 2322 | oamp3_hualu MACH_HUALU_BOARD HUALU_BOARD 2334 | 2322 | oamp3_hualu MACH_HUALU_BOARD HUALU_BOARD 2334 |
| 2323 | npcmx50 MACH_NPCMX50 NPCMX50 2335 | 2323 | npcmx50 MACH_NPCMX50 NPCMX50 2335 |
| 2324 | mx51_lange51 MACH_MX51_LANGE51 MX51_LANGE51 2336 | 2324 | mx51_efikamx MACH_MX51_EFIKAMX MX51_EFIKAMX 2336 |
| 2325 | mx51_lange52 MACH_MX51_LANGE52 MX51_LANGE52 2337 | 2325 | mx51_lange52 MACH_MX51_LANGE52 MX51_LANGE52 2337 |
| 2326 | riom MACH_RIOM RIOM 2338 | 2326 | riom MACH_RIOM RIOM 2338 |
| 2327 | comcas MACH_COMCAS COMCAS 2339 | 2327 | comcas MACH_COMCAS COMCAS 2339 |
| @@ -2355,7 +2355,7 @@ at91sam9263cs MACH_AT91SAM9263CS AT91SAM9263CS 2366 | |||
| 2355 | csb732 MACH_CSB732 CSB732 2367 | 2355 | csb732 MACH_CSB732 CSB732 2367 |
| 2356 | u8500 MACH_U8500 U8500 2368 | 2356 | u8500 MACH_U8500 U8500 2368 |
| 2357 | huqiu MACH_HUQIU HUQIU 2369 | 2357 | huqiu MACH_HUQIU HUQIU 2369 |
| 2358 | mx51_kunlun MACH_MX51_KUNLUN MX51_KUNLUN 2370 | 2358 | mx51_efikasb MACH_MX51_EFIKASB MX51_EFIKASB 2370 |
| 2359 | pmt1g MACH_PMT1G PMT1G 2371 | 2359 | pmt1g MACH_PMT1G PMT1G 2371 |
| 2360 | htcelf MACH_HTCELF HTCELF 2372 | 2360 | htcelf MACH_HTCELF HTCELF 2372 |
| 2361 | armadillo420 MACH_ARMADILLO420 ARMADILLO420 2373 | 2361 | armadillo420 MACH_ARMADILLO420 ARMADILLO420 2373 |
| @@ -2971,7 +2971,7 @@ premierwave_en MACH_PREMIERWAVE_EN PREMIERWAVE_EN 2985 | |||
| 2971 | wasabi MACH_WASABI WASABI 2986 | 2971 | wasabi MACH_WASABI WASABI 2986 |
| 2972 | vivow MACH_VIVOW VIVOW 2987 | 2972 | vivow MACH_VIVOW VIVOW 2987 |
| 2973 | mx50_rdp MACH_MX50_RDP MX50_RDP 2988 | 2973 | mx50_rdp MACH_MX50_RDP MX50_RDP 2988 |
| 2974 | universal MACH_UNIVERSAL UNIVERSAL 2989 | 2974 | universal_c210 MACH_UNIVERSAL_C210 UNIVERSAL_C210 2989 |
| 2975 | real6410 MACH_REAL6410 REAL6410 2990 | 2975 | real6410 MACH_REAL6410 REAL6410 2990 |
| 2976 | spx_sakura MACH_SPX_SAKURA SPX_SAKURA 2991 | 2976 | spx_sakura MACH_SPX_SAKURA SPX_SAKURA 2991 |
| 2977 | ij3k_2440 MACH_IJ3K_2440 IJ3K_2440 2992 | 2977 | ij3k_2440 MACH_IJ3K_2440 IJ3K_2440 2992 |
| @@ -3044,3 +3044,178 @@ harvest_desoto MACH_HARVEST_DESOTO HARVEST_DESOTO 3059 | |||
| 3044 | msm8x60_qrdc MACH_MSM8X60_QRDC MSM8X60_QRDC 3060 | 3044 | msm8x60_qrdc MACH_MSM8X60_QRDC MSM8X60_QRDC 3060 |
| 3045 | spear900 MACH_SPEAR900 SPEAR900 3061 | 3045 | spear900 MACH_SPEAR900 SPEAR900 3061 |
| 3046 | pcontrol_g20 MACH_PCONTROL_G20 PCONTROL_G20 3062 | 3046 | pcontrol_g20 MACH_PCONTROL_G20 PCONTROL_G20 3062 |
| 3047 | rdstor MACH_RDSTOR RDSTOR 3063 | ||
| 3048 | usdloader MACH_USDLOADER USDLOADER 3064 | ||
| 3049 | tsoploader MACH_TSOPLOADER TSOPLOADER 3065 | ||
| 3050 | kronos MACH_KRONOS KRONOS 3066 | ||
| 3051 | ffcore MACH_FFCORE FFCORE 3067 | ||
| 3052 | mone MACH_MONE MONE 3068 | ||
| 3053 | unit2s MACH_UNIT2S UNIT2S 3069 | ||
| 3054 | acer_a5 MACH_ACER_A5 ACER_A5 3070 | ||
| 3055 | etherpro_isp MACH_ETHERPRO_ISP ETHERPRO_ISP 3071 | ||
| 3056 | stretchs7000 MACH_STRETCHS7000 STRETCHS7000 3072 | ||
| 3057 | p87_smartsim MACH_P87_SMARTSIM P87_SMARTSIM 3073 | ||
| 3058 | tulip MACH_TULIP TULIP 3074 | ||
| 3059 | sunflower MACH_SUNFLOWER SUNFLOWER 3075 | ||
| 3060 | rib MACH_RIB RIB 3076 | ||
| 3061 | clod MACH_CLOD CLOD 3077 | ||
| 3062 | rump MACH_RUMP RUMP 3078 | ||
| 3063 | tenderloin MACH_TENDERLOIN TENDERLOIN 3079 | ||
| 3064 | shortloin MACH_SHORTLOIN SHORTLOIN 3080 | ||
| 3065 | crespo MACH_CRESPO CRESPO 3081 | ||
| 3066 | antares MACH_ANTARES ANTARES 3082 | ||
| 3067 | wb40n MACH_WB40N WB40N 3083 | ||
| 3068 | herring MACH_HERRING HERRING 3084 | ||
| 3069 | naxy400 MACH_NAXY400 NAXY400 3085 | ||
| 3070 | naxy1200 MACH_NAXY1200 NAXY1200 3086 | ||
| 3071 | vpr200 MACH_VPR200 VPR200 3087 | ||
| 3072 | bug20 MACH_BUG20 BUG20 3088 | ||
| 3073 | goflexnet MACH_GOFLEXNET GOFLEXNET 3089 | ||
| 3074 | torbreck MACH_TORBRECK TORBRECK 3090 | ||
| 3075 | saarb_mg1 MACH_SAARB_MG1 SAARB_MG1 3091 | ||
| 3076 | callisto MACH_CALLISTO CALLISTO 3092 | ||
| 3077 | multhsu MACH_MULTHSU MULTHSU 3093 | ||
| 3078 | saluda MACH_SALUDA SALUDA 3094 | ||
| 3079 | pemp_omap3_apollo MACH_PEMP_OMAP3_APOLLO PEMP_OMAP3_APOLLO 3095 | ||
| 3080 | vc0718 MACH_VC0718 VC0718 3096 | ||
| 3081 | mvblx MACH_MVBLX MVBLX 3097 | ||
| 3082 | inhand_apeiron MACH_INHAND_APEIRON INHAND_APEIRON 3098 | ||
| 3083 | inhand_fury MACH_INHAND_FURY INHAND_FURY 3099 | ||
| 3084 | inhand_siren MACH_INHAND_SIREN INHAND_SIREN 3100 | ||
| 3085 | hdnvp MACH_HDNVP HDNVP 3101 | ||
| 3086 | softwinner MACH_SOFTWINNER SOFTWINNER 3102 | ||
| 3087 | prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103 | ||
| 3088 | nas6210 MACH_NAS6210 NAS6210 3104 | ||
| 3089 | unisdev MACH_UNISDEV UNISDEV 3105 | ||
| 3090 | sbca11 MACH_SBCA11 SBCA11 3106 | ||
| 3091 | saga MACH_SAGA SAGA 3107 | ||
| 3092 | ns_k330 MACH_NS_K330 NS_K330 3108 | ||
| 3093 | tanna MACH_TANNA TANNA 3109 | ||
| 3094 | imate8502 MACH_IMATE8502 IMATE8502 3110 | ||
| 3095 | aspen MACH_ASPEN ASPEN 3111 | ||
| 3096 | daintree_cwac MACH_DAINTREE_CWAC DAINTREE_CWAC 3112 | ||
| 3097 | zmx25 MACH_ZMX25 ZMX25 3113 | ||
| 3098 | maple1 MACH_MAPLE1 MAPLE1 3114 | ||
| 3099 | qsd8x72_surf MACH_QSD8X72_SURF QSD8X72_SURF 3115 | ||
| 3100 | qsd8x72_ffa MACH_QSD8X72_FFA QSD8X72_FFA 3116 | ||
| 3101 | abilene MACH_ABILENE ABILENE 3117 | ||
| 3102 | eigen_ttr MACH_EIGEN_TTR EIGEN_TTR 3118 | ||
| 3103 | iomega_ix2_200 MACH_IOMEGA_IX2_200 IOMEGA_IX2_200 3119 | ||
| 3104 | coretec_vcx7400 MACH_CORETEC_VCX7400 CORETEC_VCX7400 3120 | ||
| 3105 | santiago MACH_SANTIAGO SANTIAGO 3121 | ||
| 3106 | mx257sol MACH_MX257SOL MX257SOL 3122 | ||
| 3107 | strasbourg MACH_STRASBOURG STRASBOURG 3123 | ||
| 3108 | msm8x60_fluid MACH_MSM8X60_FLUID MSM8X60_FLUID 3124 | ||
| 3109 | smartqv5 MACH_SMARTQV5 SMARTQV5 3125 | ||
| 3110 | smartqv3 MACH_SMARTQV3 SMARTQV3 3126 | ||
| 3111 | smartqv7 MACH_SMARTQV7 SMARTQV7 3127 | ||
| 3112 | paz00 MACH_PAZ00 PAZ00 3128 | ||
| 3113 | acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129 | ||
| 3114 | htcwillow MACH_HTCWILLOW HTCWILLOW 3130 | ||
| 3115 | fwbd_0404 MACH_FWBD_0404 FWBD_0404 3131 | ||
| 3116 | hdgu MACH_HDGU HDGU 3132 | ||
| 3117 | pyramid MACH_PYRAMID PYRAMID 3133 | ||
| 3118 | epiphan MACH_EPIPHAN EPIPHAN 3134 | ||
| 3119 | omap_bender MACH_OMAP_BENDER OMAP_BENDER 3135 | ||
| 3120 | gurnard MACH_GURNARD GURNARD 3136 | ||
| 3121 | gtl_it5100 MACH_GTL_IT5100 GTL_IT5100 3137 | ||
| 3122 | bcm2708 MACH_BCM2708 BCM2708 3138 | ||
| 3123 | mx51_ggc MACH_MX51_GGC MX51_GGC 3139 | ||
| 3124 | sharespace MACH_SHARESPACE SHARESPACE 3140 | ||
| 3125 | haba_knx_explorer MACH_HABA_KNX_EXPLORER HABA_KNX_EXPLORER 3141 | ||
| 3126 | simtec_kirkmod MACH_SIMTEC_KIRKMOD SIMTEC_KIRKMOD 3142 | ||
| 3127 | crux MACH_CRUX CRUX 3143 | ||
| 3128 | mx51_bravo MACH_MX51_BRAVO MX51_BRAVO 3144 | ||
| 3129 | charon MACH_CHARON CHARON 3145 | ||
| 3130 | picocom3 MACH_PICOCOM3 PICOCOM3 3146 | ||
| 3131 | picocom4 MACH_PICOCOM4 PICOCOM4 3147 | ||
| 3132 | serrano MACH_SERRANO SERRANO 3148 | ||
| 3133 | doubleshot MACH_DOUBLESHOT DOUBLESHOT 3149 | ||
| 3134 | evsy MACH_EVSY EVSY 3150 | ||
| 3135 | huashan MACH_HUASHAN HUASHAN 3151 | ||
| 3136 | lausanne MACH_LAUSANNE LAUSANNE 3152 | ||
| 3137 | emerald MACH_EMERALD EMERALD 3153 | ||
| 3138 | tqma35 MACH_TQMA35 TQMA35 3154 | ||
| 3139 | marvel MACH_MARVEL MARVEL 3155 | ||
| 3140 | manuae MACH_MANUAE MANUAE 3156 | ||
| 3141 | chacha MACH_CHACHA CHACHA 3157 | ||
| 3142 | lemon MACH_LEMON LEMON 3158 | ||
| 3143 | csc MACH_CSC CSC 3159 | ||
| 3144 | gira_knxip_router MACH_GIRA_KNXIP_ROUTER GIRA_KNXIP_ROUTER 3160 | ||
| 3145 | t20 MACH_T20 T20 3161 | ||
| 3146 | hdmini MACH_HDMINI HDMINI 3162 | ||
| 3147 | sciphone_g2 MACH_SCIPHONE_G2 SCIPHONE_G2 3163 | ||
| 3148 | express MACH_EXPRESS EXPRESS 3164 | ||
| 3149 | express_kt MACH_EXPRESS_KT EXPRESS_KT 3165 | ||
| 3150 | maximasp MACH_MAXIMASP MAXIMASP 3166 | ||
| 3151 | nitrogen_imx51 MACH_NITROGEN_IMX51 NITROGEN_IMX51 3167 | ||
| 3152 | nitrogen_imx53 MACH_NITROGEN_IMX53 NITROGEN_IMX53 3168 | ||
| 3153 | sunfire MACH_SUNFIRE SUNFIRE 3169 | ||
| 3154 | arowana MACH_AROWANA AROWANA 3170 | ||
| 3155 | tegra_daytona MACH_TEGRA_DAYTONA TEGRA_DAYTONA 3171 | ||
| 3156 | tegra_swordfish MACH_TEGRA_SWORDFISH TEGRA_SWORDFISH 3172 | ||
| 3157 | edison MACH_EDISON EDISON 3173 | ||
| 3158 | svp8500v1 MACH_SVP8500V1 SVP8500V1 3174 | ||
| 3159 | svp8500v2 MACH_SVP8500V2 SVP8500V2 3175 | ||
| 3160 | svp5500 MACH_SVP5500 SVP5500 3176 | ||
| 3161 | b5500 MACH_B5500 B5500 3177 | ||
| 3162 | s5500 MACH_S5500 S5500 3178 | ||
| 3163 | icon MACH_ICON ICON 3179 | ||
| 3164 | elephant MACH_ELEPHANT ELEPHANT 3180 | ||
| 3165 | msm8x60_fusion MACH_MSM8X60_FUSION MSM8X60_FUSION 3181 | ||
| 3166 | shooter MACH_SHOOTER SHOOTER 3182 | ||
| 3167 | spade_lte MACH_SPADE_LTE SPADE_LTE 3183 | ||
| 3168 | philhwani MACH_PHILHWANI PHILHWANI 3184 | ||
| 3169 | gsncomm MACH_GSNCOMM GSNCOMM 3185 | ||
| 3170 | strasbourg_a2 MACH_STRASBOURG_A2 STRASBOURG_A2 3186 | ||
| 3171 | mmm MACH_MMM MMM 3187 | ||
| 3172 | davinci_dm365_bv MACH_DAVINCI_DM365_BV DAVINCI_DM365_BV 3188 | ||
| 3173 | ag5evm MACH_AG5EVM AG5EVM 3189 | ||
| 3174 | sc575plc MACH_SC575PLC SC575PLC 3190 | ||
| 3175 | sc575hmi MACH_SC575IPC SC575IPC 3191 | ||
| 3176 | omap3_tdm3730 MACH_OMAP3_TDM3730 OMAP3_TDM3730 3192 | ||
| 3177 | g7 MACH_G7 G7 3193 | ||
| 3178 | top9000_eval MACH_TOP9000_EVAL TOP9000_EVAL 3194 | ||
| 3179 | top9000_su MACH_TOP9000_SU TOP9000_SU 3195 | ||
| 3180 | utm300 MACH_UTM300 UTM300 3196 | ||
| 3181 | tsunagi MACH_TSUNAGI TSUNAGI 3197 | ||
| 3182 | ts75xx MACH_TS75XX TS75XX 3198 | ||
| 3183 | msm8x60_fusn_ffa MACH_MSM8X60_FUSN_FFA MSM8X60_FUSN_FFA 3199 | ||
| 3184 | ts47xx MACH_TS47XX TS47XX 3200 | ||
| 3185 | da850_k5 MACH_DA850_K5 DA850_K5 3201 | ||
| 3186 | ax502 MACH_AX502 AX502 3202 | ||
| 3187 | igep0032 MACH_IGEP0032 IGEP0032 3203 | ||
| 3188 | antero MACH_ANTERO ANTERO 3204 | ||
| 3189 | synergy MACH_SYNERGY SYNERGY 3205 | ||
| 3190 | ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 | ||
| 3191 | wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 | ||
| 3192 | punica MACH_PUNICA PUNICA 3208 | ||
| 3193 | sbc_nt250 MACH_SBC_NT250 SBC_NT250 3209 | ||
| 3194 | mx27_wmultra MACH_MX27_WMULTRA MX27_WMULTRA 3210 | ||
| 3195 | mackerel MACH_MACKEREL MACKEREL 3211 | ||
| 3196 | fa9x27 MACH_FA9X27 FA9X27 3213 | ||
| 3197 | ns2816tb MACH_NS2816TB NS2816TB 3214 | ||
| 3198 | ns2816_ntpad MACH_NS2816_NTPAD NS2816_NTPAD 3215 | ||
| 3199 | ns2816_ntnb MACH_NS2816_NTNB NS2816_NTNB 3216 | ||
| 3200 | kaen MACH_KAEN KAEN 3217 | ||
| 3201 | nv1000 MACH_NV1000 NV1000 3218 | ||
| 3202 | nuc950ts MACH_NUC950TS NUC950TS 3219 | ||
| 3203 | nokia_rm680 MACH_NOKIA_RM680 NOKIA_RM680 3220 | ||
| 3204 | ast2200 MACH_AST2200 AST2200 3221 | ||
| 3205 | lead MACH_LEAD LEAD 3222 | ||
| 3206 | unino1 MACH_UNINO1 UNINO1 3223 | ||
| 3207 | greeco MACH_GREECO GREECO 3224 | ||
| 3208 | verdi MACH_VERDI VERDI 3225 | ||
| 3209 | dm6446_adbox MACH_DM6446_ADBOX DM6446_ADBOX 3226 | ||
| 3210 | quad_salsa MACH_QUAD_SALSA QUAD_SALSA 3227 | ||
| 3211 | abb_gma_1_1 MACH_ABB_GMA_1_1 ABB_GMA_1_1 3228 | ||
| 3212 | svcid MACH_SVCID SVCID 3229 | ||
| 3213 | msm8960_sim MACH_MSM8960_SIM MSM8960_SIM 3230 | ||
| 3214 | msm8960_rumi3 MACH_MSM8960_RUMI3 MSM8960_RUMI3 3231 | ||
| 3215 | icon_g MACH_ICON_G ICON_G 3232 | ||
| 3216 | mb3 MACH_MB3 MB3 3233 | ||
| 3217 | gsia18s MACH_GSIA18S GSIA18S 3234 | ||
| 3218 | pivicc MACH_PIVICC PIVICC 3235 | ||
| 3219 | pcm048 MACH_PCM048 PCM048 3236 | ||
| 3220 | dds MACH_DDS DDS 3237 | ||
| 3221 | chalten_xa1 MACH_CHALTEN_XA1 CHALTEN_XA1 3238 | ||
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 67a2fa2caa4..0a9b5b8b2a1 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
| @@ -19,6 +19,8 @@ config MIPS | |||
| 19 | select GENERIC_ATOMIC64 if !64BIT | 19 | select GENERIC_ATOMIC64 if !64BIT |
| 20 | select HAVE_DMA_ATTRS | 20 | select HAVE_DMA_ATTRS |
| 21 | select HAVE_DMA_API_DEBUG | 21 | select HAVE_DMA_API_DEBUG |
| 22 | select HAVE_GENERIC_HARDIRQS | ||
| 23 | select GENERIC_IRQ_PROBE | ||
| 22 | 24 | ||
| 23 | menu "Machine selection" | 25 | menu "Machine selection" |
| 24 | 26 | ||
| @@ -1664,6 +1666,28 @@ config PAGE_SIZE_64KB | |||
| 1664 | 1666 | ||
| 1665 | endchoice | 1667 | endchoice |
| 1666 | 1668 | ||
| 1669 | config FORCE_MAX_ZONEORDER | ||
| 1670 | int "Maximum zone order" | ||
| 1671 | range 13 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB | ||
| 1672 | default "13" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB | ||
| 1673 | range 12 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB | ||
| 1674 | default "12" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB | ||
| 1675 | range 11 64 | ||
| 1676 | default "11" | ||
| 1677 | help | ||
| 1678 | The kernel memory allocator divides physically contiguous memory | ||
| 1679 | blocks into "zones", where each zone is a power of two number of | ||
| 1680 | pages. This option selects the largest power of two that the kernel | ||
| 1681 | keeps in the memory allocator. If you need to allocate very large | ||
| 1682 | blocks of physically contiguous memory, then you may need to | ||
| 1683 | increase this value. | ||
| 1684 | |||
| 1685 | This config option is actually maximum order plus one. For example, | ||
| 1686 | a value of 11 means that the largest free memory block is 2^10 pages. | ||
| 1687 | |||
| 1688 | The page size is not necessarily 4KB. Keep this in mind | ||
| 1689 | when choosing a value for this option. | ||
| 1690 | |||
| 1667 | config BOARD_SCACHE | 1691 | config BOARD_SCACHE |
| 1668 | bool | 1692 | bool |
| 1669 | 1693 | ||
| @@ -1922,20 +1946,6 @@ config CPU_R4400_WORKAROUNDS | |||
| 1922 | bool | 1946 | bool |
| 1923 | 1947 | ||
| 1924 | # | 1948 | # |
| 1925 | # Use the generic interrupt handling code in kernel/irq/: | ||
| 1926 | # | ||
| 1927 | config GENERIC_HARDIRQS | ||
| 1928 | bool | ||
| 1929 | default y | ||
| 1930 | |||
| 1931 | config GENERIC_IRQ_PROBE | ||
| 1932 | bool | ||
| 1933 | default y | ||
| 1934 | |||
| 1935 | config IRQ_PER_CPU | ||
| 1936 | bool | ||
| 1937 | |||
| 1938 | # | ||
| 1939 | # - Highmem only makes sense for the 32-bit kernel. | 1949 | # - Highmem only makes sense for the 32-bit kernel. |
| 1940 | # - The current highmem code will only work properly on physically indexed | 1950 | # - The current highmem code will only work properly on physically indexed |
| 1941 | # caches such as R3000, SB1, R7000 or those that look like they're virtually | 1951 | # caches such as R3000, SB1, R7000 or those that look like they're virtually |
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index 3691630931d..9e7814db3d0 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | static void alchemy_8250_pm(struct uart_port *port, unsigned int state, | 27 | static void alchemy_8250_pm(struct uart_port *port, unsigned int state, |
| 28 | unsigned int old_state) | 28 | unsigned int old_state) |
| 29 | { | 29 | { |
| 30 | #ifdef CONFIG_SERIAL_8250 | ||
| 30 | switch (state) { | 31 | switch (state) { |
| 31 | case 0: | 32 | case 0: |
| 32 | if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) { | 33 | if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) { |
| @@ -49,6 +50,7 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state, | |||
| 49 | serial8250_do_pm(port, state, old_state); | 50 | serial8250_do_pm(port, state, old_state); |
| 50 | break; | 51 | break; |
| 51 | } | 52 | } |
| 53 | #endif | ||
| 52 | } | 54 | } |
| 53 | 55 | ||
| 54 | #define PORT(_base, _irq) \ | 56 | #define PORT(_base, _irq) \ |
diff --git a/arch/mips/alchemy/devboards/prom.c b/arch/mips/alchemy/devboards/prom.c index b30df5c97ad..baeb2138505 100644 --- a/arch/mips/alchemy/devboards/prom.c +++ b/arch/mips/alchemy/devboards/prom.c | |||
| @@ -54,10 +54,9 @@ void __init prom_init(void) | |||
| 54 | 54 | ||
| 55 | prom_init_cmdline(); | 55 | prom_init_cmdline(); |
| 56 | memsize_str = prom_getenv("memsize"); | 56 | memsize_str = prom_getenv("memsize"); |
| 57 | if (!memsize_str) | 57 | if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize)) |
| 58 | memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE; | 58 | memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE; |
| 59 | else | 59 | |
| 60 | strict_strtoul(memsize_str, 0, &memsize); | ||
| 61 | add_memory_region(0, memsize, BOOT_MEM_RAM); | 60 | add_memory_region(0, memsize, BOOT_MEM_RAM); |
| 62 | } | 61 | } |
| 63 | 62 | ||
diff --git a/arch/mips/ar7/clock.c b/arch/mips/ar7/clock.c index fc0e7154e8d..2ca4ada1c29 100644 --- a/arch/mips/ar7/clock.c +++ b/arch/mips/ar7/clock.c | |||
| @@ -239,12 +239,12 @@ static void tnetd7300_set_clock(u32 shift, struct tnetd7300_clock *clock, | |||
| 239 | calculate(base_clock, frequency, &prediv, &postdiv, &mul); | 239 | calculate(base_clock, frequency, &prediv, &postdiv, &mul); |
| 240 | 240 | ||
| 241 | writel(((prediv - 1) << PREDIV_SHIFT) | (postdiv - 1), &clock->ctrl); | 241 | writel(((prediv - 1) << PREDIV_SHIFT) | (postdiv - 1), &clock->ctrl); |
| 242 | msleep(1); | 242 | mdelay(1); |
| 243 | writel(4, &clock->pll); | 243 | writel(4, &clock->pll); |
| 244 | while (readl(&clock->pll) & PLL_STATUS) | 244 | while (readl(&clock->pll) & PLL_STATUS) |
| 245 | ; | 245 | ; |
| 246 | writel(((mul - 1) << MUL_SHIFT) | (0xff << 3) | 0x0e, &clock->pll); | 246 | writel(((mul - 1) << MUL_SHIFT) | (0xff << 3) | 0x0e, &clock->pll); |
| 247 | msleep(75); | 247 | mdelay(75); |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | static void __init tnetd7300_init_clocks(void) | 250 | static void __init tnetd7300_init_clocks(void) |
| @@ -456,7 +456,7 @@ void clk_put(struct clk *clk) | |||
| 456 | } | 456 | } |
| 457 | EXPORT_SYMBOL(clk_put); | 457 | EXPORT_SYMBOL(clk_put); |
| 458 | 458 | ||
| 459 | int __init ar7_init_clocks(void) | 459 | void __init ar7_init_clocks(void) |
| 460 | { | 460 | { |
| 461 | switch (ar7_chip_id()) { | 461 | switch (ar7_chip_id()) { |
| 462 | case AR7_CHIP_7100: | 462 | case AR7_CHIP_7100: |
| @@ -472,7 +472,4 @@ int __init ar7_init_clocks(void) | |||
| 472 | } | 472 | } |
| 473 | /* adjust vbus clock rate */ | 473 | /* adjust vbus clock rate */ |
| 474 | vbus_clk.rate = bus_clk.rate / 2; | 474 | vbus_clk.rate = bus_clk.rate / 2; |
| 475 | |||
| 476 | return 0; | ||
| 477 | } | 475 | } |
| 478 | arch_initcall(ar7_init_clocks); | ||
diff --git a/arch/mips/ar7/time.c b/arch/mips/ar7/time.c index 5fb8a013408..22c93213b23 100644 --- a/arch/mips/ar7/time.c +++ b/arch/mips/ar7/time.c | |||
| @@ -30,6 +30,9 @@ void __init plat_time_init(void) | |||
| 30 | { | 30 | { |
| 31 | struct clk *cpu_clk; | 31 | struct clk *cpu_clk; |
| 32 | 32 | ||
| 33 | /* Initialize ar7 clocks so the CPU clock frequency is correct */ | ||
| 34 | ar7_init_clocks(); | ||
| 35 | |||
| 33 | cpu_clk = clk_get(NULL, "cpu"); | 36 | cpu_clk = clk_get(NULL, "cpu"); |
| 34 | if (IS_ERR(cpu_clk)) { | 37 | if (IS_ERR(cpu_clk)) { |
| 35 | printk(KERN_ERR "unable to get cpu clock\n"); | 38 | printk(KERN_ERR "unable to get cpu clock\n"); |
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index b1aee33efd1..c95f90bf734 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c | |||
| @@ -32,7 +32,6 @@ | |||
| 32 | #include <asm/reboot.h> | 32 | #include <asm/reboot.h> |
| 33 | #include <asm/time.h> | 33 | #include <asm/time.h> |
| 34 | #include <bcm47xx.h> | 34 | #include <bcm47xx.h> |
| 35 | #include <asm/fw/cfe/cfe_api.h> | ||
| 36 | #include <asm/mach-bcm47xx/nvram.h> | 35 | #include <asm/mach-bcm47xx/nvram.h> |
| 37 | 36 | ||
| 38 | struct ssb_bus ssb_bcm47xx; | 37 | struct ssb_bus ssb_bcm47xx; |
| @@ -57,68 +56,112 @@ static void bcm47xx_machine_halt(void) | |||
| 57 | cpu_relax(); | 56 | cpu_relax(); |
| 58 | } | 57 | } |
| 59 | 58 | ||
| 60 | static void str2eaddr(char *str, char *dest) | 59 | #define READ_FROM_NVRAM(_outvar, name, buf) \ |
| 61 | { | 60 | if (nvram_getenv(name, buf, sizeof(buf)) >= 0)\ |
| 62 | int i = 0; | 61 | sprom->_outvar = simple_strtoul(buf, NULL, 0); |
| 63 | 62 | ||
| 64 | if (str == NULL) { | 63 | static void bcm47xx_fill_sprom(struct ssb_sprom *sprom) |
| 65 | memset(dest, 0, 6); | 64 | { |
| 66 | return; | 65 | char buf[100]; |
| 66 | u32 boardflags; | ||
| 67 | |||
| 68 | memset(sprom, 0, sizeof(struct ssb_sprom)); | ||
| 69 | |||
| 70 | sprom->revision = 1; /* Fallback: Old hardware does not define this. */ | ||
| 71 | READ_FROM_NVRAM(revision, "sromrev", buf); | ||
| 72 | if (nvram_getenv("il0macaddr", buf, sizeof(buf)) >= 0) | ||
| 73 | nvram_parse_macaddr(buf, sprom->il0mac); | ||
| 74 | if (nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0) | ||
| 75 | nvram_parse_macaddr(buf, sprom->et0mac); | ||
| 76 | if (nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0) | ||
| 77 | nvram_parse_macaddr(buf, sprom->et1mac); | ||
| 78 | READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf); | ||
| 79 | READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf); | ||
| 80 | READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf); | ||
| 81 | READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf); | ||
| 82 | READ_FROM_NVRAM(board_rev, "boardrev", buf); | ||
| 83 | READ_FROM_NVRAM(country_code, "ccode", buf); | ||
| 84 | READ_FROM_NVRAM(ant_available_a, "aa5g", buf); | ||
| 85 | READ_FROM_NVRAM(ant_available_bg, "aa2g", buf); | ||
| 86 | READ_FROM_NVRAM(pa0b0, "pa0b0", buf); | ||
| 87 | READ_FROM_NVRAM(pa0b1, "pa0b1", buf); | ||
| 88 | READ_FROM_NVRAM(pa0b2, "pa0b2", buf); | ||
| 89 | READ_FROM_NVRAM(pa1b0, "pa1b0", buf); | ||
| 90 | READ_FROM_NVRAM(pa1b1, "pa1b1", buf); | ||
| 91 | READ_FROM_NVRAM(pa1b2, "pa1b2", buf); | ||
| 92 | READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf); | ||
| 93 | READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf); | ||
| 94 | READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf); | ||
| 95 | READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf); | ||
| 96 | READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf); | ||
| 97 | READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf); | ||
| 98 | READ_FROM_NVRAM(gpio0, "wl0gpio0", buf); | ||
| 99 | READ_FROM_NVRAM(gpio1, "wl0gpio1", buf); | ||
| 100 | READ_FROM_NVRAM(gpio2, "wl0gpio2", buf); | ||
| 101 | READ_FROM_NVRAM(gpio3, "wl0gpio3", buf); | ||
| 102 | READ_FROM_NVRAM(maxpwr_bg, "pa0maxpwr", buf); | ||
| 103 | READ_FROM_NVRAM(maxpwr_al, "pa1lomaxpwr", buf); | ||
| 104 | READ_FROM_NVRAM(maxpwr_a, "pa1maxpwr", buf); | ||
| 105 | READ_FROM_NVRAM(maxpwr_ah, "pa1himaxpwr", buf); | ||
| 106 | READ_FROM_NVRAM(itssi_a, "pa1itssit", buf); | ||
| 107 | READ_FROM_NVRAM(itssi_bg, "pa0itssit", buf); | ||
| 108 | READ_FROM_NVRAM(tri2g, "tri2g", buf); | ||
| 109 | READ_FROM_NVRAM(tri5gl, "tri5gl", buf); | ||
| 110 | READ_FROM_NVRAM(tri5g, "tri5g", buf); | ||
| 111 | READ_FROM_NVRAM(tri5gh, "tri5gh", buf); | ||
| 112 | READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf); | ||
| 113 | READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf); | ||
| 114 | READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf); | ||
| 115 | READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf); | ||
| 116 | READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf); | ||
| 117 | READ_FROM_NVRAM(bxa2g, "bxa2g", buf); | ||
| 118 | READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf); | ||
| 119 | READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf); | ||
| 120 | READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf); | ||
| 121 | READ_FROM_NVRAM(bxa5g, "bxa5g", buf); | ||
| 122 | READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf); | ||
| 123 | READ_FROM_NVRAM(ofdm2gpo, "ofdm2gpo", buf); | ||
| 124 | READ_FROM_NVRAM(ofdm5glpo, "ofdm5glpo", buf); | ||
| 125 | READ_FROM_NVRAM(ofdm5gpo, "ofdm5gpo", buf); | ||
| 126 | READ_FROM_NVRAM(ofdm5ghpo, "ofdm5ghpo", buf); | ||
| 127 | |||
| 128 | if (nvram_getenv("boardflags", buf, sizeof(buf)) >= 0) { | ||
| 129 | boardflags = simple_strtoul(buf, NULL, 0); | ||
| 130 | if (boardflags) { | ||
| 131 | sprom->boardflags_lo = (boardflags & 0x0000FFFFU); | ||
| 132 | sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16; | ||
| 133 | } | ||
| 67 | } | 134 | } |
| 68 | 135 | if (nvram_getenv("boardflags2", buf, sizeof(buf)) >= 0) { | |
| 69 | for (;;) { | 136 | boardflags = simple_strtoul(buf, NULL, 0); |
| 70 | dest[i++] = (char) simple_strtoul(str, NULL, 16); | 137 | if (boardflags) { |
| 71 | str += 2; | 138 | sprom->boardflags2_lo = (boardflags & 0x0000FFFFU); |
| 72 | if (!*str++ || i == 6) | 139 | sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16; |
| 73 | break; | 140 | } |
| 74 | } | 141 | } |
| 75 | } | 142 | } |
| 76 | 143 | ||
| 77 | static int bcm47xx_get_invariants(struct ssb_bus *bus, | 144 | static int bcm47xx_get_invariants(struct ssb_bus *bus, |
| 78 | struct ssb_init_invariants *iv) | 145 | struct ssb_init_invariants *iv) |
| 79 | { | 146 | { |
| 80 | char buf[100]; | 147 | char buf[20]; |
| 81 | 148 | ||
| 82 | /* Fill boardinfo structure */ | 149 | /* Fill boardinfo structure */ |
| 83 | memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo)); | 150 | memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo)); |
| 84 | 151 | ||
| 85 | if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0 || | 152 | if (nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0) |
| 86 | nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0) | 153 | iv->boardinfo.vendor = (u16)simple_strtoul(buf, NULL, 0); |
| 87 | iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); | 154 | else |
| 88 | if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0 || | 155 | iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM; |
| 89 | nvram_getenv("boardtype", buf, sizeof(buf)) >= 0) | 156 | if (nvram_getenv("boardtype", buf, sizeof(buf)) >= 0) |
| 90 | iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); | 157 | iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); |
| 91 | if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0 || | 158 | if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0) |
| 92 | nvram_getenv("boardrev", buf, sizeof(buf)) >= 0) | ||
| 93 | iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0); | 159 | iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0); |
| 94 | 160 | ||
| 95 | /* Fill sprom structure */ | 161 | bcm47xx_fill_sprom(&iv->sprom); |
| 96 | memset(&(iv->sprom), 0, sizeof(struct ssb_sprom)); | ||
| 97 | iv->sprom.revision = 3; | ||
| 98 | |||
| 99 | if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0 || | ||
| 100 | nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0) | ||
| 101 | str2eaddr(buf, iv->sprom.et0mac); | ||
| 102 | 162 | ||
| 103 | if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0 || | 163 | if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0) |
| 104 | nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0) | 164 | iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10); |
| 105 | str2eaddr(buf, iv->sprom.et1mac); | ||
| 106 | |||
| 107 | if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0 || | ||
| 108 | nvram_getenv("et0phyaddr", buf, sizeof(buf)) >= 0) | ||
| 109 | iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 0); | ||
| 110 | |||
| 111 | if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0 || | ||
| 112 | nvram_getenv("et1phyaddr", buf, sizeof(buf)) >= 0) | ||
| 113 | iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 0); | ||
| 114 | |||
| 115 | if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0 || | ||
| 116 | nvram_getenv("et0mdcport", buf, sizeof(buf)) >= 0) | ||
| 117 | iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10); | ||
| 118 | |||
| 119 | if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0 || | ||
| 120 | nvram_getenv("et1mdcport", buf, sizeof(buf)) >= 0) | ||
| 121 | iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10); | ||
| 122 | 165 | ||
| 123 | return 0; | 166 | return 0; |
| 124 | } | 167 | } |
| @@ -126,12 +169,28 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus, | |||
| 126 | void __init plat_mem_setup(void) | 169 | void __init plat_mem_setup(void) |
| 127 | { | 170 | { |
| 128 | int err; | 171 | int err; |
| 172 | char buf[100]; | ||
| 173 | struct ssb_mipscore *mcore; | ||
| 129 | 174 | ||
| 130 | err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE, | 175 | err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE, |
| 131 | bcm47xx_get_invariants); | 176 | bcm47xx_get_invariants); |
| 132 | if (err) | 177 | if (err) |
| 133 | panic("Failed to initialize SSB bus (err %d)\n", err); | 178 | panic("Failed to initialize SSB bus (err %d)\n", err); |
| 134 | 179 | ||
| 180 | mcore = &ssb_bcm47xx.mipscore; | ||
| 181 | if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) { | ||
| 182 | if (strstr(buf, "console=ttyS1")) { | ||
| 183 | struct ssb_serial_port port; | ||
| 184 | |||
| 185 | printk(KERN_DEBUG "Swapping serial ports!\n"); | ||
| 186 | /* swap serial ports */ | ||
| 187 | memcpy(&port, &mcore->serial_ports[0], sizeof(port)); | ||
| 188 | memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1], | ||
| 189 | sizeof(port)); | ||
| 190 | memcpy(&mcore->serial_ports[1], &port, sizeof(port)); | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 135 | _machine_restart = bcm47xx_machine_restart; | 194 | _machine_restart = bcm47xx_machine_restart; |
| 136 | _machine_halt = bcm47xx_machine_halt; | 195 | _machine_halt = bcm47xx_machine_halt; |
| 137 | pm_power_off = bcm47xx_machine_halt; | 196 | pm_power_off = bcm47xx_machine_halt; |
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 06d59dcbe24..86877539c6e 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h | |||
| @@ -111,8 +111,8 @@ | |||
| 111 | * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM | 111 | * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM |
| 112 | */ | 112 | */ |
| 113 | 113 | ||
| 114 | #define PRID_IMP_BMIPS4KC 0x4000 | 114 | #define PRID_IMP_BMIPS32_REV4 0x4000 |
| 115 | #define PRID_IMP_BMIPS32 0x8000 | 115 | #define PRID_IMP_BMIPS32_REV8 0x8000 |
| 116 | #define PRID_IMP_BMIPS3300 0x9000 | 116 | #define PRID_IMP_BMIPS3300 0x9000 |
| 117 | #define PRID_IMP_BMIPS3300_ALT 0x9100 | 117 | #define PRID_IMP_BMIPS3300_ALT 0x9100 |
| 118 | #define PRID_IMP_BMIPS3300_BUG 0x0000 | 118 | #define PRID_IMP_BMIPS3300_BUG 0x0000 |
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index fd1d39eb743..455c0ac7d4e 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h | |||
| @@ -249,7 +249,8 @@ extern struct mips_abi mips_abi_n32; | |||
| 249 | 249 | ||
| 250 | #define SET_PERSONALITY(ex) \ | 250 | #define SET_PERSONALITY(ex) \ |
| 251 | do { \ | 251 | do { \ |
| 252 | set_personality(PER_LINUX); \ | 252 | if (personality(current->personality) != PER_LINUX) \ |
| 253 | set_personality(PER_LINUX); \ | ||
| 253 | \ | 254 | \ |
| 254 | current->thread.abi = &mips_abi; \ | 255 | current->thread.abi = &mips_abi; \ |
| 255 | } while (0) | 256 | } while (0) |
| @@ -296,6 +297,8 @@ do { \ | |||
| 296 | 297 | ||
| 297 | #define SET_PERSONALITY(ex) \ | 298 | #define SET_PERSONALITY(ex) \ |
| 298 | do { \ | 299 | do { \ |
| 300 | unsigned int p; \ | ||
| 301 | \ | ||
| 299 | clear_thread_flag(TIF_32BIT_REGS); \ | 302 | clear_thread_flag(TIF_32BIT_REGS); \ |
| 300 | clear_thread_flag(TIF_32BIT_ADDR); \ | 303 | clear_thread_flag(TIF_32BIT_ADDR); \ |
| 301 | \ | 304 | \ |
| @@ -304,7 +307,8 @@ do { \ | |||
| 304 | else \ | 307 | else \ |
| 305 | current->thread.abi = &mips_abi; \ | 308 | current->thread.abi = &mips_abi; \ |
| 306 | \ | 309 | \ |
| 307 | if (current->personality != PER_LINUX32) \ | 310 | p = personality(current->personality); \ |
| 311 | if (p != PER_LINUX32 && p != PER_LINUX) \ | ||
| 308 | set_personality(PER_LINUX); \ | 312 | set_personality(PER_LINUX); \ |
| 309 | } while (0) | 313 | } while (0) |
| 310 | 314 | ||
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index c98bf514ec7..5b017f23e24 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h | |||
| @@ -329,10 +329,14 @@ static inline void pfx##write##bwlq(type val, \ | |||
| 329 | "dsrl32 %L0, %L0, 0" "\n\t" \ | 329 | "dsrl32 %L0, %L0, 0" "\n\t" \ |
| 330 | "dsll32 %M0, %M0, 0" "\n\t" \ | 330 | "dsll32 %M0, %M0, 0" "\n\t" \ |
| 331 | "or %L0, %L0, %M0" "\n\t" \ | 331 | "or %L0, %L0, %M0" "\n\t" \ |
| 332 | ".set push" "\n\t" \ | ||
| 333 | ".set noreorder" "\n\t" \ | ||
| 334 | ".set nomacro" "\n\t" \ | ||
| 332 | "sd %L0, %2" "\n\t" \ | 335 | "sd %L0, %2" "\n\t" \ |
| 336 | ".set pop" "\n\t" \ | ||
| 333 | ".set mips0" "\n" \ | 337 | ".set mips0" "\n" \ |
| 334 | : "=r" (__tmp) \ | 338 | : "=r" (__tmp) \ |
| 335 | : "0" (__val), "m" (*__mem)); \ | 339 | : "0" (__val), "R" (*__mem)); \ |
| 336 | if (irq) \ | 340 | if (irq) \ |
| 337 | local_irq_restore(__flags); \ | 341 | local_irq_restore(__flags); \ |
| 338 | } else \ | 342 | } else \ |
| @@ -355,12 +359,16 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \ | |||
| 355 | local_irq_save(__flags); \ | 359 | local_irq_save(__flags); \ |
| 356 | __asm__ __volatile__( \ | 360 | __asm__ __volatile__( \ |
| 357 | ".set mips3" "\t\t# __readq" "\n\t" \ | 361 | ".set mips3" "\t\t# __readq" "\n\t" \ |
| 362 | ".set push" "\n\t" \ | ||
| 363 | ".set noreorder" "\n\t" \ | ||
| 364 | ".set nomacro" "\n\t" \ | ||
| 358 | "ld %L0, %1" "\n\t" \ | 365 | "ld %L0, %1" "\n\t" \ |
| 366 | ".set pop" "\n\t" \ | ||
| 359 | "dsra32 %M0, %L0, 0" "\n\t" \ | 367 | "dsra32 %M0, %L0, 0" "\n\t" \ |
| 360 | "sll %L0, %L0, 0" "\n\t" \ | 368 | "sll %L0, %L0, 0" "\n\t" \ |
| 361 | ".set mips0" "\n" \ | 369 | ".set mips0" "\n" \ |
| 362 | : "=r" (__val) \ | 370 | : "=r" (__val) \ |
| 363 | : "m" (*__mem)); \ | 371 | : "R" (*__mem)); \ |
| 364 | if (irq) \ | 372 | if (irq) \ |
| 365 | local_irq_restore(__flags); \ | 373 | local_irq_restore(__flags); \ |
| 366 | } else { \ | 374 | } else { \ |
diff --git a/arch/mips/include/asm/mach-ar7/ar7.h b/arch/mips/include/asm/mach-ar7/ar7.h index 7919d76186b..07d3fadb244 100644 --- a/arch/mips/include/asm/mach-ar7/ar7.h +++ b/arch/mips/include/asm/mach-ar7/ar7.h | |||
| @@ -201,7 +201,6 @@ static inline void ar7_device_off(u32 bit) | |||
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | int __init ar7_gpio_init(void); | 203 | int __init ar7_gpio_init(void); |
| 204 | 204 | void __init ar7_init_clocks(void); | |
| 205 | int __init ar7_gpio_init(void); | ||
| 206 | 205 | ||
| 207 | #endif /* __AR7_H__ */ | 206 | #endif /* __AR7_H__ */ |
diff --git a/arch/mips/include/asm/mach-bcm47xx/nvram.h b/arch/mips/include/asm/mach-bcm47xx/nvram.h index c58ebd8bc15..9759588ba3c 100644 --- a/arch/mips/include/asm/mach-bcm47xx/nvram.h +++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #define __NVRAM_H | 12 | #define __NVRAM_H |
| 13 | 13 | ||
| 14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
| 15 | #include <linux/kernel.h> | ||
| 15 | 16 | ||
| 16 | struct nvram_header { | 17 | struct nvram_header { |
| 17 | u32 magic; | 18 | u32 magic; |
| @@ -36,4 +37,10 @@ struct nvram_header { | |||
| 36 | 37 | ||
| 37 | extern int nvram_getenv(char *name, char *val, size_t val_len); | 38 | extern int nvram_getenv(char *name, char *val, size_t val_len); |
| 38 | 39 | ||
| 40 | static inline void nvram_parse_macaddr(char *buf, u8 *macaddr) | ||
| 41 | { | ||
| 42 | sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], &macaddr[1], | ||
| 43 | &macaddr[2], &macaddr[3], &macaddr[4], &macaddr[5]); | ||
| 44 | } | ||
| 45 | |||
| 39 | #endif | 46 | #endif |
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index 5742bb4d78f..5c0a3575877 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2009 Qi Hardware inc., | 6 | * Copyright (c) 2009 Qi Hardware inc., |
| 7 | * Author: Xiangfu Liu <xiangfu@qi-hardware.com> | 7 | * Author: Xiangfu Liu <xiangfu@qi-hardware.com> |
| 8 | * Copyright 2010, Lars-Petrer Clausen <lars@metafoo.de> | 8 | * Copyright 2010, Lars-Peter Clausen <lars@metafoo.de> |
| 9 | * | 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of the GNU General Public License version 2 or later | 11 | * it under the terms of the GNU General Public License version 2 or later |
| @@ -235,7 +235,7 @@ static const unsigned int qi_lb60_keypad_rows[] = { | |||
| 235 | QI_LB60_GPIO_KEYIN(3), | 235 | QI_LB60_GPIO_KEYIN(3), |
| 236 | QI_LB60_GPIO_KEYIN(4), | 236 | QI_LB60_GPIO_KEYIN(4), |
| 237 | QI_LB60_GPIO_KEYIN(5), | 237 | QI_LB60_GPIO_KEYIN(5), |
| 238 | QI_LB60_GPIO_KEYIN(7), | 238 | QI_LB60_GPIO_KEYIN(6), |
| 239 | QI_LB60_GPIO_KEYIN8, | 239 | QI_LB60_GPIO_KEYIN8, |
| 240 | }; | 240 | }; |
| 241 | 241 | ||
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c index 95bc2b5b14f..1cc9e544d16 100644 --- a/arch/mips/jz4740/platform.c +++ b/arch/mips/jz4740/platform.c | |||
| @@ -208,7 +208,7 @@ struct platform_device jz4740_i2s_device = { | |||
| 208 | 208 | ||
| 209 | /* PCM */ | 209 | /* PCM */ |
| 210 | struct platform_device jz4740_pcm_device = { | 210 | struct platform_device jz4740_pcm_device = { |
| 211 | .name = "jz4740-pcm", | 211 | .name = "jz4740-pcm-audio", |
| 212 | .id = -1, | 212 | .id = -1, |
| 213 | }; | 213 | }; |
| 214 | 214 | ||
diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c index cfeac15eb2e..4a70407f55b 100644 --- a/arch/mips/jz4740/prom.c +++ b/arch/mips/jz4740/prom.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #include <asm/bootinfo.h> | 23 | #include <asm/bootinfo.h> |
| 24 | #include <asm/mach-jz4740/base.h> | 24 | #include <asm/mach-jz4740/base.h> |
| 25 | 25 | ||
| 26 | void jz4740_init_cmdline(int argc, char *argv[]) | 26 | static __init void jz4740_init_cmdline(int argc, char *argv[]) |
| 27 | { | 27 | { |
| 28 | unsigned int count = COMMAND_LINE_SIZE - 1; | 28 | unsigned int count = COMMAND_LINE_SIZE - 1; |
| 29 | int i; | 29 | int i; |
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index 2f4d7a99bcc..98c5a9737c1 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c | |||
| @@ -32,7 +32,7 @@ static int mips_next_event(unsigned long delta, | |||
| 32 | cnt = read_c0_count(); | 32 | cnt = read_c0_count(); |
| 33 | cnt += delta; | 33 | cnt += delta; |
| 34 | write_c0_compare(cnt); | 34 | write_c0_compare(cnt); |
| 35 | res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0; | 35 | res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0; |
| 36 | return res; | 36 | return res; |
| 37 | } | 37 | } |
| 38 | 38 | ||
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 71620e19827..68dae7b6b5d 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
| @@ -905,7 +905,8 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) | |||
| 905 | { | 905 | { |
| 906 | decode_configs(c); | 906 | decode_configs(c); |
| 907 | switch (c->processor_id & 0xff00) { | 907 | switch (c->processor_id & 0xff00) { |
| 908 | case PRID_IMP_BMIPS32: | 908 | case PRID_IMP_BMIPS32_REV4: |
| 909 | case PRID_IMP_BMIPS32_REV8: | ||
| 909 | c->cputype = CPU_BMIPS32; | 910 | c->cputype = CPU_BMIPS32; |
| 910 | __cpu_name[cpu] = "Broadcom BMIPS32"; | 911 | __cpu_name[cpu] = "Broadcom BMIPS32"; |
| 911 | break; | 912 | break; |
| @@ -933,10 +934,6 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) | |||
| 933 | __cpu_name[cpu] = "Broadcom BMIPS5000"; | 934 | __cpu_name[cpu] = "Broadcom BMIPS5000"; |
| 934 | c->options |= MIPS_CPU_ULRI; | 935 | c->options |= MIPS_CPU_ULRI; |
| 935 | break; | 936 | break; |
| 936 | case PRID_IMP_BMIPS4KC: | ||
| 937 | c->cputype = CPU_4KC; | ||
| 938 | __cpu_name[cpu] = "MIPS 4Kc"; | ||
| 939 | break; | ||
| 940 | } | 937 | } |
| 941 | } | 938 | } |
| 942 | 939 | ||
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 6343b4a5b83..876a75cc376 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
| @@ -251,14 +251,15 @@ SYSCALL_DEFINE5(n32_msgrcv, int, msqid, u32, msgp, size_t, msgsz, | |||
| 251 | 251 | ||
| 252 | SYSCALL_DEFINE1(32_personality, unsigned long, personality) | 252 | SYSCALL_DEFINE1(32_personality, unsigned long, personality) |
| 253 | { | 253 | { |
| 254 | unsigned int p = personality & 0xffffffff; | ||
| 254 | int ret; | 255 | int ret; |
| 255 | personality &= 0xffffffff; | 256 | |
| 256 | if (personality(current->personality) == PER_LINUX32 && | 257 | if (personality(current->personality) == PER_LINUX32 && |
| 257 | personality == PER_LINUX) | 258 | personality(p) == PER_LINUX) |
| 258 | personality = PER_LINUX32; | 259 | p = (p & ~PER_MASK) | PER_LINUX32; |
| 259 | ret = sys_personality(personality); | 260 | ret = sys_personality(p); |
| 260 | if (ret == PER_LINUX32) | 261 | if (ret != -1 && personality(ret) == PER_LINUX32) |
| 261 | ret = PER_LINUX; | 262 | ret = (ret & ~PER_MASK) | PER_LINUX; |
| 262 | return ret; | 263 | return ret; |
| 263 | } | 264 | } |
| 264 | 265 | ||
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 99960940d4a..ae167df73dd 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
| @@ -142,7 +142,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
| 142 | childregs->regs[7] = 0; /* Clear error flag */ | 142 | childregs->regs[7] = 0; /* Clear error flag */ |
| 143 | 143 | ||
| 144 | childregs->regs[2] = 0; /* Child gets zero as return value */ | 144 | childregs->regs[2] = 0; /* Child gets zero as return value */ |
| 145 | regs->regs[2] = p->pid; | ||
| 146 | 145 | ||
| 147 | if (childregs->cp0_status & ST0_CU0) { | 146 | if (childregs->cp0_status & ST0_CU0) { |
| 148 | childregs->regs[28] = (unsigned long) ti; | 147 | childregs->regs[28] = (unsigned long) ti; |
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index e000b278f02..9dbe5836895 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c | |||
| @@ -100,7 +100,7 @@ void __init device_tree_init(void) | |||
| 100 | return; | 100 | return; |
| 101 | 101 | ||
| 102 | base = virt_to_phys((void *)initial_boot_params); | 102 | base = virt_to_phys((void *)initial_boot_params); |
| 103 | size = initial_boot_params->totalsize; | 103 | size = be32_to_cpu(initial_boot_params->totalsize); |
| 104 | 104 | ||
| 105 | /* Before we do anything, lets reserve the dt blob */ | 105 | /* Before we do anything, lets reserve the dt blob */ |
| 106 | reserve_mem_mach(base, size); | 106 | reserve_mem_mach(base, size); |
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 43e7cdc5ded..c0e81418ba2 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c | |||
| @@ -153,7 +153,7 @@ static void __cpuinit vsmp_init_secondary(void) | |||
| 153 | { | 153 | { |
| 154 | extern int gic_present; | 154 | extern int gic_present; |
| 155 | 155 | ||
| 156 | /* This is Malta specific: IPI,performance and timer inetrrupts */ | 156 | /* This is Malta specific: IPI,performance and timer interrupts */ |
| 157 | if (gic_present) | 157 | if (gic_present) |
| 158 | change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | | 158 | change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | |
| 159 | STATUSF_IP6 | STATUSF_IP7); | 159 | STATUSF_IP6 | STATUSF_IP7); |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 8e9fbe75894..e9710430254 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
| @@ -83,7 +83,8 @@ extern asmlinkage void handle_mcheck(void); | |||
| 83 | extern asmlinkage void handle_reserved(void); | 83 | extern asmlinkage void handle_reserved(void); |
| 84 | 84 | ||
| 85 | extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, | 85 | extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, |
| 86 | struct mips_fpu_struct *ctx, int has_fpu); | 86 | struct mips_fpu_struct *ctx, int has_fpu, |
| 87 | void *__user *fault_addr); | ||
| 87 | 88 | ||
| 88 | void (*board_be_init)(void); | 89 | void (*board_be_init)(void); |
| 89 | int (*board_be_handler)(struct pt_regs *regs, int is_fixup); | 90 | int (*board_be_handler)(struct pt_regs *regs, int is_fixup); |
| @@ -661,12 +662,36 @@ asmlinkage void do_ov(struct pt_regs *regs) | |||
| 661 | force_sig_info(SIGFPE, &info, current); | 662 | force_sig_info(SIGFPE, &info, current); |
| 662 | } | 663 | } |
| 663 | 664 | ||
| 665 | static int process_fpemu_return(int sig, void __user *fault_addr) | ||
| 666 | { | ||
| 667 | if (sig == SIGSEGV || sig == SIGBUS) { | ||
| 668 | struct siginfo si = {0}; | ||
| 669 | si.si_addr = fault_addr; | ||
| 670 | si.si_signo = sig; | ||
| 671 | if (sig == SIGSEGV) { | ||
| 672 | if (find_vma(current->mm, (unsigned long)fault_addr)) | ||
| 673 | si.si_code = SEGV_ACCERR; | ||
| 674 | else | ||
| 675 | si.si_code = SEGV_MAPERR; | ||
| 676 | } else { | ||
| 677 | si.si_code = BUS_ADRERR; | ||
| 678 | } | ||
| 679 | force_sig_info(sig, &si, current); | ||
| 680 | return 1; | ||
| 681 | } else if (sig) { | ||
| 682 | force_sig(sig, current); | ||
| 683 | return 1; | ||
| 684 | } else { | ||
| 685 | return 0; | ||
| 686 | } | ||
| 687 | } | ||
| 688 | |||
| 664 | /* | 689 | /* |
| 665 | * XXX Delayed fp exceptions when doing a lazy ctx switch XXX | 690 | * XXX Delayed fp exceptions when doing a lazy ctx switch XXX |
| 666 | */ | 691 | */ |
| 667 | asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | 692 | asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) |
| 668 | { | 693 | { |
| 669 | siginfo_t info; | 694 | siginfo_t info = {0}; |
| 670 | 695 | ||
| 671 | if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE) | 696 | if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE) |
| 672 | == NOTIFY_STOP) | 697 | == NOTIFY_STOP) |
| @@ -675,6 +700,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | |||
| 675 | 700 | ||
| 676 | if (fcr31 & FPU_CSR_UNI_X) { | 701 | if (fcr31 & FPU_CSR_UNI_X) { |
| 677 | int sig; | 702 | int sig; |
| 703 | void __user *fault_addr = NULL; | ||
| 678 | 704 | ||
| 679 | /* | 705 | /* |
| 680 | * Unimplemented operation exception. If we've got the full | 706 | * Unimplemented operation exception. If we've got the full |
| @@ -690,7 +716,8 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | |||
| 690 | lose_fpu(1); | 716 | lose_fpu(1); |
| 691 | 717 | ||
| 692 | /* Run the emulator */ | 718 | /* Run the emulator */ |
| 693 | sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1); | 719 | sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, |
| 720 | &fault_addr); | ||
| 694 | 721 | ||
| 695 | /* | 722 | /* |
| 696 | * We can't allow the emulated instruction to leave any of | 723 | * We can't allow the emulated instruction to leave any of |
| @@ -702,8 +729,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | |||
| 702 | own_fpu(1); /* Using the FPU again. */ | 729 | own_fpu(1); /* Using the FPU again. */ |
| 703 | 730 | ||
| 704 | /* If something went wrong, signal */ | 731 | /* If something went wrong, signal */ |
| 705 | if (sig) | 732 | process_fpemu_return(sig, fault_addr); |
| 706 | force_sig(sig, current); | ||
| 707 | 733 | ||
| 708 | return; | 734 | return; |
| 709 | } else if (fcr31 & FPU_CSR_INV_X) | 735 | } else if (fcr31 & FPU_CSR_INV_X) |
| @@ -996,11 +1022,11 @@ asmlinkage void do_cpu(struct pt_regs *regs) | |||
| 996 | 1022 | ||
| 997 | if (!raw_cpu_has_fpu) { | 1023 | if (!raw_cpu_has_fpu) { |
| 998 | int sig; | 1024 | int sig; |
| 1025 | void __user *fault_addr = NULL; | ||
| 999 | sig = fpu_emulator_cop1Handler(regs, | 1026 | sig = fpu_emulator_cop1Handler(regs, |
| 1000 | ¤t->thread.fpu, 0); | 1027 | ¤t->thread.fpu, |
| 1001 | if (sig) | 1028 | 0, &fault_addr); |
| 1002 | force_sig(sig, current); | 1029 | if (!process_fpemu_return(sig, fault_addr)) |
| 1003 | else | ||
| 1004 | mt_ase_fp_affinity(); | 1030 | mt_ase_fp_affinity(); |
| 1005 | } | 1031 | } |
| 1006 | 1032 | ||
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 3eb3cde2f66..6a1fdfef8fd 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c | |||
| @@ -1092,6 +1092,10 @@ static int vpe_open(struct inode *inode, struct file *filp) | |||
| 1092 | 1092 | ||
| 1093 | /* this of-course trashes what was there before... */ | 1093 | /* this of-course trashes what was there before... */ |
| 1094 | v->pbuffer = vmalloc(P_SIZE); | 1094 | v->pbuffer = vmalloc(P_SIZE); |
| 1095 | if (!v->pbuffer) { | ||
| 1096 | pr_warning("VPE loader: unable to allocate memory\n"); | ||
| 1097 | return -ENOMEM; | ||
| 1098 | } | ||
| 1095 | v->plen = P_SIZE; | 1099 | v->plen = P_SIZE; |
| 1096 | v->load_addr = NULL; | 1100 | v->load_addr = NULL; |
| 1097 | v->len = 0; | 1101 | v->len = 0; |
| @@ -1149,10 +1153,9 @@ static int vpe_release(struct inode *inode, struct file *filp) | |||
| 1149 | if (ret < 0) | 1153 | if (ret < 0) |
| 1150 | v->shared_ptr = NULL; | 1154 | v->shared_ptr = NULL; |
| 1151 | 1155 | ||
| 1152 | // cleanup any temp buffers | 1156 | vfree(v->pbuffer); |
| 1153 | if (v->pbuffer) | ||
| 1154 | vfree(v->pbuffer); | ||
| 1155 | v->plen = 0; | 1157 | v->plen = 0; |
| 1158 | |||
| 1156 | return ret; | 1159 | return ret; |
| 1157 | } | 1160 | } |
| 1158 | 1161 | ||
| @@ -1169,11 +1172,6 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer, | |||
| 1169 | if (v == NULL) | 1172 | if (v == NULL) |
| 1170 | return -ENODEV; | 1173 | return -ENODEV; |
| 1171 | 1174 | ||
| 1172 | if (v->pbuffer == NULL) { | ||
| 1173 | printk(KERN_ERR "VPE loader: no buffer for program\n"); | ||
| 1174 | return -ENOMEM; | ||
| 1175 | } | ||
| 1176 | |||
| 1177 | if ((count + v->len) > v->plen) { | 1175 | if ((count + v->len) > v->plen) { |
| 1178 | printk(KERN_WARNING | 1176 | printk(KERN_WARNING |
| 1179 | "VPE loader: elf size too big. Perhaps strip uneeded symbols\n"); | 1177 | "VPE loader: elf size too big. Perhaps strip uneeded symbols\n"); |
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S index 77dc3b20110..606c8a9efe3 100644 --- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S | |||
| @@ -161,16 +161,16 @@ FEXPORT(__bzero) | |||
| 161 | 161 | ||
| 162 | .Lfwd_fixup: | 162 | .Lfwd_fixup: |
| 163 | PTR_L t0, TI_TASK($28) | 163 | PTR_L t0, TI_TASK($28) |
| 164 | LONG_L t0, THREAD_BUADDR(t0) | ||
| 165 | andi a2, 0x3f | 164 | andi a2, 0x3f |
| 165 | LONG_L t0, THREAD_BUADDR(t0) | ||
| 166 | LONG_ADDU a2, t1 | 166 | LONG_ADDU a2, t1 |
| 167 | jr ra | 167 | jr ra |
| 168 | LONG_SUBU a2, t0 | 168 | LONG_SUBU a2, t0 |
| 169 | 169 | ||
| 170 | .Lpartial_fixup: | 170 | .Lpartial_fixup: |
| 171 | PTR_L t0, TI_TASK($28) | 171 | PTR_L t0, TI_TASK($28) |
| 172 | LONG_L t0, THREAD_BUADDR(t0) | ||
| 173 | andi a2, LONGMASK | 172 | andi a2, LONGMASK |
| 173 | LONG_L t0, THREAD_BUADDR(t0) | ||
| 174 | LONG_ADDU a2, t1 | 174 | LONG_ADDU a2, t1 |
| 175 | jr ra | 175 | jr ra |
| 176 | LONG_SUBU a2, t0 | 176 | LONG_SUBU a2, t0 |
diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c index ae4cff97a56..11b193f848f 100644 --- a/arch/mips/loongson/common/env.c +++ b/arch/mips/loongson/common/env.c | |||
| @@ -29,9 +29,9 @@ unsigned long memsize, highmemsize; | |||
| 29 | 29 | ||
| 30 | #define parse_even_earlier(res, option, p) \ | 30 | #define parse_even_earlier(res, option, p) \ |
| 31 | do { \ | 31 | do { \ |
| 32 | int ret; \ | ||
| 32 | if (strncmp(option, (char *)p, strlen(option)) == 0) \ | 33 | if (strncmp(option, (char *)p, strlen(option)) == 0) \ |
| 33 | strict_strtol((char *)p + strlen(option"="), \ | 34 | ret = strict_strtol((char *)p + strlen(option"="), 10, &res); \ |
| 34 | 10, &res); \ | ||
| 35 | } while (0) | 35 | } while (0) |
| 36 | 36 | ||
| 37 | void __init prom_init_env(void) | 37 | void __init prom_init_env(void) |
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index b2ad1b0910f..d32cb050311 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c | |||
| @@ -64,7 +64,7 @@ static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *, | |||
| 64 | 64 | ||
| 65 | #if __mips >= 4 && __mips != 32 | 65 | #if __mips >= 4 && __mips != 32 |
| 66 | static int fpux_emu(struct pt_regs *, | 66 | static int fpux_emu(struct pt_regs *, |
| 67 | struct mips_fpu_struct *, mips_instruction); | 67 | struct mips_fpu_struct *, mips_instruction, void *__user *); |
| 68 | #endif | 68 | #endif |
| 69 | 69 | ||
| 70 | /* Further private data for which no space exists in mips_fpu_struct */ | 70 | /* Further private data for which no space exists in mips_fpu_struct */ |
| @@ -208,16 +208,23 @@ static inline int cop1_64bit(struct pt_regs *xcp) | |||
| 208 | * Two instructions if the instruction is in a branch delay slot. | 208 | * Two instructions if the instruction is in a branch delay slot. |
| 209 | */ | 209 | */ |
| 210 | 210 | ||
| 211 | static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | 211 | static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, |
| 212 | void *__user *fault_addr) | ||
| 212 | { | 213 | { |
| 213 | mips_instruction ir; | 214 | mips_instruction ir; |
| 214 | unsigned long emulpc, contpc; | 215 | unsigned long emulpc, contpc; |
| 215 | unsigned int cond; | 216 | unsigned int cond; |
| 216 | 217 | ||
| 217 | if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) { | 218 | if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) { |
| 218 | MIPS_FPU_EMU_INC_STATS(errors); | 219 | MIPS_FPU_EMU_INC_STATS(errors); |
| 220 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
| 219 | return SIGBUS; | 221 | return SIGBUS; |
| 220 | } | 222 | } |
| 223 | if (__get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) { | ||
| 224 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 225 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
| 226 | return SIGSEGV; | ||
| 227 | } | ||
| 221 | 228 | ||
| 222 | /* XXX NEC Vr54xx bug workaround */ | 229 | /* XXX NEC Vr54xx bug workaround */ |
| 223 | if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir)) | 230 | if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir)) |
| @@ -245,10 +252,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
| 245 | #endif | 252 | #endif |
| 246 | return SIGILL; | 253 | return SIGILL; |
| 247 | } | 254 | } |
| 248 | if (get_user(ir, (mips_instruction __user *) emulpc)) { | 255 | if (!access_ok(VERIFY_READ, emulpc, sizeof(mips_instruction))) { |
| 249 | MIPS_FPU_EMU_INC_STATS(errors); | 256 | MIPS_FPU_EMU_INC_STATS(errors); |
| 257 | *fault_addr = (mips_instruction __user *)emulpc; | ||
| 250 | return SIGBUS; | 258 | return SIGBUS; |
| 251 | } | 259 | } |
| 260 | if (__get_user(ir, (mips_instruction __user *) emulpc)) { | ||
| 261 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 262 | *fault_addr = (mips_instruction __user *)emulpc; | ||
| 263 | return SIGSEGV; | ||
| 264 | } | ||
| 252 | /* __compute_return_epc() will have updated cp0_epc */ | 265 | /* __compute_return_epc() will have updated cp0_epc */ |
| 253 | contpc = xcp->cp0_epc; | 266 | contpc = xcp->cp0_epc; |
| 254 | /* In order not to confuse ptrace() et al, tweak context */ | 267 | /* In order not to confuse ptrace() et al, tweak context */ |
| @@ -269,10 +282,17 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
| 269 | u64 val; | 282 | u64 val; |
| 270 | 283 | ||
| 271 | MIPS_FPU_EMU_INC_STATS(loads); | 284 | MIPS_FPU_EMU_INC_STATS(loads); |
| 272 | if (get_user(val, va)) { | 285 | |
| 286 | if (!access_ok(VERIFY_READ, va, sizeof(u64))) { | ||
| 273 | MIPS_FPU_EMU_INC_STATS(errors); | 287 | MIPS_FPU_EMU_INC_STATS(errors); |
| 288 | *fault_addr = va; | ||
| 274 | return SIGBUS; | 289 | return SIGBUS; |
| 275 | } | 290 | } |
| 291 | if (__get_user(val, va)) { | ||
| 292 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 293 | *fault_addr = va; | ||
| 294 | return SIGSEGV; | ||
| 295 | } | ||
| 276 | DITOREG(val, MIPSInst_RT(ir)); | 296 | DITOREG(val, MIPSInst_RT(ir)); |
| 277 | break; | 297 | break; |
| 278 | } | 298 | } |
| @@ -284,10 +304,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
| 284 | 304 | ||
| 285 | MIPS_FPU_EMU_INC_STATS(stores); | 305 | MIPS_FPU_EMU_INC_STATS(stores); |
| 286 | DIFROMREG(val, MIPSInst_RT(ir)); | 306 | DIFROMREG(val, MIPSInst_RT(ir)); |
| 287 | if (put_user(val, va)) { | 307 | if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) { |
| 288 | MIPS_FPU_EMU_INC_STATS(errors); | 308 | MIPS_FPU_EMU_INC_STATS(errors); |
| 309 | *fault_addr = va; | ||
| 289 | return SIGBUS; | 310 | return SIGBUS; |
| 290 | } | 311 | } |
| 312 | if (__put_user(val, va)) { | ||
| 313 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 314 | *fault_addr = va; | ||
| 315 | return SIGSEGV; | ||
| 316 | } | ||
| 291 | break; | 317 | break; |
| 292 | } | 318 | } |
| 293 | 319 | ||
| @@ -297,10 +323,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
| 297 | u32 val; | 323 | u32 val; |
| 298 | 324 | ||
| 299 | MIPS_FPU_EMU_INC_STATS(loads); | 325 | MIPS_FPU_EMU_INC_STATS(loads); |
| 300 | if (get_user(val, va)) { | 326 | if (!access_ok(VERIFY_READ, va, sizeof(u32))) { |
| 301 | MIPS_FPU_EMU_INC_STATS(errors); | 327 | MIPS_FPU_EMU_INC_STATS(errors); |
| 328 | *fault_addr = va; | ||
| 302 | return SIGBUS; | 329 | return SIGBUS; |
| 303 | } | 330 | } |
| 331 | if (__get_user(val, va)) { | ||
| 332 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 333 | *fault_addr = va; | ||
| 334 | return SIGSEGV; | ||
| 335 | } | ||
| 304 | SITOREG(val, MIPSInst_RT(ir)); | 336 | SITOREG(val, MIPSInst_RT(ir)); |
| 305 | break; | 337 | break; |
| 306 | } | 338 | } |
| @@ -312,10 +344,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
| 312 | 344 | ||
| 313 | MIPS_FPU_EMU_INC_STATS(stores); | 345 | MIPS_FPU_EMU_INC_STATS(stores); |
| 314 | SIFROMREG(val, MIPSInst_RT(ir)); | 346 | SIFROMREG(val, MIPSInst_RT(ir)); |
| 315 | if (put_user(val, va)) { | 347 | if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) { |
| 316 | MIPS_FPU_EMU_INC_STATS(errors); | 348 | MIPS_FPU_EMU_INC_STATS(errors); |
| 349 | *fault_addr = va; | ||
| 317 | return SIGBUS; | 350 | return SIGBUS; |
| 318 | } | 351 | } |
| 352 | if (__put_user(val, va)) { | ||
| 353 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 354 | *fault_addr = va; | ||
| 355 | return SIGSEGV; | ||
| 356 | } | ||
| 319 | break; | 357 | break; |
| 320 | } | 358 | } |
| 321 | 359 | ||
| @@ -440,11 +478,18 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
| 440 | contpc = (xcp->cp0_epc + | 478 | contpc = (xcp->cp0_epc + |
| 441 | (MIPSInst_SIMM(ir) << 2)); | 479 | (MIPSInst_SIMM(ir) << 2)); |
| 442 | 480 | ||
| 443 | if (get_user(ir, | 481 | if (!access_ok(VERIFY_READ, xcp->cp0_epc, |
| 444 | (mips_instruction __user *) xcp->cp0_epc)) { | 482 | sizeof(mips_instruction))) { |
| 445 | MIPS_FPU_EMU_INC_STATS(errors); | 483 | MIPS_FPU_EMU_INC_STATS(errors); |
| 484 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
| 446 | return SIGBUS; | 485 | return SIGBUS; |
| 447 | } | 486 | } |
| 487 | if (__get_user(ir, | ||
| 488 | (mips_instruction __user *) xcp->cp0_epc)) { | ||
| 489 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 490 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
| 491 | return SIGSEGV; | ||
| 492 | } | ||
| 448 | 493 | ||
| 449 | switch (MIPSInst_OPCODE(ir)) { | 494 | switch (MIPSInst_OPCODE(ir)) { |
| 450 | case lwc1_op: | 495 | case lwc1_op: |
| @@ -506,9 +551,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
| 506 | 551 | ||
| 507 | #if __mips >= 4 && __mips != 32 | 552 | #if __mips >= 4 && __mips != 32 |
| 508 | case cop1x_op:{ | 553 | case cop1x_op:{ |
| 509 | int sig; | 554 | int sig = fpux_emu(xcp, ctx, ir, fault_addr); |
| 510 | 555 | if (sig) | |
| 511 | if ((sig = fpux_emu(xcp, ctx, ir))) | ||
| 512 | return sig; | 556 | return sig; |
| 513 | break; | 557 | break; |
| 514 | } | 558 | } |
| @@ -604,7 +648,7 @@ DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg); | |||
| 604 | DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); | 648 | DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); |
| 605 | 649 | ||
| 606 | static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | 650 | static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, |
| 607 | mips_instruction ir) | 651 | mips_instruction ir, void *__user *fault_addr) |
| 608 | { | 652 | { |
| 609 | unsigned rcsr = 0; /* resulting csr */ | 653 | unsigned rcsr = 0; /* resulting csr */ |
| 610 | 654 | ||
| @@ -624,10 +668,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
| 624 | xcp->regs[MIPSInst_FT(ir)]); | 668 | xcp->regs[MIPSInst_FT(ir)]); |
| 625 | 669 | ||
| 626 | MIPS_FPU_EMU_INC_STATS(loads); | 670 | MIPS_FPU_EMU_INC_STATS(loads); |
| 627 | if (get_user(val, va)) { | 671 | if (!access_ok(VERIFY_READ, va, sizeof(u32))) { |
| 628 | MIPS_FPU_EMU_INC_STATS(errors); | 672 | MIPS_FPU_EMU_INC_STATS(errors); |
| 673 | *fault_addr = va; | ||
| 629 | return SIGBUS; | 674 | return SIGBUS; |
| 630 | } | 675 | } |
| 676 | if (__get_user(val, va)) { | ||
| 677 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 678 | *fault_addr = va; | ||
| 679 | return SIGSEGV; | ||
| 680 | } | ||
| 631 | SITOREG(val, MIPSInst_FD(ir)); | 681 | SITOREG(val, MIPSInst_FD(ir)); |
| 632 | break; | 682 | break; |
| 633 | 683 | ||
| @@ -638,10 +688,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
| 638 | MIPS_FPU_EMU_INC_STATS(stores); | 688 | MIPS_FPU_EMU_INC_STATS(stores); |
| 639 | 689 | ||
| 640 | SIFROMREG(val, MIPSInst_FS(ir)); | 690 | SIFROMREG(val, MIPSInst_FS(ir)); |
| 641 | if (put_user(val, va)) { | 691 | if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) { |
| 642 | MIPS_FPU_EMU_INC_STATS(errors); | 692 | MIPS_FPU_EMU_INC_STATS(errors); |
| 693 | *fault_addr = va; | ||
| 643 | return SIGBUS; | 694 | return SIGBUS; |
| 644 | } | 695 | } |
| 696 | if (put_user(val, va)) { | ||
| 697 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 698 | *fault_addr = va; | ||
| 699 | return SIGSEGV; | ||
| 700 | } | ||
| 645 | break; | 701 | break; |
| 646 | 702 | ||
| 647 | case madd_s_op: | 703 | case madd_s_op: |
| @@ -701,10 +757,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
| 701 | xcp->regs[MIPSInst_FT(ir)]); | 757 | xcp->regs[MIPSInst_FT(ir)]); |
| 702 | 758 | ||
| 703 | MIPS_FPU_EMU_INC_STATS(loads); | 759 | MIPS_FPU_EMU_INC_STATS(loads); |
| 704 | if (get_user(val, va)) { | 760 | if (!access_ok(VERIFY_READ, va, sizeof(u64))) { |
| 705 | MIPS_FPU_EMU_INC_STATS(errors); | 761 | MIPS_FPU_EMU_INC_STATS(errors); |
| 762 | *fault_addr = va; | ||
| 706 | return SIGBUS; | 763 | return SIGBUS; |
| 707 | } | 764 | } |
| 765 | if (__get_user(val, va)) { | ||
| 766 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 767 | *fault_addr = va; | ||
| 768 | return SIGSEGV; | ||
| 769 | } | ||
| 708 | DITOREG(val, MIPSInst_FD(ir)); | 770 | DITOREG(val, MIPSInst_FD(ir)); |
| 709 | break; | 771 | break; |
| 710 | 772 | ||
| @@ -714,10 +776,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
| 714 | 776 | ||
| 715 | MIPS_FPU_EMU_INC_STATS(stores); | 777 | MIPS_FPU_EMU_INC_STATS(stores); |
| 716 | DIFROMREG(val, MIPSInst_FS(ir)); | 778 | DIFROMREG(val, MIPSInst_FS(ir)); |
| 717 | if (put_user(val, va)) { | 779 | if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) { |
| 718 | MIPS_FPU_EMU_INC_STATS(errors); | 780 | MIPS_FPU_EMU_INC_STATS(errors); |
| 781 | *fault_addr = va; | ||
| 719 | return SIGBUS; | 782 | return SIGBUS; |
| 720 | } | 783 | } |
| 784 | if (__put_user(val, va)) { | ||
| 785 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 786 | *fault_addr = va; | ||
| 787 | return SIGSEGV; | ||
| 788 | } | ||
| 721 | break; | 789 | break; |
| 722 | 790 | ||
| 723 | case madd_d_op: | 791 | case madd_d_op: |
| @@ -1242,7 +1310,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
| 1242 | } | 1310 | } |
| 1243 | 1311 | ||
| 1244 | int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | 1312 | int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, |
| 1245 | int has_fpu) | 1313 | int has_fpu, void *__user *fault_addr) |
| 1246 | { | 1314 | { |
| 1247 | unsigned long oldepc, prevepc; | 1315 | unsigned long oldepc, prevepc; |
| 1248 | mips_instruction insn; | 1316 | mips_instruction insn; |
| @@ -1252,10 +1320,16 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
| 1252 | do { | 1320 | do { |
| 1253 | prevepc = xcp->cp0_epc; | 1321 | prevepc = xcp->cp0_epc; |
| 1254 | 1322 | ||
| 1255 | if (get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) { | 1323 | if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) { |
| 1256 | MIPS_FPU_EMU_INC_STATS(errors); | 1324 | MIPS_FPU_EMU_INC_STATS(errors); |
| 1325 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
| 1257 | return SIGBUS; | 1326 | return SIGBUS; |
| 1258 | } | 1327 | } |
| 1328 | if (__get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) { | ||
| 1329 | MIPS_FPU_EMU_INC_STATS(errors); | ||
| 1330 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
| 1331 | return SIGSEGV; | ||
| 1332 | } | ||
| 1259 | if (insn == 0) | 1333 | if (insn == 0) |
| 1260 | xcp->cp0_epc += 4; /* skip nops */ | 1334 | xcp->cp0_epc += 4; /* skip nops */ |
| 1261 | else { | 1335 | else { |
| @@ -1267,7 +1341,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
| 1267 | */ | 1341 | */ |
| 1268 | /* convert to ieee library modes */ | 1342 | /* convert to ieee library modes */ |
| 1269 | ieee754_csr.rm = ieee_rm[ieee754_csr.rm]; | 1343 | ieee754_csr.rm = ieee_rm[ieee754_csr.rm]; |
| 1270 | sig = cop1Emulate(xcp, ctx); | 1344 | sig = cop1Emulate(xcp, ctx, fault_addr); |
| 1271 | /* revert to mips rounding mode */ | 1345 | /* revert to mips rounding mode */ |
| 1272 | ieee754_csr.rm = mips_rm[ieee754_csr.rm]; | 1346 | ieee754_csr.rm = mips_rm[ieee754_csr.rm]; |
| 1273 | } | 1347 | } |
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 4fc1a0fbe00..21ea14efb83 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c | |||
| @@ -288,7 +288,7 @@ int mips_dma_supported(struct device *dev, u64 mask) | |||
| 288 | return plat_dma_supported(dev, mask); | 288 | return plat_dma_supported(dev, mask); |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size, | 291 | void dma_cache_sync(struct device *dev, void *vaddr, size_t size, |
| 292 | enum dma_data_direction direction) | 292 | enum dma_data_direction direction) |
| 293 | { | 293 | { |
| 294 | BUG_ON(direction == DMA_NONE); | 294 | BUG_ON(direction == DMA_NONE); |
| @@ -298,6 +298,8 @@ void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size, | |||
| 298 | __dma_sync((unsigned long)vaddr, size, direction); | 298 | __dma_sync((unsigned long)vaddr, size, direction); |
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | EXPORT_SYMBOL(dma_cache_sync); | ||
| 302 | |||
| 301 | static struct dma_map_ops mips_default_dma_map_ops = { | 303 | static struct dma_map_ops mips_default_dma_map_ops = { |
| 302 | .alloc_coherent = mips_dma_alloc_coherent, | 304 | .alloc_coherent = mips_dma_alloc_coherent, |
| 303 | .free_coherent = mips_dma_free_coherent, | 305 | .free_coherent = mips_dma_free_coherent, |
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c index 505fecad468..9cca8de0054 100644 --- a/arch/mips/mm/sc-mips.c +++ b/arch/mips/mm/sc-mips.c | |||
| @@ -68,6 +68,9 @@ static struct bcache_ops mips_sc_ops = { | |||
| 68 | */ | 68 | */ |
| 69 | static inline int mips_sc_is_activated(struct cpuinfo_mips *c) | 69 | static inline int mips_sc_is_activated(struct cpuinfo_mips *c) |
| 70 | { | 70 | { |
| 71 | unsigned int config2 = read_c0_config2(); | ||
| 72 | unsigned int tmp; | ||
| 73 | |||
| 71 | /* Check the bypass bit (L2B) */ | 74 | /* Check the bypass bit (L2B) */ |
| 72 | switch (c->cputype) { | 75 | switch (c->cputype) { |
| 73 | case CPU_34K: | 76 | case CPU_34K: |
| @@ -83,6 +86,7 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c) | |||
| 83 | c->scache.linesz = 2 << tmp; | 86 | c->scache.linesz = 2 << tmp; |
| 84 | else | 87 | else |
| 85 | return 0; | 88 | return 0; |
| 89 | return 1; | ||
| 86 | } | 90 | } |
| 87 | 91 | ||
| 88 | static inline int __init mips_sc_probe(void) | 92 | static inline int __init mips_sc_probe(void) |
diff --git a/arch/mips/pmc-sierra/yosemite/py-console.c b/arch/mips/pmc-sierra/yosemite/py-console.c index b7f1d9c4a8a..434d7b1a8c6 100644 --- a/arch/mips/pmc-sierra/yosemite/py-console.c +++ b/arch/mips/pmc-sierra/yosemite/py-console.c | |||
| @@ -65,11 +65,15 @@ static unsigned char readb_outer_space(unsigned long long phys) | |||
| 65 | 65 | ||
| 66 | __asm__ __volatile__ ( | 66 | __asm__ __volatile__ ( |
| 67 | " .set mips3 \n" | 67 | " .set mips3 \n" |
| 68 | " .set push \n" | ||
| 69 | " .set noreorder \n" | ||
| 70 | " .set nomacro \n" | ||
| 68 | " ld %0, %1 \n" | 71 | " ld %0, %1 \n" |
| 72 | " .set pop \n" | ||
| 69 | " lbu %0, (%0) \n" | 73 | " lbu %0, (%0) \n" |
| 70 | " .set mips0 \n" | 74 | " .set mips0 \n" |
| 71 | : "=r" (res) | 75 | : "=r" (res) |
| 72 | : "m" (vaddr)); | 76 | : "R" (vaddr)); |
| 73 | 77 | ||
| 74 | write_c0_status(sr); | 78 | write_c0_status(sr); |
| 75 | ssnop_4(); | 79 | ssnop_4(); |
| @@ -89,11 +93,15 @@ static void writeb_outer_space(unsigned long long phys, unsigned char c) | |||
| 89 | 93 | ||
| 90 | __asm__ __volatile__ ( | 94 | __asm__ __volatile__ ( |
| 91 | " .set mips3 \n" | 95 | " .set mips3 \n" |
| 96 | " .set push \n" | ||
| 97 | " .set noreorder \n" | ||
| 98 | " .set nomacro \n" | ||
| 92 | " ld %0, %1 \n" | 99 | " ld %0, %1 \n" |
| 100 | " .set pop \n" | ||
| 93 | " sb %2, (%0) \n" | 101 | " sb %2, (%0) \n" |
| 94 | " .set mips0 \n" | 102 | " .set mips0 \n" |
| 95 | : "=&r" (tmp) | 103 | : "=&r" (tmp) |
| 96 | : "m" (vaddr), "r" (c)); | 104 | : "R" (vaddr), "r" (c)); |
| 97 | 105 | ||
| 98 | write_c0_status(sr); | 106 | write_c0_status(sr); |
| 99 | ssnop_4(); | 107 | ssnop_4(); |
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c index c308989fc46..41707a245de 100644 --- a/arch/mips/sibyte/swarm/setup.c +++ b/arch/mips/sibyte/swarm/setup.c | |||
| @@ -82,7 +82,7 @@ int swarm_be_handler(struct pt_regs *regs, int is_fixup) | |||
| 82 | enum swarm_rtc_type { | 82 | enum swarm_rtc_type { |
| 83 | RTC_NONE, | 83 | RTC_NONE, |
| 84 | RTC_XICOR, | 84 | RTC_XICOR, |
| 85 | RTC_M4LT81 | 85 | RTC_M41T81, |
| 86 | }; | 86 | }; |
| 87 | 87 | ||
| 88 | enum swarm_rtc_type swarm_rtc_type; | 88 | enum swarm_rtc_type swarm_rtc_type; |
| @@ -96,7 +96,7 @@ void read_persistent_clock(struct timespec *ts) | |||
| 96 | sec = xicor_get_time(); | 96 | sec = xicor_get_time(); |
| 97 | break; | 97 | break; |
| 98 | 98 | ||
| 99 | case RTC_M4LT81: | 99 | case RTC_M41T81: |
| 100 | sec = m41t81_get_time(); | 100 | sec = m41t81_get_time(); |
| 101 | break; | 101 | break; |
| 102 | 102 | ||
| @@ -115,7 +115,7 @@ int rtc_mips_set_time(unsigned long sec) | |||
| 115 | case RTC_XICOR: | 115 | case RTC_XICOR: |
| 116 | return xicor_set_time(sec); | 116 | return xicor_set_time(sec); |
| 117 | 117 | ||
| 118 | case RTC_M4LT81: | 118 | case RTC_M41T81: |
| 119 | return m41t81_set_time(sec); | 119 | return m41t81_set_time(sec); |
| 120 | 120 | ||
| 121 | case RTC_NONE: | 121 | case RTC_NONE: |
| @@ -141,7 +141,7 @@ void __init plat_mem_setup(void) | |||
| 141 | if (xicor_probe()) | 141 | if (xicor_probe()) |
| 142 | swarm_rtc_type = RTC_XICOR; | 142 | swarm_rtc_type = RTC_XICOR; |
| 143 | if (m41t81_probe()) | 143 | if (m41t81_probe()) |
| 144 | swarm_rtc_type = RTC_M4LT81; | 144 | swarm_rtc_type = RTC_M41T81; |
| 145 | 145 | ||
| 146 | #ifdef CONFIG_VT | 146 | #ifdef CONFIG_VT |
| 147 | screen_info = (struct screen_info) { | 147 | screen_info = (struct screen_info) { |
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 7f217b3a50a..2e9d78d21fd 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
| @@ -22,7 +22,8 @@ config SUPERH | |||
| 22 | select HAVE_SPARSE_IRQ | 22 | select HAVE_SPARSE_IRQ |
| 23 | select RTC_LIB | 23 | select RTC_LIB |
| 24 | select GENERIC_ATOMIC64 | 24 | select GENERIC_ATOMIC64 |
| 25 | select GENERIC_HARDIRQS_NO_DEPRECATED | 25 | # Support the deprecated APIs until MFD and GPIOLIB catch up. |
| 26 | select GENERIC_HARDIRQS_NO_DEPRECATED if !MFD_SUPPORT && !GPIOLIB | ||
| 26 | help | 27 | help |
| 27 | The SuperH is a RISC processor targeted for use in embedded systems | 28 | The SuperH is a RISC processor targeted for use in embedded systems |
| 28 | and consumer electronics; it was also used in the Sega Dreamcast | 29 | and consumer electronics; it was also used in the Sega Dreamcast |
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h index 903cd618eb7..d6741fca89a 100644 --- a/arch/sh/include/asm/unistd_32.h +++ b/arch/sh/include/asm/unistd_32.h | |||
| @@ -368,8 +368,9 @@ | |||
| 368 | #define __NR_sendmsg 355 | 368 | #define __NR_sendmsg 355 |
| 369 | #define __NR_recvmsg 356 | 369 | #define __NR_recvmsg 356 |
| 370 | #define __NR_recvmmsg 357 | 370 | #define __NR_recvmmsg 357 |
| 371 | #define __NR_accept4 358 | ||
| 371 | 372 | ||
| 372 | #define NR_syscalls 358 | 373 | #define NR_syscalls 359 |
| 373 | 374 | ||
| 374 | #ifdef __KERNEL__ | 375 | #ifdef __KERNEL__ |
| 375 | 376 | ||
diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index e872e81add8..6fc347ebe59 100644 --- a/arch/sh/kernel/syscalls_32.S +++ b/arch/sh/kernel/syscalls_32.S | |||
| @@ -375,3 +375,4 @@ ENTRY(sys_call_table) | |||
| 375 | .long sys_sendmsg /* 355 */ | 375 | .long sys_sendmsg /* 355 */ |
| 376 | .long sys_recvmsg | 376 | .long sys_recvmsg |
| 377 | .long sys_recvmmsg | 377 | .long sys_recvmmsg |
| 378 | .long sys_accept4 | ||
diff --git a/arch/sparc/include/asm/openprom.h b/arch/sparc/include/asm/openprom.h index 81cd43432dc..47eaafad15c 100644 --- a/arch/sparc/include/asm/openprom.h +++ b/arch/sparc/include/asm/openprom.h | |||
| @@ -39,7 +39,7 @@ struct linux_dev_v2_funcs { | |||
| 39 | int (*v2_dev_open)(char *devpath); | 39 | int (*v2_dev_open)(char *devpath); |
| 40 | void (*v2_dev_close)(int d); | 40 | void (*v2_dev_close)(int d); |
| 41 | int (*v2_dev_read)(int d, char *buf, int nbytes); | 41 | int (*v2_dev_read)(int d, char *buf, int nbytes); |
| 42 | int (*v2_dev_write)(int d, char *buf, int nbytes); | 42 | int (*v2_dev_write)(int d, const char *buf, int nbytes); |
| 43 | int (*v2_dev_seek)(int d, int hi, int lo); | 43 | int (*v2_dev_seek)(int d, int hi, int lo); |
| 44 | 44 | ||
| 45 | /* Never issued (multistage load support) */ | 45 | /* Never issued (multistage load support) */ |
diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h index 51296a6f500..9e5c64084b8 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h | |||
| @@ -60,25 +60,6 @@ extern char *prom_getbootargs(void); | |||
| 60 | extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes); | 60 | extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes); |
| 61 | extern void prom_unmapio(char *virt_addr, unsigned int num_bytes); | 61 | extern void prom_unmapio(char *virt_addr, unsigned int num_bytes); |
| 62 | 62 | ||
| 63 | /* Device operations. */ | ||
| 64 | |||
| 65 | /* Open the device described by the passed string. Note, that the format | ||
| 66 | * of the string is different on V0 vs. V2->higher proms. The caller must | ||
| 67 | * know what he/she is doing! Returns the device descriptor, an int. | ||
| 68 | */ | ||
| 69 | extern int prom_devopen(char *device_string); | ||
| 70 | |||
| 71 | /* Close a previously opened device described by the passed integer | ||
| 72 | * descriptor. | ||
| 73 | */ | ||
| 74 | extern int prom_devclose(int device_handle); | ||
| 75 | |||
| 76 | /* Do a seek operation on the device described by the passed integer | ||
| 77 | * descriptor. | ||
| 78 | */ | ||
| 79 | extern void prom_seek(int device_handle, unsigned int seek_hival, | ||
| 80 | unsigned int seek_lowval); | ||
| 81 | |||
| 82 | /* Miscellaneous routines, don't really fit in any category per se. */ | 63 | /* Miscellaneous routines, don't really fit in any category per se. */ |
| 83 | 64 | ||
| 84 | /* Reboot the machine with the command line passed. */ | 65 | /* Reboot the machine with the command line passed. */ |
| @@ -121,19 +102,8 @@ extern int prom_getrev(void); | |||
| 121 | /* Get the prom firmware revision. */ | 102 | /* Get the prom firmware revision. */ |
| 122 | extern int prom_getprev(void); | 103 | extern int prom_getprev(void); |
| 123 | 104 | ||
| 124 | /* Character operations to/from the console.... */ | 105 | /* Write a buffer of characters to the console. */ |
| 125 | 106 | extern void prom_console_write_buf(const char *buf, int len); | |
| 126 | /* Non-blocking get character from console. */ | ||
| 127 | extern int prom_nbgetchar(void); | ||
| 128 | |||
| 129 | /* Non-blocking put character to console. */ | ||
| 130 | extern int prom_nbputchar(char character); | ||
| 131 | |||
| 132 | /* Blocking get character from console. */ | ||
| 133 | extern char prom_getchar(void); | ||
| 134 | |||
| 135 | /* Blocking put character to console. */ | ||
| 136 | extern void prom_putchar(char character); | ||
| 137 | 107 | ||
| 138 | /* Prom's internal routines, don't use in kernel/boot code. */ | 108 | /* Prom's internal routines, don't use in kernel/boot code. */ |
| 139 | extern void prom_printf(const char *fmt, ...); | 109 | extern void prom_printf(const char *fmt, ...); |
| @@ -238,7 +208,6 @@ extern int prom_node_has_property(phandle node, char *property); | |||
| 238 | extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, | 208 | extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, |
| 239 | int value_size); | 209 | int value_size); |
| 240 | 210 | ||
| 241 | extern phandle prom_pathtoinode(char *path); | ||
| 242 | extern phandle prom_inst2pkg(int); | 211 | extern phandle prom_inst2pkg(int); |
| 243 | 212 | ||
| 244 | /* Dorking with Bus ranges... */ | 213 | /* Dorking with Bus ranges... */ |
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index c9cc078e3e3..8cd0df34e82 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h | |||
| @@ -67,27 +67,6 @@ extern void prom_init(void *cif_handler, void *cif_stack); | |||
| 67 | /* Boot argument acquisition, returns the boot command line string. */ | 67 | /* Boot argument acquisition, returns the boot command line string. */ |
| 68 | extern char *prom_getbootargs(void); | 68 | extern char *prom_getbootargs(void); |
| 69 | 69 | ||
| 70 | /* Device utilities. */ | ||
| 71 | |||
| 72 | /* Device operations. */ | ||
| 73 | |||
| 74 | /* Open the device described by the passed string. Note, that the format | ||
| 75 | * of the string is different on V0 vs. V2->higher proms. The caller must | ||
| 76 | * know what he/she is doing! Returns the device descriptor, an int. | ||
| 77 | */ | ||
| 78 | extern int prom_devopen(const char *device_string); | ||
| 79 | |||
| 80 | /* Close a previously opened device described by the passed integer | ||
| 81 | * descriptor. | ||
| 82 | */ | ||
| 83 | extern int prom_devclose(int device_handle); | ||
| 84 | |||
| 85 | /* Do a seek operation on the device described by the passed integer | ||
| 86 | * descriptor. | ||
| 87 | */ | ||
| 88 | extern void prom_seek(int device_handle, unsigned int seek_hival, | ||
| 89 | unsigned int seek_lowval); | ||
| 90 | |||
| 91 | /* Miscellaneous routines, don't really fit in any category per se. */ | 70 | /* Miscellaneous routines, don't really fit in any category per se. */ |
| 92 | 71 | ||
| 93 | /* Reboot the machine with the command line passed. */ | 72 | /* Reboot the machine with the command line passed. */ |
| @@ -109,33 +88,14 @@ extern void prom_halt(void) __attribute__ ((noreturn)); | |||
| 109 | /* Halt and power-off the machine. */ | 88 | /* Halt and power-off the machine. */ |
| 110 | extern void prom_halt_power_off(void) __attribute__ ((noreturn)); | 89 | extern void prom_halt_power_off(void) __attribute__ ((noreturn)); |
| 111 | 90 | ||
| 112 | /* Set the PROM 'sync' callback function to the passed function pointer. | ||
| 113 | * When the user gives the 'sync' command at the prom prompt while the | ||
| 114 | * kernel is still active, the prom will call this routine. | ||
| 115 | * | ||
| 116 | */ | ||
| 117 | typedef int (*callback_func_t)(long *cmd); | ||
| 118 | extern void prom_setcallback(callback_func_t func_ptr); | ||
| 119 | |||
| 120 | /* Acquire the IDPROM of the root node in the prom device tree. This | 91 | /* Acquire the IDPROM of the root node in the prom device tree. This |
| 121 | * gets passed a buffer where you would like it stuffed. The return value | 92 | * gets passed a buffer where you would like it stuffed. The return value |
| 122 | * is the format type of this idprom or 0xff on error. | 93 | * is the format type of this idprom or 0xff on error. |
| 123 | */ | 94 | */ |
| 124 | extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); | 95 | extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); |
| 125 | 96 | ||
| 126 | /* Character operations to/from the console.... */ | 97 | /* Write a buffer of characters to the console. */ |
| 127 | 98 | extern void prom_console_write_buf(const char *buf, int len); | |
| 128 | /* Non-blocking get character from console. */ | ||
| 129 | extern int prom_nbgetchar(void); | ||
| 130 | |||
| 131 | /* Non-blocking put character to console. */ | ||
| 132 | extern int prom_nbputchar(char character); | ||
| 133 | |||
| 134 | /* Blocking get character from console. */ | ||
| 135 | extern char prom_getchar(void); | ||
| 136 | |||
| 137 | /* Blocking put character to console. */ | ||
| 138 | extern void prom_putchar(char character); | ||
| 139 | 99 | ||
| 140 | /* Prom's internal routines, don't use in kernel/boot code. */ | 100 | /* Prom's internal routines, don't use in kernel/boot code. */ |
| 141 | extern void prom_printf(const char *fmt, ...); | 101 | extern void prom_printf(const char *fmt, ...); |
| @@ -279,9 +239,7 @@ extern phandle prom_finddevice(const char *name); | |||
| 279 | extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, | 239 | extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, |
| 280 | int value_size); | 240 | int value_size); |
| 281 | 241 | ||
| 282 | extern phandle prom_pathtoinode(const char *path); | ||
| 283 | extern phandle prom_inst2pkg(int); | 242 | extern phandle prom_inst2pkg(int); |
| 284 | extern int prom_service_exists(const char *service_name); | ||
| 285 | extern void prom_sun4v_guest_soft_state(void); | 243 | extern void prom_sun4v_guest_soft_state(void); |
| 286 | 244 | ||
| 287 | extern int prom_ihandle2path(int handle, char *buffer, int bufsize); | 245 | extern int prom_ihandle2path(int handle, char *buffer, int bufsize); |
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 2d51527d810..f01c42661ee 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c | |||
| @@ -114,7 +114,7 @@ void __init leon_init_timers(irq_handler_t counter_fn) | |||
| 114 | if (leon3_gptimer_regs && leon3_irqctrl_regs) { | 114 | if (leon3_gptimer_regs && leon3_irqctrl_regs) { |
| 115 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0); | 115 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0); |
| 116 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld, | 116 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld, |
| 117 | (((1000000 / 100) - 1))); | 117 | (((1000000 / HZ) - 1))); |
| 118 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0); | 118 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0); |
| 119 | 119 | ||
| 120 | #ifdef CONFIG_SMP | 120 | #ifdef CONFIG_SMP |
| @@ -128,7 +128,7 @@ void __init leon_init_timers(irq_handler_t counter_fn) | |||
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0); | 130 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0); |
| 131 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/100) - 1))); | 131 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/HZ) - 1))); |
| 132 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0); | 132 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0); |
| 133 | # endif | 133 | # endif |
| 134 | 134 | ||
diff --git a/arch/sparc/prom/Makefile b/arch/sparc/prom/Makefile index 1b8c073adb4..816c0fa12dc 100644 --- a/arch/sparc/prom/Makefile +++ b/arch/sparc/prom/Makefile | |||
| @@ -6,7 +6,6 @@ ccflags := -Werror | |||
| 6 | 6 | ||
| 7 | lib-y := bootstr_$(BITS).o | 7 | lib-y := bootstr_$(BITS).o |
| 8 | lib-$(CONFIG_SPARC32) += devmap.o | 8 | lib-$(CONFIG_SPARC32) += devmap.o |
| 9 | lib-y += devops_$(BITS).o | ||
| 10 | lib-y += init_$(BITS).o | 9 | lib-y += init_$(BITS).o |
| 11 | lib-$(CONFIG_SPARC32) += memory.o | 10 | lib-$(CONFIG_SPARC32) += memory.o |
| 12 | lib-y += misc_$(BITS).o | 11 | lib-y += misc_$(BITS).o |
diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c index 5340264b78f..48863108a44 100644 --- a/arch/sparc/prom/console_32.c +++ b/arch/sparc/prom/console_32.c | |||
| @@ -16,63 +16,26 @@ | |||
| 16 | 16 | ||
| 17 | extern void restore_current(void); | 17 | extern void restore_current(void); |
| 18 | 18 | ||
| 19 | /* Non blocking get character from console input device, returns -1 | ||
| 20 | * if no input was taken. This can be used for polling. | ||
| 21 | */ | ||
| 22 | int | ||
| 23 | prom_nbgetchar(void) | ||
| 24 | { | ||
| 25 | static char inc; | ||
| 26 | int i = -1; | ||
| 27 | unsigned long flags; | ||
| 28 | |||
| 29 | spin_lock_irqsave(&prom_lock, flags); | ||
| 30 | switch(prom_vers) { | ||
| 31 | case PROM_V0: | ||
| 32 | i = (*(romvec->pv_nbgetchar))(); | ||
| 33 | break; | ||
| 34 | case PROM_V2: | ||
| 35 | case PROM_V3: | ||
| 36 | if( (*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin , &inc, 0x1) == 1) { | ||
| 37 | i = inc; | ||
| 38 | } else { | ||
| 39 | i = -1; | ||
| 40 | } | ||
| 41 | break; | ||
| 42 | default: | ||
| 43 | i = -1; | ||
| 44 | break; | ||
| 45 | }; | ||
| 46 | restore_current(); | ||
| 47 | spin_unlock_irqrestore(&prom_lock, flags); | ||
| 48 | return i; /* Ugh, we could spin forever on unsupported proms ;( */ | ||
| 49 | } | ||
| 50 | |||
| 51 | /* Non blocking put character to console device, returns -1 if | 19 | /* Non blocking put character to console device, returns -1 if |
| 52 | * unsuccessful. | 20 | * unsuccessful. |
| 53 | */ | 21 | */ |
| 54 | int | 22 | static int prom_nbputchar(const char *buf) |
| 55 | prom_nbputchar(char c) | ||
| 56 | { | 23 | { |
| 57 | static char outc; | ||
| 58 | unsigned long flags; | 24 | unsigned long flags; |
| 59 | int i = -1; | 25 | int i = -1; |
| 60 | 26 | ||
| 61 | spin_lock_irqsave(&prom_lock, flags); | 27 | spin_lock_irqsave(&prom_lock, flags); |
| 62 | switch(prom_vers) { | 28 | switch(prom_vers) { |
| 63 | case PROM_V0: | 29 | case PROM_V0: |
| 64 | i = (*(romvec->pv_nbputchar))(c); | 30 | i = (*(romvec->pv_nbputchar))(*buf); |
| 65 | break; | 31 | break; |
| 66 | case PROM_V2: | 32 | case PROM_V2: |
| 67 | case PROM_V3: | 33 | case PROM_V3: |
| 68 | outc = c; | 34 | if ((*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, |
| 69 | if( (*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, &outc, 0x1) == 1) | 35 | buf, 0x1) == 1) |
| 70 | i = 0; | 36 | i = 0; |
| 71 | else | ||
| 72 | i = -1; | ||
| 73 | break; | 37 | break; |
| 74 | default: | 38 | default: |
| 75 | i = -1; | ||
| 76 | break; | 39 | break; |
| 77 | }; | 40 | }; |
| 78 | restore_current(); | 41 | restore_current(); |
| @@ -80,18 +43,14 @@ prom_nbputchar(char c) | |||
| 80 | return i; /* Ugh, we could spin forever on unsupported proms ;( */ | 43 | return i; /* Ugh, we could spin forever on unsupported proms ;( */ |
| 81 | } | 44 | } |
| 82 | 45 | ||
| 83 | /* Blocking version of get character routine above. */ | 46 | void prom_console_write_buf(const char *buf, int len) |
| 84 | char | ||
| 85 | prom_getchar(void) | ||
| 86 | { | 47 | { |
| 87 | int character; | 48 | while (len) { |
| 88 | while((character = prom_nbgetchar()) == -1) ; | 49 | int n = prom_nbputchar(buf); |
| 89 | return (char) character; | 50 | if (n) |
| 51 | continue; | ||
| 52 | len--; | ||
| 53 | buf++; | ||
| 54 | } | ||
| 90 | } | 55 | } |
| 91 | 56 | ||
| 92 | /* Blocking version of put character routine above. */ | ||
| 93 | void | ||
| 94 | prom_putchar(char c) | ||
| 95 | { | ||
| 96 | while(prom_nbputchar(c) == -1) ; | ||
| 97 | } | ||
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c index 10322dc2f55..ed39e75828b 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c | |||
| @@ -15,85 +15,34 @@ | |||
| 15 | 15 | ||
| 16 | extern int prom_stdin, prom_stdout; | 16 | extern int prom_stdin, prom_stdout; |
| 17 | 17 | ||
| 18 | /* Non blocking get character from console input device, returns -1 | 18 | static int __prom_console_write_buf(const char *buf, int len) |
| 19 | * if no input was taken. This can be used for polling. | ||
| 20 | */ | ||
| 21 | inline int | ||
| 22 | prom_nbgetchar(void) | ||
| 23 | { | ||
| 24 | unsigned long args[7]; | ||
| 25 | char inc; | ||
| 26 | |||
| 27 | args[0] = (unsigned long) "read"; | ||
| 28 | args[1] = 3; | ||
| 29 | args[2] = 1; | ||
| 30 | args[3] = (unsigned int) prom_stdin; | ||
| 31 | args[4] = (unsigned long) &inc; | ||
| 32 | args[5] = 1; | ||
| 33 | args[6] = (unsigned long) -1; | ||
| 34 | |||
| 35 | p1275_cmd_direct(args); | ||
| 36 | |||
| 37 | if (args[6] == 1) | ||
| 38 | return inc; | ||
| 39 | return -1; | ||
| 40 | } | ||
| 41 | |||
| 42 | /* Non blocking put character to console device, returns -1 if | ||
| 43 | * unsuccessful. | ||
| 44 | */ | ||
| 45 | inline int | ||
| 46 | prom_nbputchar(char c) | ||
| 47 | { | 19 | { |
| 48 | unsigned long args[7]; | 20 | unsigned long args[7]; |
| 49 | char outc; | 21 | int ret; |
| 50 | |||
| 51 | outc = c; | ||
| 52 | 22 | ||
| 53 | args[0] = (unsigned long) "write"; | 23 | args[0] = (unsigned long) "write"; |
| 54 | args[1] = 3; | 24 | args[1] = 3; |
| 55 | args[2] = 1; | 25 | args[2] = 1; |
| 56 | args[3] = (unsigned int) prom_stdout; | 26 | args[3] = (unsigned int) prom_stdout; |
| 57 | args[4] = (unsigned long) &outc; | 27 | args[4] = (unsigned long) buf; |
| 58 | args[5] = 1; | 28 | args[5] = (unsigned int) len; |
| 59 | args[6] = (unsigned long) -1; | 29 | args[6] = (unsigned long) -1; |
| 60 | 30 | ||
| 61 | p1275_cmd_direct(args); | 31 | p1275_cmd_direct(args); |
| 62 | 32 | ||
| 63 | if (args[6] == 1) | 33 | ret = (int) args[6]; |
| 64 | return 0; | 34 | if (ret < 0) |
| 65 | else | ||
| 66 | return -1; | 35 | return -1; |
| 36 | return ret; | ||
| 67 | } | 37 | } |
| 68 | 38 | ||
| 69 | /* Blocking version of get character routine above. */ | 39 | void prom_console_write_buf(const char *buf, int len) |
| 70 | char | ||
| 71 | prom_getchar(void) | ||
| 72 | { | ||
| 73 | int character; | ||
| 74 | while((character = prom_nbgetchar()) == -1) ; | ||
| 75 | return (char) character; | ||
| 76 | } | ||
| 77 | |||
| 78 | /* Blocking version of put character routine above. */ | ||
| 79 | void | ||
| 80 | prom_putchar(char c) | ||
| 81 | { | 40 | { |
| 82 | prom_nbputchar(c); | 41 | while (len) { |
| 83 | } | 42 | int n = __prom_console_write_buf(buf, len); |
| 84 | 43 | if (n < 0) | |
| 85 | void | 44 | continue; |
| 86 | prom_puts(const char *s, int len) | 45 | len -= n; |
| 87 | { | 46 | buf += len; |
| 88 | unsigned long args[7]; | 47 | } |
| 89 | |||
| 90 | args[0] = (unsigned long) "write"; | ||
| 91 | args[1] = 3; | ||
| 92 | args[2] = 1; | ||
| 93 | args[3] = (unsigned int) prom_stdout; | ||
| 94 | args[4] = (unsigned long) s; | ||
| 95 | args[5] = len; | ||
| 96 | args[6] = (unsigned long) -1; | ||
| 97 | |||
| 98 | p1275_cmd_direct(args); | ||
| 99 | } | 48 | } |
diff --git a/arch/sparc/prom/devops_32.c b/arch/sparc/prom/devops_32.c deleted file mode 100644 index 9c5d4687242..00000000000 --- a/arch/sparc/prom/devops_32.c +++ /dev/null | |||
| @@ -1,87 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * devops.c: Device operations using the PROM. | ||
| 3 | * | ||
| 4 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) | ||
| 5 | */ | ||
| 6 | #include <linux/types.h> | ||
| 7 | #include <linux/kernel.h> | ||
| 8 | #include <linux/sched.h> | ||
| 9 | |||
| 10 | #include <asm/openprom.h> | ||
| 11 | #include <asm/oplib.h> | ||
| 12 | |||
| 13 | extern void restore_current(void); | ||
| 14 | |||
| 15 | /* Open the device described by the string 'dstr'. Returns the handle | ||
| 16 | * to that device used for subsequent operations on that device. | ||
| 17 | * Returns -1 on failure. | ||
| 18 | */ | ||
| 19 | int | ||
| 20 | prom_devopen(char *dstr) | ||
| 21 | { | ||
| 22 | int handle; | ||
| 23 | unsigned long flags; | ||
| 24 | spin_lock_irqsave(&prom_lock, flags); | ||
| 25 | switch(prom_vers) { | ||
| 26 | case PROM_V0: | ||
| 27 | handle = (*(romvec->pv_v0devops.v0_devopen))(dstr); | ||
| 28 | if(handle == 0) handle = -1; | ||
| 29 | break; | ||
| 30 | case PROM_V2: | ||
| 31 | case PROM_V3: | ||
| 32 | handle = (*(romvec->pv_v2devops.v2_dev_open))(dstr); | ||
| 33 | break; | ||
| 34 | default: | ||
| 35 | handle = -1; | ||
| 36 | break; | ||
| 37 | }; | ||
| 38 | restore_current(); | ||
| 39 | spin_unlock_irqrestore(&prom_lock, flags); | ||
| 40 | |||
| 41 | return handle; | ||
| 42 | } | ||
| 43 | |||
| 44 | /* Close the device described by device handle 'dhandle'. */ | ||
| 45 | int | ||
| 46 | prom_devclose(int dhandle) | ||
| 47 | { | ||
| 48 | unsigned long flags; | ||
| 49 | spin_lock_irqsave(&prom_lock, flags); | ||
| 50 | switch(prom_vers) { | ||
| 51 | case PROM_V0: | ||
| 52 | (*(romvec->pv_v0devops.v0_devclose))(dhandle); | ||
| 53 | break; | ||
| 54 | case PROM_V2: | ||
| 55 | case PROM_V3: | ||
| 56 | (*(romvec->pv_v2devops.v2_dev_close))(dhandle); | ||
| 57 | break; | ||
| 58 | default: | ||
| 59 | break; | ||
| 60 | }; | ||
| 61 | restore_current(); | ||
| 62 | spin_unlock_irqrestore(&prom_lock, flags); | ||
| 63 | return 0; | ||
| 64 | } | ||
| 65 | |||
| 66 | /* Seek to specified location described by 'seekhi' and 'seeklo' | ||
| 67 | * for device 'dhandle'. | ||
| 68 | */ | ||
| 69 | void | ||
| 70 | prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) | ||
| 71 | { | ||
| 72 | unsigned long flags; | ||
| 73 | spin_lock_irqsave(&prom_lock, flags); | ||
| 74 | switch(prom_vers) { | ||
| 75 | case PROM_V0: | ||
| 76 | (*(romvec->pv_v0devops.v0_seekdev))(dhandle, seekhi, seeklo); | ||
| 77 | break; | ||
| 78 | case PROM_V2: | ||
| 79 | case PROM_V3: | ||
| 80 | (*(romvec->pv_v2devops.v2_dev_seek))(dhandle, seekhi, seeklo); | ||
| 81 | break; | ||
| 82 | default: | ||
| 83 | break; | ||
| 84 | }; | ||
| 85 | restore_current(); | ||
| 86 | spin_unlock_irqrestore(&prom_lock, flags); | ||
| 87 | } | ||
diff --git a/arch/sparc/prom/devops_64.c b/arch/sparc/prom/devops_64.c deleted file mode 100644 index a017119e7ef..00000000000 --- a/arch/sparc/prom/devops_64.c +++ /dev/null | |||
| @@ -1,67 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * devops.c: Device operations using the PROM. | ||
| 3 | * | ||
| 4 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) | ||
| 5 | * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
| 6 | */ | ||
| 7 | #include <linux/types.h> | ||
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/sched.h> | ||
| 10 | |||
| 11 | #include <asm/openprom.h> | ||
| 12 | #include <asm/oplib.h> | ||
| 13 | |||
| 14 | /* Open the device described by the string 'dstr'. Returns the handle | ||
| 15 | * to that device used for subsequent operations on that device. | ||
| 16 | * Returns 0 on failure. | ||
| 17 | */ | ||
| 18 | int | ||
| 19 | prom_devopen(const char *dstr) | ||
| 20 | { | ||
| 21 | unsigned long args[5]; | ||
| 22 | |||
| 23 | args[0] = (unsigned long) "open"; | ||
| 24 | args[1] = 1; | ||
| 25 | args[2] = 1; | ||
| 26 | args[3] = (unsigned long) dstr; | ||
| 27 | args[4] = (unsigned long) -1; | ||
| 28 | |||
| 29 | p1275_cmd_direct(args); | ||
| 30 | |||
| 31 | return (int) args[4]; | ||
| 32 | } | ||
| 33 | |||
| 34 | /* Close the device described by device handle 'dhandle'. */ | ||
| 35 | int | ||
| 36 | prom_devclose(int dhandle) | ||
| 37 | { | ||
| 38 | unsigned long args[4]; | ||
| 39 | |||
| 40 | args[0] = (unsigned long) "close"; | ||
| 41 | args[1] = 1; | ||
| 42 | args[2] = 0; | ||
| 43 | args[3] = (unsigned int) dhandle; | ||
| 44 | |||
| 45 | p1275_cmd_direct(args); | ||
| 46 | |||
| 47 | return 0; | ||
| 48 | } | ||
| 49 | |||
| 50 | /* Seek to specified location described by 'seekhi' and 'seeklo' | ||
| 51 | * for device 'dhandle'. | ||
| 52 | */ | ||
| 53 | void | ||
| 54 | prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) | ||
| 55 | { | ||
| 56 | unsigned long args[7]; | ||
| 57 | |||
| 58 | args[0] = (unsigned long) "seek"; | ||
| 59 | args[1] = 3; | ||
| 60 | args[2] = 1; | ||
| 61 | args[3] = (unsigned int) dhandle; | ||
| 62 | args[4] = seekhi; | ||
| 63 | args[5] = seeklo; | ||
| 64 | args[6] = (unsigned long) -1; | ||
| 65 | |||
| 66 | p1275_cmd_direct(args); | ||
| 67 | } | ||
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c index d24bc44e361..e4f31d4d371 100644 --- a/arch/sparc/prom/misc_64.c +++ b/arch/sparc/prom/misc_64.c | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | #include <asm/system.h> | 18 | #include <asm/system.h> |
| 19 | #include <asm/ldc.h> | 19 | #include <asm/ldc.h> |
| 20 | 20 | ||
| 21 | int prom_service_exists(const char *service_name) | 21 | static int prom_service_exists(const char *service_name) |
| 22 | { | 22 | { |
| 23 | unsigned long args[5]; | 23 | unsigned long args[5]; |
| 24 | 24 | ||
| @@ -150,20 +150,6 @@ void prom_halt_power_off(void) | |||
| 150 | prom_halt(); | 150 | prom_halt(); |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | /* Set prom sync handler to call function 'funcp'. */ | ||
| 154 | void prom_setcallback(callback_func_t funcp) | ||
| 155 | { | ||
| 156 | unsigned long args[5]; | ||
| 157 | if (!funcp) | ||
| 158 | return; | ||
| 159 | args[0] = (unsigned long) "set-callback"; | ||
| 160 | args[1] = 1; | ||
| 161 | args[2] = 1; | ||
| 162 | args[3] = (unsigned long) funcp; | ||
| 163 | args[4] = (unsigned long) -1; | ||
| 164 | p1275_cmd_direct(args); | ||
| 165 | } | ||
| 166 | |||
| 167 | /* Get the idprom and stuff it into buffer 'idbuf'. Returns the | 153 | /* Get the idprom and stuff it into buffer 'idbuf'. Returns the |
| 168 | * format type. 'num_bytes' is the number of bytes that your idbuf | 154 | * format type. 'num_bytes' is the number of bytes that your idbuf |
| 169 | * has space for. Returns 0xff on error. | 155 | * has space for. Returns 0xff on error. |
diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c index ca869266b9f..d9682f06b3b 100644 --- a/arch/sparc/prom/printf.c +++ b/arch/sparc/prom/printf.c | |||
| @@ -15,22 +15,45 @@ | |||
| 15 | 15 | ||
| 16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/compiler.h> | 17 | #include <linux/compiler.h> |
| 18 | #include <linux/spinlock.h> | ||
| 18 | 19 | ||
| 19 | #include <asm/openprom.h> | 20 | #include <asm/openprom.h> |
| 20 | #include <asm/oplib.h> | 21 | #include <asm/oplib.h> |
| 21 | 22 | ||
| 23 | #define CONSOLE_WRITE_BUF_SIZE 1024 | ||
| 24 | |||
| 22 | static char ppbuf[1024]; | 25 | static char ppbuf[1024]; |
| 26 | static char console_write_buf[CONSOLE_WRITE_BUF_SIZE]; | ||
| 27 | static DEFINE_RAW_SPINLOCK(console_write_lock); | ||
| 23 | 28 | ||
| 24 | void notrace prom_write(const char *buf, unsigned int n) | 29 | void notrace prom_write(const char *buf, unsigned int n) |
| 25 | { | 30 | { |
| 26 | char ch; | 31 | unsigned int dest_len; |
| 32 | unsigned long flags; | ||
| 33 | char *dest; | ||
| 34 | |||
| 35 | dest = console_write_buf; | ||
| 36 | raw_spin_lock_irqsave(&console_write_lock, flags); | ||
| 27 | 37 | ||
| 28 | while (n != 0) { | 38 | dest_len = 0; |
| 29 | --n; | 39 | while (n-- != 0) { |
| 30 | if ((ch = *buf++) == '\n') | 40 | char ch = *buf++; |
| 31 | prom_putchar('\r'); | 41 | if (ch == '\n') { |
| 32 | prom_putchar(ch); | 42 | *dest++ = '\r'; |
| 43 | dest_len++; | ||
| 44 | } | ||
| 45 | *dest++ = ch; | ||
| 46 | dest_len++; | ||
| 47 | if (dest_len >= CONSOLE_WRITE_BUF_SIZE - 1) { | ||
| 48 | prom_console_write_buf(console_write_buf, dest_len); | ||
| 49 | dest = console_write_buf; | ||
| 50 | dest_len = 0; | ||
| 51 | } | ||
| 33 | } | 52 | } |
| 53 | if (dest_len) | ||
| 54 | prom_console_write_buf(console_write_buf, dest_len); | ||
| 55 | |||
| 56 | raw_spin_unlock_irqrestore(&console_write_lock, flags); | ||
| 34 | } | 57 | } |
| 35 | 58 | ||
| 36 | void notrace prom_printf(const char *fmt, ...) | 59 | void notrace prom_printf(const char *fmt, ...) |
diff --git a/arch/sparc/prom/tree_32.c b/arch/sparc/prom/tree_32.c index 63e08e14977..535e2e69ac1 100644 --- a/arch/sparc/prom/tree_32.c +++ b/arch/sparc/prom/tree_32.c | |||
| @@ -342,19 +342,3 @@ phandle prom_inst2pkg(int inst) | |||
| 342 | if (node == -1) return 0; | 342 | if (node == -1) return 0; |
| 343 | return node; | 343 | return node; |
| 344 | } | 344 | } |
| 345 | |||
| 346 | /* Return 'node' assigned to a particular prom 'path' | ||
| 347 | * FIXME: Should work for v0 as well | ||
| 348 | */ | ||
| 349 | phandle prom_pathtoinode(char *path) | ||
| 350 | { | ||
| 351 | phandle node; | ||
| 352 | int inst; | ||
| 353 | |||
| 354 | inst = prom_devopen (path); | ||
| 355 | if (inst == -1) return 0; | ||
| 356 | node = prom_inst2pkg (inst); | ||
| 357 | prom_devclose (inst); | ||
| 358 | if (node == -1) return 0; | ||
| 359 | return node; | ||
| 360 | } | ||
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c index 691be68932f..d9366004837 100644 --- a/arch/sparc/prom/tree_64.c +++ b/arch/sparc/prom/tree_64.c | |||
| @@ -374,24 +374,6 @@ inline phandle prom_inst2pkg(int inst) | |||
| 374 | return node; | 374 | return node; |
| 375 | } | 375 | } |
| 376 | 376 | ||
| 377 | /* Return 'node' assigned to a particular prom 'path' | ||
| 378 | * FIXME: Should work for v0 as well | ||
| 379 | */ | ||
| 380 | phandle prom_pathtoinode(const char *path) | ||
| 381 | { | ||
| 382 | phandle node; | ||
| 383 | int inst; | ||
| 384 | |||
| 385 | inst = prom_devopen (path); | ||
| 386 | if (inst == 0) | ||
| 387 | return 0; | ||
| 388 | node = prom_inst2pkg(inst); | ||
| 389 | prom_devclose(inst); | ||
| 390 | if (node == -1) | ||
| 391 | return 0; | ||
| 392 | return node; | ||
| 393 | } | ||
| 394 | |||
| 395 | int prom_ihandle2path(int handle, char *buffer, int bufsize) | 377 | int prom_ihandle2path(int handle, char *buffer, int bufsize) |
| 396 | { | 378 | { |
| 397 | unsigned long args[7]; | 379 | unsigned long args[7]; |
diff --git a/arch/tile/include/asm/signal.h b/arch/tile/include/asm/signal.h index c1ee1d61d44..81d92a45cd4 100644 --- a/arch/tile/include/asm/signal.h +++ b/arch/tile/include/asm/signal.h | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | 25 | ||
| 26 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) | 26 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) |
| 27 | struct pt_regs; | 27 | struct pt_regs; |
| 28 | int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *); | 28 | int restore_sigcontext(struct pt_regs *, struct sigcontext __user *); |
| 29 | int setup_sigcontext(struct sigcontext __user *, struct pt_regs *); | 29 | int setup_sigcontext(struct sigcontext __user *, struct pt_regs *); |
| 30 | void do_signal(struct pt_regs *regs); | 30 | void do_signal(struct pt_regs *regs); |
| 31 | #endif | 31 | #endif |
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c index 543d6a33aa2..dbb0dfc7bec 100644 --- a/arch/tile/kernel/compat_signal.c +++ b/arch/tile/kernel/compat_signal.c | |||
| @@ -290,12 +290,12 @@ long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, | |||
| 290 | return ret; | 290 | return ret; |
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | /* The assembly shim for this function arranges to ignore the return value. */ | ||
| 293 | long compat_sys_rt_sigreturn(struct pt_regs *regs) | 294 | long compat_sys_rt_sigreturn(struct pt_regs *regs) |
| 294 | { | 295 | { |
| 295 | struct compat_rt_sigframe __user *frame = | 296 | struct compat_rt_sigframe __user *frame = |
| 296 | (struct compat_rt_sigframe __user *) compat_ptr(regs->sp); | 297 | (struct compat_rt_sigframe __user *) compat_ptr(regs->sp); |
| 297 | sigset_t set; | 298 | sigset_t set; |
| 298 | long r0; | ||
| 299 | 299 | ||
| 300 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 300 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
| 301 | goto badframe; | 301 | goto badframe; |
| @@ -308,13 +308,13 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs) | |||
| 308 | recalc_sigpending(); | 308 | recalc_sigpending(); |
| 309 | spin_unlock_irq(¤t->sighand->siglock); | 309 | spin_unlock_irq(¤t->sighand->siglock); |
| 310 | 310 | ||
| 311 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) | 311 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) |
| 312 | goto badframe; | 312 | goto badframe; |
| 313 | 313 | ||
| 314 | if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0) | 314 | if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0) |
| 315 | goto badframe; | 315 | goto badframe; |
| 316 | 316 | ||
| 317 | return r0; | 317 | return 0; |
| 318 | 318 | ||
| 319 | badframe: | 319 | badframe: |
| 320 | force_sig(SIGSEGV, current); | 320 | force_sig(SIGSEGV, current); |
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index f5821626247..5eed4a02bf6 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S | |||
| @@ -1342,8 +1342,8 @@ handle_syscall: | |||
| 1342 | lw r20, r20 | 1342 | lw r20, r20 |
| 1343 | 1343 | ||
| 1344 | /* Jump to syscall handler. */ | 1344 | /* Jump to syscall handler. */ |
| 1345 | jalr r20; .Lhandle_syscall_link: | 1345 | jalr r20 |
| 1346 | FEEDBACK_REENTER(handle_syscall) | 1346 | .Lhandle_syscall_link: /* value of "lr" after "jalr r20" above */ |
| 1347 | 1347 | ||
| 1348 | /* | 1348 | /* |
| 1349 | * Write our r0 onto the stack so it gets restored instead | 1349 | * Write our r0 onto the stack so it gets restored instead |
| @@ -1352,6 +1352,9 @@ handle_syscall: | |||
| 1352 | PTREGS_PTR(r29, PTREGS_OFFSET_REG(0)) | 1352 | PTREGS_PTR(r29, PTREGS_OFFSET_REG(0)) |
| 1353 | sw r29, r0 | 1353 | sw r29, r0 |
| 1354 | 1354 | ||
| 1355 | .Lsyscall_sigreturn_skip: | ||
| 1356 | FEEDBACK_REENTER(handle_syscall) | ||
| 1357 | |||
| 1355 | /* Do syscall trace again, if requested. */ | 1358 | /* Do syscall trace again, if requested. */ |
| 1356 | lw r30, r31 | 1359 | lw r30, r31 |
| 1357 | andi r30, r30, _TIF_SYSCALL_TRACE | 1360 | andi r30, r30, _TIF_SYSCALL_TRACE |
| @@ -1536,9 +1539,24 @@ STD_ENTRY_LOCAL(bad_intr) | |||
| 1536 | }; \ | 1539 | }; \ |
| 1537 | STD_ENDPROC(_##x) | 1540 | STD_ENDPROC(_##x) |
| 1538 | 1541 | ||
| 1542 | /* | ||
| 1543 | * Special-case sigreturn to not write r0 to the stack on return. | ||
| 1544 | * This is technically more efficient, but it also avoids difficulties | ||
| 1545 | * in the 64-bit OS when handling 32-bit compat code, since we must not | ||
| 1546 | * sign-extend r0 for the sigreturn return-value case. | ||
| 1547 | */ | ||
| 1548 | #define PTREGS_SYSCALL_SIGRETURN(x, reg) \ | ||
| 1549 | STD_ENTRY(_##x); \ | ||
| 1550 | addli lr, lr, .Lsyscall_sigreturn_skip - .Lhandle_syscall_link; \ | ||
| 1551 | { \ | ||
| 1552 | PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \ | ||
| 1553 | j x \ | ||
| 1554 | }; \ | ||
| 1555 | STD_ENDPROC(_##x) | ||
| 1556 | |||
| 1539 | PTREGS_SYSCALL(sys_execve, r3) | 1557 | PTREGS_SYSCALL(sys_execve, r3) |
| 1540 | PTREGS_SYSCALL(sys_sigaltstack, r2) | 1558 | PTREGS_SYSCALL(sys_sigaltstack, r2) |
| 1541 | PTREGS_SYSCALL(sys_rt_sigreturn, r0) | 1559 | PTREGS_SYSCALL_SIGRETURN(sys_rt_sigreturn, r0) |
| 1542 | PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1) | 1560 | PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1) |
| 1543 | 1561 | ||
| 1544 | /* Save additional callee-saves to pt_regs, put address in r4 and jump. */ | 1562 | /* Save additional callee-saves to pt_regs, put address in r4 and jump. */ |
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c index 8430f45daea..e90eb53173b 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c | |||
| @@ -212,6 +212,13 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
| 212 | childregs->sp = sp; /* override with new user stack pointer */ | 212 | childregs->sp = sp; /* override with new user stack pointer */ |
| 213 | 213 | ||
| 214 | /* | 214 | /* |
| 215 | * If CLONE_SETTLS is set, set "tp" in the new task to "r4", | ||
| 216 | * which is passed in as arg #5 to sys_clone(). | ||
| 217 | */ | ||
| 218 | if (clone_flags & CLONE_SETTLS) | ||
| 219 | childregs->tp = regs->regs[4]; | ||
| 220 | |||
| 221 | /* | ||
| 215 | * Copy the callee-saved registers from the passed pt_regs struct | 222 | * Copy the callee-saved registers from the passed pt_regs struct |
| 216 | * into the context-switch callee-saved registers area. | 223 | * into the context-switch callee-saved registers area. |
| 217 | * This way when we start the interrupt-return sequence, the | 224 | * This way when we start the interrupt-return sequence, the |
| @@ -539,6 +546,7 @@ struct task_struct *__sched _switch_to(struct task_struct *prev, | |||
| 539 | return __switch_to(prev, next, next_current_ksp0(next)); | 546 | return __switch_to(prev, next, next_current_ksp0(next)); |
| 540 | } | 547 | } |
| 541 | 548 | ||
| 549 | /* Note there is an implicit fifth argument if (clone_flags & CLONE_SETTLS). */ | ||
| 542 | SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, | 550 | SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, |
| 543 | void __user *, parent_tidptr, void __user *, child_tidptr, | 551 | void __user *, parent_tidptr, void __user *, child_tidptr, |
| 544 | struct pt_regs *, regs) | 552 | struct pt_regs *, regs) |
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c index 757407e3669..1260321155f 100644 --- a/arch/tile/kernel/signal.c +++ b/arch/tile/kernel/signal.c | |||
| @@ -52,7 +52,7 @@ SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss, | |||
| 52 | */ | 52 | */ |
| 53 | 53 | ||
| 54 | int restore_sigcontext(struct pt_regs *regs, | 54 | int restore_sigcontext(struct pt_regs *regs, |
| 55 | struct sigcontext __user *sc, long *pr0) | 55 | struct sigcontext __user *sc) |
| 56 | { | 56 | { |
| 57 | int err = 0; | 57 | int err = 0; |
| 58 | int i; | 58 | int i; |
| @@ -75,17 +75,15 @@ int restore_sigcontext(struct pt_regs *regs, | |||
| 75 | 75 | ||
| 76 | regs->faultnum = INT_SWINT_1_SIGRETURN; | 76 | regs->faultnum = INT_SWINT_1_SIGRETURN; |
| 77 | 77 | ||
| 78 | err |= __get_user(*pr0, &sc->gregs[0]); | ||
| 79 | return err; | 78 | return err; |
| 80 | } | 79 | } |
| 81 | 80 | ||
| 82 | /* sigreturn() returns long since it restores r0 in the interrupted code. */ | 81 | /* The assembly shim for this function arranges to ignore the return value. */ |
| 83 | SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) | 82 | SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) |
| 84 | { | 83 | { |
| 85 | struct rt_sigframe __user *frame = | 84 | struct rt_sigframe __user *frame = |
| 86 | (struct rt_sigframe __user *)(regs->sp); | 85 | (struct rt_sigframe __user *)(regs->sp); |
| 87 | sigset_t set; | 86 | sigset_t set; |
| 88 | long r0; | ||
| 89 | 87 | ||
| 90 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 88 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
| 91 | goto badframe; | 89 | goto badframe; |
| @@ -98,13 +96,13 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) | |||
| 98 | recalc_sigpending(); | 96 | recalc_sigpending(); |
| 99 | spin_unlock_irq(¤t->sighand->siglock); | 97 | spin_unlock_irq(¤t->sighand->siglock); |
| 100 | 98 | ||
| 101 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) | 99 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) |
| 102 | goto badframe; | 100 | goto badframe; |
| 103 | 101 | ||
| 104 | if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) | 102 | if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) |
| 105 | goto badframe; | 103 | goto badframe; |
| 106 | 104 | ||
| 107 | return r0; | 105 | return 0; |
| 108 | 106 | ||
| 109 | badframe: | 107 | badframe: |
| 110 | force_sig(SIGSEGV, current); | 108 | force_sig(SIGSEGV, current); |
diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c index cbcc8d8ea93..7a6e68e4f74 100644 --- a/arch/x86/crypto/ghash-clmulni-intel_glue.c +++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | * by the Free Software Foundation. | 10 | * by the Free Software Foundation. |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/err.h> | ||
| 13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h index 5be1542fbfa..e99d55d74df 100644 --- a/arch/x86/include/asm/e820.h +++ b/arch/x86/include/asm/e820.h | |||
| @@ -72,6 +72,9 @@ struct e820map { | |||
| 72 | #define BIOS_BEGIN 0x000a0000 | 72 | #define BIOS_BEGIN 0x000a0000 |
| 73 | #define BIOS_END 0x00100000 | 73 | #define BIOS_END 0x00100000 |
| 74 | 74 | ||
| 75 | #define BIOS_ROM_BASE 0xffe00000 | ||
| 76 | #define BIOS_ROM_END 0xffffffff | ||
| 77 | |||
| 75 | #ifdef __KERNEL__ | 78 | #ifdef __KERNEL__ |
| 76 | /* see comment in arch/x86/kernel/e820.c */ | 79 | /* see comment in arch/x86/kernel/e820.c */ |
| 77 | extern struct e820map e820; | 80 | extern struct e820map e820; |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 9e6fe391094..f702f82aa1e 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
| @@ -79,7 +79,7 @@ | |||
| 79 | #define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT) | 79 | #define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT) |
| 80 | #define KVM_MIN_FREE_MMU_PAGES 5 | 80 | #define KVM_MIN_FREE_MMU_PAGES 5 |
| 81 | #define KVM_REFILL_PAGES 25 | 81 | #define KVM_REFILL_PAGES 25 |
| 82 | #define KVM_MAX_CPUID_ENTRIES 40 | 82 | #define KVM_MAX_CPUID_ENTRIES 80 |
| 83 | #define KVM_NR_FIXED_MTRR_REGION 88 | 83 | #define KVM_NR_FIXED_MTRR_REGION 88 |
| 84 | #define KVM_NR_VAR_MTRR 8 | 84 | #define KVM_NR_VAR_MTRR 8 |
| 85 | 85 | ||
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 9e13763b609..1e994754d32 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
| @@ -45,6 +45,7 @@ obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o | |||
| 45 | obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o | 45 | obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o |
| 46 | obj-y += tsc.o io_delay.o rtc.o | 46 | obj-y += tsc.o io_delay.o rtc.o |
| 47 | obj-y += pci-iommu_table.o | 47 | obj-y += pci-iommu_table.o |
| 48 | obj-y += resource.o | ||
| 48 | 49 | ||
| 49 | obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o | 50 | obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o |
| 50 | obj-y += process.o | 51 | obj-y += process.o |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index bcece91dd31..f0bea76f6ea 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
| @@ -620,13 +620,13 @@ ENTRY(initial_code) | |||
| 620 | __PAGE_ALIGNED_BSS | 620 | __PAGE_ALIGNED_BSS |
| 621 | .align PAGE_SIZE_asm | 621 | .align PAGE_SIZE_asm |
| 622 | #ifdef CONFIG_X86_PAE | 622 | #ifdef CONFIG_X86_PAE |
| 623 | initial_pg_pmd: | 623 | ENTRY(initial_pg_pmd) |
| 624 | .fill 1024*KPMDS,4,0 | 624 | .fill 1024*KPMDS,4,0 |
| 625 | #else | 625 | #else |
| 626 | ENTRY(initial_page_table) | 626 | ENTRY(initial_page_table) |
| 627 | .fill 1024,4,0 | 627 | .fill 1024,4,0 |
| 628 | #endif | 628 | #endif |
| 629 | initial_pg_fixmap: | 629 | ENTRY(initial_pg_fixmap) |
| 630 | .fill 1024,4,0 | 630 | .fill 1024,4,0 |
| 631 | ENTRY(empty_zero_page) | 631 | ENTRY(empty_zero_page) |
| 632 | .fill 4096,1,0 | 632 | .fill 4096,1,0 |
diff --git a/arch/x86/kernel/resource.c b/arch/x86/kernel/resource.c new file mode 100644 index 00000000000..2a26819bb6a --- /dev/null +++ b/arch/x86/kernel/resource.c | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | #include <linux/ioport.h> | ||
| 2 | #include <asm/e820.h> | ||
| 3 | |||
| 4 | static void resource_clip(struct resource *res, resource_size_t start, | ||
| 5 | resource_size_t end) | ||
| 6 | { | ||
| 7 | resource_size_t low = 0, high = 0; | ||
| 8 | |||
| 9 | if (res->end < start || res->start > end) | ||
| 10 | return; /* no conflict */ | ||
| 11 | |||
| 12 | if (res->start < start) | ||
| 13 | low = start - res->start; | ||
| 14 | |||
| 15 | if (res->end > end) | ||
| 16 | high = res->end - end; | ||
| 17 | |||
| 18 | /* Keep the area above or below the conflict, whichever is larger */ | ||
| 19 | if (low > high) | ||
| 20 | res->end = start - 1; | ||
| 21 | else | ||
| 22 | res->start = end + 1; | ||
| 23 | } | ||
| 24 | |||
| 25 | static void remove_e820_regions(struct resource *avail) | ||
| 26 | { | ||
| 27 | int i; | ||
| 28 | struct e820entry *entry; | ||
| 29 | |||
| 30 | for (i = 0; i < e820.nr_map; i++) { | ||
| 31 | entry = &e820.map[i]; | ||
| 32 | |||
| 33 | resource_clip(avail, entry->addr, | ||
| 34 | entry->addr + entry->size - 1); | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | void arch_remove_reservations(struct resource *avail) | ||
| 39 | { | ||
| 40 | /* Trim out BIOS areas (low 1MB and high 2MB) and E820 regions */ | ||
| 41 | if (avail->flags & IORESOURCE_MEM) { | ||
| 42 | if (avail->start < BIOS_END) | ||
| 43 | avail->start = BIOS_END; | ||
| 44 | resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END); | ||
| 45 | |||
| 46 | remove_e820_regions(avail); | ||
| 47 | } | ||
| 48 | } | ||
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 21c6746338a..85268f8eadf 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
| @@ -769,7 +769,6 @@ void __init setup_arch(char **cmdline_p) | |||
| 769 | 769 | ||
| 770 | x86_init.oem.arch_setup(); | 770 | x86_init.oem.arch_setup(); |
| 771 | 771 | ||
| 772 | resource_alloc_from_bottom = 0; | ||
| 773 | iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1; | 772 | iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1; |
| 774 | setup_memory_map(); | 773 | setup_memory_map(); |
| 775 | parse_setup_data(); | 774 | parse_setup_data(); |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 1ca12298ffc..b81a9b7c2ca 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
| @@ -3494,6 +3494,10 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu) | |||
| 3494 | static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) | 3494 | static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) |
| 3495 | { | 3495 | { |
| 3496 | switch (func) { | 3496 | switch (func) { |
| 3497 | case 0x00000001: | ||
| 3498 | /* Mask out xsave bit as long as it is not supported by SVM */ | ||
| 3499 | entry->ecx &= ~(bit(X86_FEATURE_XSAVE)); | ||
| 3500 | break; | ||
| 3497 | case 0x80000001: | 3501 | case 0x80000001: |
| 3498 | if (nested) | 3502 | if (nested) |
| 3499 | entry->ecx |= (1 << 2); /* Set SVM bit */ | 3503 | entry->ecx |= (1 << 2); /* Set SVM bit */ |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ff21fdda0c5..81fcbe9515c 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -4227,11 +4227,6 @@ static int vmx_get_lpage_level(void) | |||
| 4227 | return PT_PDPE_LEVEL; | 4227 | return PT_PDPE_LEVEL; |
| 4228 | } | 4228 | } |
| 4229 | 4229 | ||
| 4230 | static inline u32 bit(int bitno) | ||
| 4231 | { | ||
| 4232 | return 1 << (bitno & 31); | ||
| 4233 | } | ||
| 4234 | |||
| 4235 | static void vmx_cpuid_update(struct kvm_vcpu *vcpu) | 4230 | static void vmx_cpuid_update(struct kvm_vcpu *vcpu) |
| 4236 | { | 4231 | { |
| 4237 | struct kvm_cpuid_entry2 *best; | 4232 | struct kvm_cpuid_entry2 *best; |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index cdac9e592aa..b989e1f1e5d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -155,11 +155,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
| 155 | 155 | ||
| 156 | u64 __read_mostly host_xcr0; | 156 | u64 __read_mostly host_xcr0; |
| 157 | 157 | ||
| 158 | static inline u32 bit(int bitno) | ||
| 159 | { | ||
| 160 | return 1 << (bitno & 31); | ||
| 161 | } | ||
| 162 | |||
| 163 | static void kvm_on_user_return(struct user_return_notifier *urn) | 158 | static void kvm_on_user_return(struct user_return_notifier *urn) |
| 164 | { | 159 | { |
| 165 | unsigned slot; | 160 | unsigned slot; |
| @@ -4569,9 +4564,11 @@ static void kvm_timer_init(void) | |||
| 4569 | #ifdef CONFIG_CPU_FREQ | 4564 | #ifdef CONFIG_CPU_FREQ |
| 4570 | struct cpufreq_policy policy; | 4565 | struct cpufreq_policy policy; |
| 4571 | memset(&policy, 0, sizeof(policy)); | 4566 | memset(&policy, 0, sizeof(policy)); |
| 4572 | cpufreq_get_policy(&policy, get_cpu()); | 4567 | cpu = get_cpu(); |
| 4568 | cpufreq_get_policy(&policy, cpu); | ||
| 4573 | if (policy.cpuinfo.max_freq) | 4569 | if (policy.cpuinfo.max_freq) |
| 4574 | max_tsc_khz = policy.cpuinfo.max_freq; | 4570 | max_tsc_khz = policy.cpuinfo.max_freq; |
| 4571 | put_cpu(); | ||
| 4575 | #endif | 4572 | #endif |
| 4576 | cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block, | 4573 | cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block, |
| 4577 | CPUFREQ_TRANSITION_NOTIFIER); | 4574 | CPUFREQ_TRANSITION_NOTIFIER); |
| @@ -5522,6 +5519,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | |||
| 5522 | 5519 | ||
| 5523 | mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4; | 5520 | mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4; |
| 5524 | kvm_x86_ops->set_cr4(vcpu, sregs->cr4); | 5521 | kvm_x86_ops->set_cr4(vcpu, sregs->cr4); |
| 5522 | if (sregs->cr4 & X86_CR4_OSXSAVE) | ||
| 5523 | update_cpuid(vcpu); | ||
| 5525 | if (!is_long_mode(vcpu) && is_pae(vcpu)) { | 5524 | if (!is_long_mode(vcpu) && is_pae(vcpu)) { |
| 5526 | load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3); | 5525 | load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3); |
| 5527 | mmu_reset_needed = 1; | 5526 | mmu_reset_needed = 1; |
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 2cea414489f..c600da830ce 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h | |||
| @@ -70,6 +70,11 @@ static inline int is_paging(struct kvm_vcpu *vcpu) | |||
| 70 | return kvm_read_cr0_bits(vcpu, X86_CR0_PG); | 70 | return kvm_read_cr0_bits(vcpu, X86_CR0_PG); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | static inline u32 bit(int bitno) | ||
| 74 | { | ||
| 75 | return 1 << (bitno & 31); | ||
| 76 | } | ||
| 77 | |||
| 73 | void kvm_before_handle_nmi(struct kvm_vcpu *vcpu); | 78 | void kvm_before_handle_nmi(struct kvm_vcpu *vcpu); |
| 74 | void kvm_after_handle_nmi(struct kvm_vcpu *vcpu); | 79 | void kvm_after_handle_nmi(struct kvm_vcpu *vcpu); |
| 75 | int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq); | 80 | int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq); |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 73b1e1a1f48..4996cf5f73a 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
| @@ -531,7 +531,10 @@ static void lguest_write_cr3(unsigned long cr3) | |||
| 531 | { | 531 | { |
| 532 | lguest_data.pgdir = cr3; | 532 | lguest_data.pgdir = cr3; |
| 533 | lazy_hcall1(LHCALL_NEW_PGTABLE, cr3); | 533 | lazy_hcall1(LHCALL_NEW_PGTABLE, cr3); |
| 534 | cr3_changed = true; | 534 | |
| 535 | /* These two page tables are simple, linear, and used during boot */ | ||
| 536 | if (cr3 != __pa(swapper_pg_dir) && cr3 != __pa(initial_page_table)) | ||
| 537 | cr3_changed = true; | ||
| 535 | } | 538 | } |
| 536 | 539 | ||
| 537 | static unsigned long lguest_read_cr3(void) | 540 | static unsigned long lguest_read_cr3(void) |
| @@ -703,9 +706,9 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval) | |||
| 703 | * to forget all of them. Fortunately, this is very rare. | 706 | * to forget all of them. Fortunately, this is very rare. |
| 704 | * | 707 | * |
| 705 | * ... except in early boot when the kernel sets up the initial pagetables, | 708 | * ... except in early boot when the kernel sets up the initial pagetables, |
| 706 | * which makes booting astonishingly slow: 1.83 seconds! So we don't even tell | 709 | * which makes booting astonishingly slow: 48 seconds! So we don't even tell |
| 707 | * the Host anything changed until we've done the first page table switch, | 710 | * the Host anything changed until we've done the first real page table switch, |
| 708 | * which brings boot back to 0.25 seconds. | 711 | * which brings boot back to 4.3 seconds. |
| 709 | */ | 712 | */ |
| 710 | static void lguest_set_pte(pte_t *ptep, pte_t pteval) | 713 | static void lguest_set_pte(pte_t *ptep, pte_t pteval) |
| 711 | { | 714 | { |
| @@ -1002,7 +1005,7 @@ static void lguest_time_init(void) | |||
| 1002 | clockevents_register_device(&lguest_clockevent); | 1005 | clockevents_register_device(&lguest_clockevent); |
| 1003 | 1006 | ||
| 1004 | /* Finally, we unblock the timer interrupt. */ | 1007 | /* Finally, we unblock the timer interrupt. */ |
| 1005 | enable_lguest_irq(0); | 1008 | clear_bit(0, lguest_data.blocked_interrupts); |
| 1006 | } | 1009 | } |
| 1007 | 1010 | ||
| 1008 | /* | 1011 | /* |
| @@ -1349,9 +1352,6 @@ __init void lguest_init(void) | |||
| 1349 | */ | 1352 | */ |
| 1350 | switch_to_new_gdt(0); | 1353 | switch_to_new_gdt(0); |
| 1351 | 1354 | ||
| 1352 | /* We actually boot with all memory mapped, but let's say 128MB. */ | ||
| 1353 | max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT; | ||
| 1354 | |||
| 1355 | /* | 1355 | /* |
| 1356 | * The Host<->Guest Switcher lives at the top of our address space, and | 1356 | * The Host<->Guest Switcher lives at the top of our address space, and |
| 1357 | * the Host told us how big it is when we made LGUEST_INIT hypercall: | 1357 | * the Host told us how big it is when we made LGUEST_INIT hypercall: |
diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S index 4f420c2f2d5..e7d5382ef26 100644 --- a/arch/x86/lguest/i386_head.S +++ b/arch/x86/lguest/i386_head.S | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include <asm/asm-offsets.h> | 4 | #include <asm/asm-offsets.h> |
| 5 | #include <asm/thread_info.h> | 5 | #include <asm/thread_info.h> |
| 6 | #include <asm/processor-flags.h> | 6 | #include <asm/processor-flags.h> |
| 7 | #include <asm/pgtable.h> | ||
| 7 | 8 | ||
| 8 | /*G:020 | 9 | /*G:020 |
| 9 | * Our story starts with the kernel booting into startup_32 in | 10 | * Our story starts with the kernel booting into startup_32 in |
| @@ -37,9 +38,113 @@ ENTRY(lguest_entry) | |||
| 37 | /* Set up the initial stack so we can run C code. */ | 38 | /* Set up the initial stack so we can run C code. */ |
| 38 | movl $(init_thread_union+THREAD_SIZE),%esp | 39 | movl $(init_thread_union+THREAD_SIZE),%esp |
| 39 | 40 | ||
| 41 | call init_pagetables | ||
| 42 | |||
| 40 | /* Jumps are relative: we're running __PAGE_OFFSET too low. */ | 43 | /* Jumps are relative: we're running __PAGE_OFFSET too low. */ |
| 41 | jmp lguest_init+__PAGE_OFFSET | 44 | jmp lguest_init+__PAGE_OFFSET |
| 42 | 45 | ||
| 46 | /* | ||
| 47 | * Initialize page tables. This creates a PDE and a set of page | ||
| 48 | * tables, which are located immediately beyond __brk_base. The variable | ||
| 49 | * _brk_end is set up to point to the first "safe" location. | ||
| 50 | * Mappings are created both at virtual address 0 (identity mapping) | ||
| 51 | * and PAGE_OFFSET for up to _end. | ||
| 52 | * | ||
| 53 | * FIXME: This code is taken verbatim from arch/x86/kernel/head_32.S: they | ||
| 54 | * don't have a stack at this point, so we can't just use call and ret. | ||
| 55 | */ | ||
| 56 | init_pagetables: | ||
| 57 | #if PTRS_PER_PMD > 1 | ||
| 58 | #define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD) | ||
| 59 | #else | ||
| 60 | #define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) | ||
| 61 | #endif | ||
| 62 | #define pa(X) ((X) - __PAGE_OFFSET) | ||
| 63 | |||
| 64 | /* Enough space to fit pagetables for the low memory linear map */ | ||
| 65 | MAPPING_BEYOND_END = \ | ||
| 66 | PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT | ||
| 67 | #ifdef CONFIG_X86_PAE | ||
| 68 | |||
| 69 | /* | ||
| 70 | * In PAE mode initial_page_table is statically defined to contain | ||
| 71 | * enough entries to cover the VMSPLIT option (that is the top 1, 2 or 3 | ||
| 72 | * entries). The identity mapping is handled by pointing two PGD entries | ||
| 73 | * to the first kernel PMD. | ||
| 74 | * | ||
| 75 | * Note the upper half of each PMD or PTE are always zero at this stage. | ||
| 76 | */ | ||
| 77 | |||
| 78 | #define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */ | ||
| 79 | |||
| 80 | xorl %ebx,%ebx /* %ebx is kept at zero */ | ||
| 81 | |||
| 82 | movl $pa(__brk_base), %edi | ||
| 83 | movl $pa(initial_pg_pmd), %edx | ||
| 84 | movl $PTE_IDENT_ATTR, %eax | ||
| 85 | 10: | ||
| 86 | leal PDE_IDENT_ATTR(%edi),%ecx /* Create PMD entry */ | ||
| 87 | movl %ecx,(%edx) /* Store PMD entry */ | ||
| 88 | /* Upper half already zero */ | ||
| 89 | addl $8,%edx | ||
| 90 | movl $512,%ecx | ||
| 91 | 11: | ||
| 92 | stosl | ||
| 93 | xchgl %eax,%ebx | ||
| 94 | stosl | ||
| 95 | xchgl %eax,%ebx | ||
| 96 | addl $0x1000,%eax | ||
| 97 | loop 11b | ||
| 98 | |||
| 99 | /* | ||
| 100 | * End condition: we must map up to the end + MAPPING_BEYOND_END. | ||
| 101 | */ | ||
| 102 | movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp | ||
| 103 | cmpl %ebp,%eax | ||
| 104 | jb 10b | ||
| 105 | 1: | ||
| 106 | addl $__PAGE_OFFSET, %edi | ||
| 107 | movl %edi, pa(_brk_end) | ||
| 108 | shrl $12, %eax | ||
| 109 | movl %eax, pa(max_pfn_mapped) | ||
| 110 | |||
| 111 | /* Do early initialization of the fixmap area */ | ||
| 112 | movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax | ||
| 113 | movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8) | ||
| 114 | #else /* Not PAE */ | ||
| 115 | |||
| 116 | page_pde_offset = (__PAGE_OFFSET >> 20); | ||
| 117 | |||
| 118 | movl $pa(__brk_base), %edi | ||
| 119 | movl $pa(initial_page_table), %edx | ||
| 120 | movl $PTE_IDENT_ATTR, %eax | ||
| 121 | 10: | ||
| 122 | leal PDE_IDENT_ATTR(%edi),%ecx /* Create PDE entry */ | ||
| 123 | movl %ecx,(%edx) /* Store identity PDE entry */ | ||
| 124 | movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */ | ||
| 125 | addl $4,%edx | ||
| 126 | movl $1024, %ecx | ||
| 127 | 11: | ||
| 128 | stosl | ||
| 129 | addl $0x1000,%eax | ||
| 130 | loop 11b | ||
| 131 | /* | ||
| 132 | * End condition: we must map up to the end + MAPPING_BEYOND_END. | ||
| 133 | */ | ||
| 134 | movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp | ||
| 135 | cmpl %ebp,%eax | ||
| 136 | jb 10b | ||
| 137 | addl $__PAGE_OFFSET, %edi | ||
| 138 | movl %edi, pa(_brk_end) | ||
| 139 | shrl $12, %eax | ||
| 140 | movl %eax, pa(max_pfn_mapped) | ||
| 141 | |||
| 142 | /* Do early initialization of the fixmap area */ | ||
| 143 | movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax | ||
| 144 | movl %eax,pa(initial_page_table+0xffc) | ||
| 145 | #endif | ||
| 146 | ret | ||
| 147 | |||
| 43 | /*G:055 | 148 | /*G:055 |
| 44 | * We create a macro which puts the assembler code between lgstart_ and lgend_ | 149 | * We create a macro which puts the assembler code between lgstart_ and lgend_ |
| 45 | * markers. These templates are put in the .text section: they can't be | 150 | * markers. These templates are put in the .text section: they can't be |
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index c4bb261c106..b1805b78842 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
| @@ -65,21 +65,13 @@ pcibios_align_resource(void *data, const struct resource *res, | |||
| 65 | resource_size_t size, resource_size_t align) | 65 | resource_size_t size, resource_size_t align) |
| 66 | { | 66 | { |
| 67 | struct pci_dev *dev = data; | 67 | struct pci_dev *dev = data; |
| 68 | resource_size_t start = round_down(res->end - size + 1, align); | 68 | resource_size_t start = res->start; |
| 69 | 69 | ||
| 70 | if (res->flags & IORESOURCE_IO) { | 70 | if (res->flags & IORESOURCE_IO) { |
| 71 | 71 | if (skip_isa_ioresource_align(dev)) | |
| 72 | /* | 72 | return start; |
| 73 | * If we're avoiding ISA aliases, the largest contiguous I/O | 73 | if (start & 0x300) |
| 74 | * port space is 256 bytes. Clearing bits 9 and 10 preserves | 74 | start = (start + 0x3ff) & ~0x3ff; |
| 75 | * all 256-byte and smaller alignments, so the result will | ||
| 76 | * still be correctly aligned. | ||
| 77 | */ | ||
| 78 | if (!skip_isa_ioresource_align(dev)) | ||
| 79 | start &= ~0x300; | ||
| 80 | } else if (res->flags & IORESOURCE_MEM) { | ||
| 81 | if (start < BIOS_END) | ||
| 82 | start = res->end; /* fail; no space */ | ||
| 83 | } | 75 | } |
| 84 | return start; | 76 | return start; |
| 85 | } | 77 | } |
diff --git a/block/bsg.c b/block/bsg.c index f20d6a789d4..0c8b64a1648 100644 --- a/block/bsg.c +++ b/block/bsg.c | |||
| @@ -250,6 +250,14 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm, | |||
| 250 | int ret, rw; | 250 | int ret, rw; |
| 251 | unsigned int dxfer_len; | 251 | unsigned int dxfer_len; |
| 252 | void *dxferp = NULL; | 252 | void *dxferp = NULL; |
| 253 | struct bsg_class_device *bcd = &q->bsg_dev; | ||
| 254 | |||
| 255 | /* if the LLD has been removed then the bsg_unregister_queue will | ||
| 256 | * eventually be called and the class_dev was freed, so we can no | ||
| 257 | * longer use this request_queue. Return no such address. | ||
| 258 | */ | ||
| 259 | if (!bcd->class_dev) | ||
| 260 | return ERR_PTR(-ENXIO); | ||
| 253 | 261 | ||
| 254 | dprintk("map hdr %llx/%u %llx/%u\n", (unsigned long long) hdr->dout_xferp, | 262 | dprintk("map hdr %llx/%u %llx/%u\n", (unsigned long long) hdr->dout_xferp, |
| 255 | hdr->dout_xfer_len, (unsigned long long) hdr->din_xferp, | 263 | hdr->dout_xfer_len, (unsigned long long) hdr->din_xferp, |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index ba9afeaa23a..25d3aaebc10 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
| @@ -100,24 +100,7 @@ static const struct file_operations acpi_ac_fops = { | |||
| 100 | .release = single_release, | 100 | .release = single_release, |
| 101 | }; | 101 | }; |
| 102 | #endif | 102 | #endif |
| 103 | static int get_ac_property(struct power_supply *psy, | ||
| 104 | enum power_supply_property psp, | ||
| 105 | union power_supply_propval *val) | ||
| 106 | { | ||
| 107 | struct acpi_ac *ac = to_acpi_ac(psy); | ||
| 108 | switch (psp) { | ||
| 109 | case POWER_SUPPLY_PROP_ONLINE: | ||
| 110 | val->intval = ac->state; | ||
| 111 | break; | ||
| 112 | default: | ||
| 113 | return -EINVAL; | ||
| 114 | } | ||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | 103 | ||
| 118 | static enum power_supply_property ac_props[] = { | ||
| 119 | POWER_SUPPLY_PROP_ONLINE, | ||
| 120 | }; | ||
| 121 | /* -------------------------------------------------------------------------- | 104 | /* -------------------------------------------------------------------------- |
| 122 | AC Adapter Management | 105 | AC Adapter Management |
| 123 | -------------------------------------------------------------------------- */ | 106 | -------------------------------------------------------------------------- */ |
| @@ -140,6 +123,35 @@ static int acpi_ac_get_state(struct acpi_ac *ac) | |||
| 140 | return 0; | 123 | return 0; |
| 141 | } | 124 | } |
| 142 | 125 | ||
| 126 | /* -------------------------------------------------------------------------- | ||
| 127 | sysfs I/F | ||
| 128 | -------------------------------------------------------------------------- */ | ||
| 129 | static int get_ac_property(struct power_supply *psy, | ||
| 130 | enum power_supply_property psp, | ||
| 131 | union power_supply_propval *val) | ||
| 132 | { | ||
| 133 | struct acpi_ac *ac = to_acpi_ac(psy); | ||
| 134 | |||
| 135 | if (!ac) | ||
| 136 | return -ENODEV; | ||
| 137 | |||
| 138 | if (acpi_ac_get_state(ac)) | ||
| 139 | return -ENODEV; | ||
| 140 | |||
| 141 | switch (psp) { | ||
| 142 | case POWER_SUPPLY_PROP_ONLINE: | ||
| 143 | val->intval = ac->state; | ||
| 144 | break; | ||
| 145 | default: | ||
| 146 | return -EINVAL; | ||
| 147 | } | ||
| 148 | return 0; | ||
| 149 | } | ||
| 150 | |||
| 151 | static enum power_supply_property ac_props[] = { | ||
| 152 | POWER_SUPPLY_PROP_ONLINE, | ||
| 153 | }; | ||
| 154 | |||
| 143 | #ifdef CONFIG_ACPI_PROCFS_POWER | 155 | #ifdef CONFIG_ACPI_PROCFS_POWER |
| 144 | /* -------------------------------------------------------------------------- | 156 | /* -------------------------------------------------------------------------- |
| 145 | FS Interface (/proc) | 157 | FS Interface (/proc) |
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 1211c03149e..5850d320404 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
| @@ -86,7 +86,7 @@ static struct erst_erange { | |||
| 86 | * It is used to provide exclusive accessing for ERST Error Log | 86 | * It is used to provide exclusive accessing for ERST Error Log |
| 87 | * Address Range too. | 87 | * Address Range too. |
| 88 | */ | 88 | */ |
| 89 | static DEFINE_SPINLOCK(erst_lock); | 89 | static DEFINE_RAW_SPINLOCK(erst_lock); |
| 90 | 90 | ||
| 91 | static inline int erst_errno(int command_status) | 91 | static inline int erst_errno(int command_status) |
| 92 | { | 92 | { |
| @@ -421,9 +421,9 @@ ssize_t erst_get_record_count(void) | |||
| 421 | if (erst_disable) | 421 | if (erst_disable) |
| 422 | return -ENODEV; | 422 | return -ENODEV; |
| 423 | 423 | ||
| 424 | spin_lock_irqsave(&erst_lock, flags); | 424 | raw_spin_lock_irqsave(&erst_lock, flags); |
| 425 | count = __erst_get_record_count(); | 425 | count = __erst_get_record_count(); |
| 426 | spin_unlock_irqrestore(&erst_lock, flags); | 426 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
| 427 | 427 | ||
| 428 | return count; | 428 | return count; |
| 429 | } | 429 | } |
| @@ -456,9 +456,9 @@ int erst_get_next_record_id(u64 *record_id) | |||
| 456 | if (erst_disable) | 456 | if (erst_disable) |
| 457 | return -ENODEV; | 457 | return -ENODEV; |
| 458 | 458 | ||
| 459 | spin_lock_irqsave(&erst_lock, flags); | 459 | raw_spin_lock_irqsave(&erst_lock, flags); |
| 460 | rc = __erst_get_next_record_id(record_id); | 460 | rc = __erst_get_next_record_id(record_id); |
| 461 | spin_unlock_irqrestore(&erst_lock, flags); | 461 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
| 462 | 462 | ||
| 463 | return rc; | 463 | return rc; |
| 464 | } | 464 | } |
| @@ -624,17 +624,17 @@ int erst_write(const struct cper_record_header *record) | |||
| 624 | return -EINVAL; | 624 | return -EINVAL; |
| 625 | 625 | ||
| 626 | if (erst_erange.attr & ERST_RANGE_NVRAM) { | 626 | if (erst_erange.attr & ERST_RANGE_NVRAM) { |
| 627 | if (!spin_trylock_irqsave(&erst_lock, flags)) | 627 | if (!raw_spin_trylock_irqsave(&erst_lock, flags)) |
| 628 | return -EBUSY; | 628 | return -EBUSY; |
| 629 | rc = __erst_write_to_nvram(record); | 629 | rc = __erst_write_to_nvram(record); |
| 630 | spin_unlock_irqrestore(&erst_lock, flags); | 630 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
| 631 | return rc; | 631 | return rc; |
| 632 | } | 632 | } |
| 633 | 633 | ||
| 634 | if (record->record_length > erst_erange.size) | 634 | if (record->record_length > erst_erange.size) |
| 635 | return -EINVAL; | 635 | return -EINVAL; |
| 636 | 636 | ||
| 637 | if (!spin_trylock_irqsave(&erst_lock, flags)) | 637 | if (!raw_spin_trylock_irqsave(&erst_lock, flags)) |
| 638 | return -EBUSY; | 638 | return -EBUSY; |
| 639 | memcpy(erst_erange.vaddr, record, record->record_length); | 639 | memcpy(erst_erange.vaddr, record, record->record_length); |
| 640 | rcd_erange = erst_erange.vaddr; | 640 | rcd_erange = erst_erange.vaddr; |
| @@ -642,7 +642,7 @@ int erst_write(const struct cper_record_header *record) | |||
| 642 | memcpy(&rcd_erange->persistence_information, "ER", 2); | 642 | memcpy(&rcd_erange->persistence_information, "ER", 2); |
| 643 | 643 | ||
| 644 | rc = __erst_write_to_storage(0); | 644 | rc = __erst_write_to_storage(0); |
| 645 | spin_unlock_irqrestore(&erst_lock, flags); | 645 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
| 646 | 646 | ||
| 647 | return rc; | 647 | return rc; |
| 648 | } | 648 | } |
| @@ -696,9 +696,9 @@ ssize_t erst_read(u64 record_id, struct cper_record_header *record, | |||
| 696 | if (erst_disable) | 696 | if (erst_disable) |
| 697 | return -ENODEV; | 697 | return -ENODEV; |
| 698 | 698 | ||
| 699 | spin_lock_irqsave(&erst_lock, flags); | 699 | raw_spin_lock_irqsave(&erst_lock, flags); |
| 700 | len = __erst_read(record_id, record, buflen); | 700 | len = __erst_read(record_id, record, buflen); |
| 701 | spin_unlock_irqrestore(&erst_lock, flags); | 701 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
| 702 | return len; | 702 | return len; |
| 703 | } | 703 | } |
| 704 | EXPORT_SYMBOL_GPL(erst_read); | 704 | EXPORT_SYMBOL_GPL(erst_read); |
| @@ -719,20 +719,20 @@ ssize_t erst_read_next(struct cper_record_header *record, size_t buflen) | |||
| 719 | if (erst_disable) | 719 | if (erst_disable) |
| 720 | return -ENODEV; | 720 | return -ENODEV; |
| 721 | 721 | ||
| 722 | spin_lock_irqsave(&erst_lock, flags); | 722 | raw_spin_lock_irqsave(&erst_lock, flags); |
| 723 | rc = __erst_get_next_record_id(&record_id); | 723 | rc = __erst_get_next_record_id(&record_id); |
| 724 | if (rc) { | 724 | if (rc) { |
| 725 | spin_unlock_irqrestore(&erst_lock, flags); | 725 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
| 726 | return rc; | 726 | return rc; |
| 727 | } | 727 | } |
| 728 | /* no more record */ | 728 | /* no more record */ |
| 729 | if (record_id == APEI_ERST_INVALID_RECORD_ID) { | 729 | if (record_id == APEI_ERST_INVALID_RECORD_ID) { |
| 730 | spin_unlock_irqrestore(&erst_lock, flags); | 730 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
| 731 | return 0; | 731 | return 0; |
| 732 | } | 732 | } |
| 733 | 733 | ||
| 734 | len = __erst_read(record_id, record, buflen); | 734 | len = __erst_read(record_id, record, buflen); |
| 735 | spin_unlock_irqrestore(&erst_lock, flags); | 735 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
| 736 | 736 | ||
| 737 | return len; | 737 | return len; |
| 738 | } | 738 | } |
| @@ -746,12 +746,12 @@ int erst_clear(u64 record_id) | |||
| 746 | if (erst_disable) | 746 | if (erst_disable) |
| 747 | return -ENODEV; | 747 | return -ENODEV; |
| 748 | 748 | ||
| 749 | spin_lock_irqsave(&erst_lock, flags); | 749 | raw_spin_lock_irqsave(&erst_lock, flags); |
| 750 | if (erst_erange.attr & ERST_RANGE_NVRAM) | 750 | if (erst_erange.attr & ERST_RANGE_NVRAM) |
| 751 | rc = __erst_clear_from_nvram(record_id); | 751 | rc = __erst_clear_from_nvram(record_id); |
| 752 | else | 752 | else |
| 753 | rc = __erst_clear_from_storage(record_id); | 753 | rc = __erst_clear_from_storage(record_id); |
| 754 | spin_unlock_irqrestore(&erst_lock, flags); | 754 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
| 755 | 755 | ||
| 756 | return rc; | 756 | return rc; |
| 757 | } | 757 | } |
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 1a3508a7fe0..daa7bc63f1d 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c | |||
| @@ -46,9 +46,9 @@ EXPORT_SYMBOL_GPL(hest_disable); | |||
| 46 | 46 | ||
| 47 | /* HEST table parsing */ | 47 | /* HEST table parsing */ |
| 48 | 48 | ||
| 49 | static struct acpi_table_hest *hest_tab; | 49 | static struct acpi_table_hest *__read_mostly hest_tab; |
| 50 | 50 | ||
| 51 | static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { | 51 | static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { |
| 52 | [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ | 52 | [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ |
| 53 | [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, | 53 | [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, |
| 54 | [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi), | 54 | [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi), |
| @@ -126,7 +126,7 @@ struct ghes_arr { | |||
| 126 | unsigned int count; | 126 | unsigned int count; |
| 127 | }; | 127 | }; |
| 128 | 128 | ||
| 129 | static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | 129 | static int __init hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) |
| 130 | { | 130 | { |
| 131 | int *count = data; | 131 | int *count = data; |
| 132 | 132 | ||
| @@ -135,7 +135,7 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | |||
| 135 | return 0; | 135 | return 0; |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) | 138 | static int __init hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) |
| 139 | { | 139 | { |
| 140 | struct platform_device *ghes_dev; | 140 | struct platform_device *ghes_dev; |
| 141 | struct ghes_arr *ghes_arr = data; | 141 | struct ghes_arr *ghes_arr = data; |
| @@ -165,7 +165,7 @@ err: | |||
| 165 | return rc; | 165 | return rc; |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | static int hest_ghes_dev_register(unsigned int ghes_count) | 168 | static int __init hest_ghes_dev_register(unsigned int ghes_count) |
| 169 | { | 169 | { |
| 170 | int rc, i; | 170 | int rc, i; |
| 171 | struct ghes_arr ghes_arr; | 171 | struct ghes_arr ghes_arr; |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 95649d37307..9fb9d5ac939 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
| @@ -130,6 +130,8 @@ struct acpi_battery { | |||
| 130 | unsigned long flags; | 130 | unsigned long flags; |
| 131 | }; | 131 | }; |
| 132 | 132 | ||
| 133 | static int acpi_battery_update(struct acpi_battery *battery); | ||
| 134 | |||
| 133 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); | 135 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); |
| 134 | 136 | ||
| 135 | inline int acpi_battery_present(struct acpi_battery *battery) | 137 | inline int acpi_battery_present(struct acpi_battery *battery) |
| @@ -184,6 +186,9 @@ static int acpi_battery_get_property(struct power_supply *psy, | |||
| 184 | int ret = 0; | 186 | int ret = 0; |
| 185 | struct acpi_battery *battery = to_acpi_battery(psy); | 187 | struct acpi_battery *battery = to_acpi_battery(psy); |
| 186 | 188 | ||
| 189 | if (acpi_battery_update(battery)) | ||
| 190 | return -ENODEV; | ||
| 191 | |||
| 187 | if (acpi_battery_present(battery)) { | 192 | if (acpi_battery_present(battery)) { |
| 188 | /* run battery update only if it is present */ | 193 | /* run battery update only if it is present */ |
| 189 | acpi_battery_get_state(battery); | 194 | acpi_battery_get_state(battery); |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 372ff80b7b0..302b31ed31f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -934,6 +934,9 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { | |||
| 934 | ec_flag_msi, "MSI hardware", { | 934 | ec_flag_msi, "MSI hardware", { |
| 935 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL}, | 935 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL}, |
| 936 | { | 936 | { |
| 937 | ec_flag_msi, "MSI hardware", { | ||
| 938 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL}, | ||
| 939 | { | ||
| 937 | ec_validate_ecdt, "ASUS hardware", { | 940 | ec_validate_ecdt, "ASUS hardware", { |
| 938 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, | 941 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, |
| 939 | {}, | 942 | {}, |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 966feddf6b1..055d7b701ff 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
| @@ -110,9 +110,6 @@ struct acpi_ioremap { | |||
| 110 | static LIST_HEAD(acpi_ioremaps); | 110 | static LIST_HEAD(acpi_ioremaps); |
| 111 | static DEFINE_SPINLOCK(acpi_ioremap_lock); | 111 | static DEFINE_SPINLOCK(acpi_ioremap_lock); |
| 112 | 112 | ||
| 113 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | ||
| 114 | static char osi_setup_string[OSI_STRING_LENGTH_MAX]; | ||
| 115 | |||
| 116 | static void __init acpi_osi_setup_late(void); | 113 | static void __init acpi_osi_setup_late(void); |
| 117 | 114 | ||
| 118 | /* | 115 | /* |
| @@ -152,8 +149,7 @@ static struct osi_linux { | |||
| 152 | unsigned int enable:1; | 149 | unsigned int enable:1; |
| 153 | unsigned int dmi:1; | 150 | unsigned int dmi:1; |
| 154 | unsigned int cmdline:1; | 151 | unsigned int cmdline:1; |
| 155 | unsigned int known:1; | 152 | } osi_linux = {0, 0, 0}; |
| 156 | } osi_linux = { 0, 0, 0, 0}; | ||
| 157 | 153 | ||
| 158 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) | 154 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) |
| 159 | { | 155 | { |
| @@ -1055,13 +1051,53 @@ static int __init acpi_os_name_setup(char *str) | |||
| 1055 | 1051 | ||
| 1056 | __setup("acpi_os_name=", acpi_os_name_setup); | 1052 | __setup("acpi_os_name=", acpi_os_name_setup); |
| 1057 | 1053 | ||
| 1054 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | ||
| 1055 | #define OSI_STRING_ENTRIES_MAX 16 /* arbitrary */ | ||
| 1056 | |||
| 1057 | struct osi_setup_entry { | ||
| 1058 | char string[OSI_STRING_LENGTH_MAX]; | ||
| 1059 | bool enable; | ||
| 1060 | }; | ||
| 1061 | |||
| 1062 | static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX]; | ||
| 1063 | |||
| 1064 | void __init acpi_osi_setup(char *str) | ||
| 1065 | { | ||
| 1066 | struct osi_setup_entry *osi; | ||
| 1067 | bool enable = true; | ||
| 1068 | int i; | ||
| 1069 | |||
| 1070 | if (!acpi_gbl_create_osi_method) | ||
| 1071 | return; | ||
| 1072 | |||
| 1073 | if (str == NULL || *str == '\0') { | ||
| 1074 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | ||
| 1075 | acpi_gbl_create_osi_method = FALSE; | ||
| 1076 | return; | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | if (*str == '!') { | ||
| 1080 | str++; | ||
| 1081 | enable = false; | ||
| 1082 | } | ||
| 1083 | |||
| 1084 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { | ||
| 1085 | osi = &osi_setup_entries[i]; | ||
| 1086 | if (!strcmp(osi->string, str)) { | ||
| 1087 | osi->enable = enable; | ||
| 1088 | break; | ||
| 1089 | } else if (osi->string[0] == '\0') { | ||
| 1090 | osi->enable = enable; | ||
| 1091 | strncpy(osi->string, str, OSI_STRING_LENGTH_MAX); | ||
| 1092 | break; | ||
| 1093 | } | ||
| 1094 | } | ||
| 1095 | } | ||
| 1096 | |||
| 1058 | static void __init set_osi_linux(unsigned int enable) | 1097 | static void __init set_osi_linux(unsigned int enable) |
| 1059 | { | 1098 | { |
| 1060 | if (osi_linux.enable != enable) { | 1099 | if (osi_linux.enable != enable) |
| 1061 | osi_linux.enable = enable; | 1100 | osi_linux.enable = enable; |
| 1062 | printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", | ||
| 1063 | enable ? "Add": "Delet"); | ||
| 1064 | } | ||
| 1065 | 1101 | ||
| 1066 | if (osi_linux.enable) | 1102 | if (osi_linux.enable) |
| 1067 | acpi_osi_setup("Linux"); | 1103 | acpi_osi_setup("Linux"); |
| @@ -1073,7 +1109,8 @@ static void __init set_osi_linux(unsigned int enable) | |||
| 1073 | 1109 | ||
| 1074 | static void __init acpi_cmdline_osi_linux(unsigned int enable) | 1110 | static void __init acpi_cmdline_osi_linux(unsigned int enable) |
| 1075 | { | 1111 | { |
| 1076 | osi_linux.cmdline = 1; /* cmdline set the default */ | 1112 | osi_linux.cmdline = 1; /* cmdline set the default and override DMI */ |
| 1113 | osi_linux.dmi = 0; | ||
| 1077 | set_osi_linux(enable); | 1114 | set_osi_linux(enable); |
| 1078 | 1115 | ||
| 1079 | return; | 1116 | return; |
| @@ -1081,15 +1118,12 @@ static void __init acpi_cmdline_osi_linux(unsigned int enable) | |||
| 1081 | 1118 | ||
| 1082 | void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) | 1119 | void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) |
| 1083 | { | 1120 | { |
| 1084 | osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */ | ||
| 1085 | |||
| 1086 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); | 1121 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); |
| 1087 | 1122 | ||
| 1088 | if (enable == -1) | 1123 | if (enable == -1) |
| 1089 | return; | 1124 | return; |
| 1090 | 1125 | ||
| 1091 | osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */ | 1126 | osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */ |
| 1092 | |||
| 1093 | set_osi_linux(enable); | 1127 | set_osi_linux(enable); |
| 1094 | 1128 | ||
| 1095 | return; | 1129 | return; |
| @@ -1104,37 +1138,44 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) | |||
| 1104 | */ | 1138 | */ |
| 1105 | static void __init acpi_osi_setup_late(void) | 1139 | static void __init acpi_osi_setup_late(void) |
| 1106 | { | 1140 | { |
| 1107 | char *str = osi_setup_string; | 1141 | struct osi_setup_entry *osi; |
| 1142 | char *str; | ||
| 1143 | int i; | ||
| 1144 | acpi_status status; | ||
| 1108 | 1145 | ||
| 1109 | if (*str == '\0') | 1146 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { |
| 1110 | return; | 1147 | osi = &osi_setup_entries[i]; |
| 1148 | str = osi->string; | ||
| 1111 | 1149 | ||
| 1112 | if (!strcmp("!Linux", str)) { | 1150 | if (*str == '\0') |
| 1113 | acpi_cmdline_osi_linux(0); /* !enable */ | 1151 | break; |
| 1114 | } else if (*str == '!') { | 1152 | if (osi->enable) { |
| 1115 | if (acpi_remove_interface(++str) == AE_OK) | 1153 | status = acpi_install_interface(str); |
| 1116 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); | 1154 | |
| 1117 | } else if (!strcmp("Linux", str)) { | 1155 | if (ACPI_SUCCESS(status)) |
| 1118 | acpi_cmdline_osi_linux(1); /* enable */ | 1156 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); |
| 1119 | } else { | 1157 | } else { |
| 1120 | if (acpi_install_interface(str) == AE_OK) | 1158 | status = acpi_remove_interface(str); |
| 1121 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); | 1159 | |
| 1160 | if (ACPI_SUCCESS(status)) | ||
| 1161 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); | ||
| 1162 | } | ||
| 1122 | } | 1163 | } |
| 1123 | } | 1164 | } |
| 1124 | 1165 | ||
| 1125 | int __init acpi_osi_setup(char *str) | 1166 | static int __init osi_setup(char *str) |
| 1126 | { | 1167 | { |
| 1127 | if (str == NULL || *str == '\0') { | 1168 | if (str && !strcmp("Linux", str)) |
| 1128 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | 1169 | acpi_cmdline_osi_linux(1); |
| 1129 | acpi_gbl_create_osi_method = FALSE; | 1170 | else if (str && !strcmp("!Linux", str)) |
| 1130 | } else { | 1171 | acpi_cmdline_osi_linux(0); |
| 1131 | strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX); | 1172 | else |
| 1132 | } | 1173 | acpi_osi_setup(str); |
| 1133 | 1174 | ||
| 1134 | return 1; | 1175 | return 1; |
| 1135 | } | 1176 | } |
| 1136 | 1177 | ||
| 1137 | __setup("acpi_osi=", acpi_osi_setup); | 1178 | __setup("acpi_osi=", osi_setup); |
| 1138 | 1179 | ||
| 1139 | /* enable serialization to combat AE_ALREADY_EXISTS errors */ | 1180 | /* enable serialization to combat AE_ALREADY_EXISTS errors */ |
| 1140 | static int __init acpi_serialize_setup(char *str) | 1181 | static int __init acpi_serialize_setup(char *str) |
| @@ -1530,7 +1571,7 @@ acpi_status __init acpi_os_initialize(void) | |||
| 1530 | return AE_OK; | 1571 | return AE_OK; |
| 1531 | } | 1572 | } |
| 1532 | 1573 | ||
| 1533 | acpi_status acpi_os_initialize1(void) | 1574 | acpi_status __init acpi_os_initialize1(void) |
| 1534 | { | 1575 | { |
| 1535 | kacpid_wq = create_workqueue("kacpid"); | 1576 | kacpid_wq = create_workqueue("kacpid"); |
| 1536 | kacpi_notify_wq = create_workqueue("kacpi_notify"); | 1577 | kacpi_notify_wq = create_workqueue("kacpi_notify"); |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 67dedeed144..4c9c2fb5d98 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
| @@ -213,11 +213,13 @@ static int acpi_power_on(acpi_handle handle) | |||
| 213 | resource->name)); | 213 | resource->name)); |
| 214 | } else { | 214 | } else { |
| 215 | result = __acpi_power_on(resource); | 215 | result = __acpi_power_on(resource); |
| 216 | if (result) | ||
| 217 | resource->ref_count--; | ||
| 216 | } | 218 | } |
| 217 | 219 | ||
| 218 | mutex_unlock(&resource->resource_lock); | 220 | mutex_unlock(&resource->resource_lock); |
| 219 | 221 | ||
| 220 | return 0; | 222 | return result; |
| 221 | } | 223 | } |
| 222 | 224 | ||
| 223 | static int acpi_power_off_device(acpi_handle handle) | 225 | static int acpi_power_off_device(acpi_handle handle) |
| @@ -465,10 +467,12 @@ int acpi_power_transition(struct acpi_device *device, int state) | |||
| 465 | struct acpi_handle_list *tl = NULL; /* Target Resources */ | 467 | struct acpi_handle_list *tl = NULL; /* Target Resources */ |
| 466 | int i = 0; | 468 | int i = 0; |
| 467 | 469 | ||
| 468 | |||
| 469 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) | 470 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) |
| 470 | return -EINVAL; | 471 | return -EINVAL; |
| 471 | 472 | ||
| 473 | if (device->power.state == state) | ||
| 474 | return 0; | ||
| 475 | |||
| 472 | if ((device->power.state < ACPI_STATE_D0) | 476 | if ((device->power.state < ACPI_STATE_D0) |
| 473 | || (device->power.state > ACPI_STATE_D3)) | 477 | || (device->power.state > ACPI_STATE_D3)) |
| 474 | return -ENODEV; | 478 | return -ENODEV; |
| @@ -488,10 +492,6 @@ int acpi_power_transition(struct acpi_device *device, int state) | |||
| 488 | goto end; | 492 | goto end; |
| 489 | } | 493 | } |
| 490 | 494 | ||
| 491 | if (device->power.state == state) { | ||
| 492 | goto end; | ||
| 493 | } | ||
| 494 | |||
| 495 | /* | 495 | /* |
| 496 | * Then we dereference all power resources used in the current list. | 496 | * Then we dereference all power resources used in the current list. |
| 497 | */ | 497 | */ |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index fde49b9b1d9..79cb6533289 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
| @@ -156,15 +156,6 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state) | |||
| 156 | return 0; | 156 | return 0; |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | static int acpi_thermal_cpufreq_increase(unsigned int cpu) | ||
| 160 | { | ||
| 161 | return -ENODEV; | ||
| 162 | } | ||
| 163 | static int acpi_thermal_cpufreq_decrease(unsigned int cpu) | ||
| 164 | { | ||
| 165 | return -ENODEV; | ||
| 166 | } | ||
| 167 | |||
| 168 | #endif | 159 | #endif |
| 169 | 160 | ||
| 170 | int acpi_processor_get_limit_info(struct acpi_processor *pr) | 161 | int acpi_processor_get_limit_info(struct acpi_processor *pr) |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 721d93b3cee..febb153b5a6 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
| @@ -27,8 +27,6 @@ | |||
| 27 | 27 | ||
| 28 | static u8 sleep_states[ACPI_S_STATE_COUNT]; | 28 | static u8 sleep_states[ACPI_S_STATE_COUNT]; |
| 29 | 29 | ||
| 30 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | ||
| 31 | |||
| 32 | static void acpi_sleep_tts_switch(u32 acpi_state) | 30 | static void acpi_sleep_tts_switch(u32 acpi_state) |
| 33 | { | 31 | { |
| 34 | union acpi_object in_arg = { ACPI_TYPE_INTEGER }; | 32 | union acpi_object in_arg = { ACPI_TYPE_INTEGER }; |
| @@ -81,6 +79,8 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
| 81 | } | 79 | } |
| 82 | 80 | ||
| 83 | #ifdef CONFIG_ACPI_SLEEP | 81 | #ifdef CONFIG_ACPI_SLEEP |
| 82 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | ||
| 83 | |||
| 84 | /* | 84 | /* |
| 85 | * The ACPI specification wants us to save NVS memory regions during hibernation | 85 | * The ACPI specification wants us to save NVS memory regions during hibernation |
| 86 | * and to restore them during the subsequent resume. Windows does that also for | 86 | * and to restore them during the subsequent resume. Windows does that also for |
| @@ -427,6 +427,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
| 427 | DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"), | 427 | DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"), |
| 428 | }, | 428 | }, |
| 429 | }, | 429 | }, |
| 430 | { | ||
| 431 | .callback = init_nvs_nosave, | ||
| 432 | .ident = "Sony Vaio VGN-NW130D", | ||
| 433 | .matches = { | ||
| 434 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
| 435 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"), | ||
| 436 | }, | ||
| 437 | }, | ||
| 430 | {}, | 438 | {}, |
| 431 | }; | 439 | }; |
| 432 | #endif /* CONFIG_SUSPEND */ | 440 | #endif /* CONFIG_SUSPEND */ |
diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c index 46b94762125..f9b983ae687 100644 --- a/drivers/atm/adummy.c +++ b/drivers/atm/adummy.c | |||
| @@ -154,7 +154,7 @@ static int __init adummy_init(void) | |||
| 154 | err = -ENOMEM; | 154 | err = -ENOMEM; |
| 155 | goto out; | 155 | goto out; |
| 156 | } | 156 | } |
| 157 | atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL); | 157 | atm_dev = atm_dev_register(DEV_LABEL, NULL, &adummy_ops, -1, NULL); |
| 158 | if (!atm_dev) { | 158 | if (!atm_dev) { |
| 159 | printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n"); | 159 | printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n"); |
| 160 | err = -ENODEV; | 160 | err = -ENODEV; |
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index a33896a482e..ffe9b655292 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c | |||
| @@ -2244,7 +2244,8 @@ static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_ | |||
| 2244 | goto out_reset; | 2244 | goto out_reset; |
| 2245 | } | 2245 | } |
| 2246 | 2246 | ||
| 2247 | dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL); | 2247 | dev->atm_dev = atm_dev_register (DEV_LABEL, &pci_dev->dev, &amb_ops, -1, |
| 2248 | NULL); | ||
| 2248 | if (!dev->atm_dev) { | 2249 | if (!dev->atm_dev) { |
| 2249 | PRINTD (DBG_ERR, "failed to register Madge ATM adapter"); | 2250 | PRINTD (DBG_ERR, "failed to register Madge ATM adapter"); |
| 2250 | err = -EINVAL; | 2251 | err = -EINVAL; |
diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c index b9101818b47..2b464b631f2 100644 --- a/drivers/atm/atmtcp.c +++ b/drivers/atm/atmtcp.c | |||
| @@ -366,7 +366,7 @@ static int atmtcp_create(int itf,int persist,struct atm_dev **result) | |||
| 366 | if (!dev_data) | 366 | if (!dev_data) |
| 367 | return -ENOMEM; | 367 | return -ENOMEM; |
| 368 | 368 | ||
| 369 | dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,NULL); | 369 | dev = atm_dev_register(DEV_LABEL,NULL,&atmtcp_v_dev_ops,itf,NULL); |
| 370 | if (!dev) { | 370 | if (!dev) { |
| 371 | kfree(dev_data); | 371 | kfree(dev_data); |
| 372 | return itf == -1 ? -ENOMEM : -EBUSY; | 372 | return itf == -1 ? -ENOMEM : -EBUSY; |
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index 97c5898cd76..c495fae7420 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c | |||
| @@ -2244,7 +2244,7 @@ static int __devinit eni_init_one(struct pci_dev *pci_dev, | |||
| 2244 | &zeroes); | 2244 | &zeroes); |
| 2245 | if (!cpu_zeroes) goto out1; | 2245 | if (!cpu_zeroes) goto out1; |
| 2246 | } | 2246 | } |
| 2247 | dev = atm_dev_register(DEV_LABEL,&ops,-1,NULL); | 2247 | dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL); |
| 2248 | if (!dev) goto out2; | 2248 | if (!dev) goto out2; |
| 2249 | pci_set_drvdata(pci_dev, dev); | 2249 | pci_set_drvdata(pci_dev, dev); |
| 2250 | eni_dev->pci_dev = pci_dev; | 2250 | eni_dev->pci_dev = pci_dev; |
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 5d86bb803e9..7d912baf01d 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c | |||
| @@ -1911,7 +1911,7 @@ static int __devinit firestream_init_one (struct pci_dev *pci_dev, | |||
| 1911 | fs_dev, sizeof (struct fs_dev)); | 1911 | fs_dev, sizeof (struct fs_dev)); |
| 1912 | if (!fs_dev) | 1912 | if (!fs_dev) |
| 1913 | goto err_out; | 1913 | goto err_out; |
| 1914 | atm_dev = atm_dev_register("fs", &ops, -1, NULL); | 1914 | atm_dev = atm_dev_register("fs", &pci_dev->dev, &ops, -1, NULL); |
| 1915 | if (!atm_dev) | 1915 | if (!atm_dev) |
| 1916 | goto err_out_free_fs_dev; | 1916 | goto err_out_free_fs_dev; |
| 1917 | 1917 | ||
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index c8fc69c85a0..962c309b40c 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c | |||
| @@ -2567,14 +2567,14 @@ release: | |||
| 2567 | 2567 | ||
| 2568 | 2568 | ||
| 2569 | static int __devinit | 2569 | static int __devinit |
| 2570 | fore200e_register(struct fore200e* fore200e) | 2570 | fore200e_register(struct fore200e* fore200e, struct device *parent) |
| 2571 | { | 2571 | { |
| 2572 | struct atm_dev* atm_dev; | 2572 | struct atm_dev* atm_dev; |
| 2573 | 2573 | ||
| 2574 | DPRINTK(2, "device %s being registered\n", fore200e->name); | 2574 | DPRINTK(2, "device %s being registered\n", fore200e->name); |
| 2575 | 2575 | ||
| 2576 | atm_dev = atm_dev_register(fore200e->bus->proc_name, &fore200e_ops, -1, | 2576 | atm_dev = atm_dev_register(fore200e->bus->proc_name, parent, &fore200e_ops, |
| 2577 | NULL); | 2577 | -1, NULL); |
| 2578 | if (atm_dev == NULL) { | 2578 | if (atm_dev == NULL) { |
| 2579 | printk(FORE200E "unable to register device %s\n", fore200e->name); | 2579 | printk(FORE200E "unable to register device %s\n", fore200e->name); |
| 2580 | return -ENODEV; | 2580 | return -ENODEV; |
| @@ -2594,9 +2594,9 @@ fore200e_register(struct fore200e* fore200e) | |||
| 2594 | 2594 | ||
| 2595 | 2595 | ||
| 2596 | static int __devinit | 2596 | static int __devinit |
| 2597 | fore200e_init(struct fore200e* fore200e) | 2597 | fore200e_init(struct fore200e* fore200e, struct device *parent) |
| 2598 | { | 2598 | { |
| 2599 | if (fore200e_register(fore200e) < 0) | 2599 | if (fore200e_register(fore200e, parent) < 0) |
| 2600 | return -ENODEV; | 2600 | return -ENODEV; |
| 2601 | 2601 | ||
| 2602 | if (fore200e->bus->configure(fore200e) < 0) | 2602 | if (fore200e->bus->configure(fore200e) < 0) |
| @@ -2662,7 +2662,7 @@ static int __devinit fore200e_sba_probe(struct platform_device *op, | |||
| 2662 | 2662 | ||
| 2663 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); | 2663 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); |
| 2664 | 2664 | ||
| 2665 | err = fore200e_init(fore200e); | 2665 | err = fore200e_init(fore200e, &op->dev); |
| 2666 | if (err < 0) { | 2666 | if (err < 0) { |
| 2667 | fore200e_shutdown(fore200e); | 2667 | fore200e_shutdown(fore200e); |
| 2668 | kfree(fore200e); | 2668 | kfree(fore200e); |
| @@ -2740,7 +2740,7 @@ fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent | |||
| 2740 | 2740 | ||
| 2741 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); | 2741 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); |
| 2742 | 2742 | ||
| 2743 | err = fore200e_init(fore200e); | 2743 | err = fore200e_init(fore200e, &pci_dev->dev); |
| 2744 | if (err < 0) { | 2744 | if (err < 0) { |
| 2745 | fore200e_shutdown(fore200e); | 2745 | fore200e_shutdown(fore200e); |
| 2746 | goto out_free; | 2746 | goto out_free; |
diff --git a/drivers/atm/he.c b/drivers/atm/he.c index 801e8b6e9d1..6cf59bf281d 100644 --- a/drivers/atm/he.c +++ b/drivers/atm/he.c | |||
| @@ -366,7 +366,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent) | |||
| 366 | goto init_one_failure; | 366 | goto init_one_failure; |
| 367 | } | 367 | } |
| 368 | 368 | ||
| 369 | atm_dev = atm_dev_register(DEV_LABEL, &he_ops, -1, NULL); | 369 | atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &he_ops, -1, NULL); |
| 370 | if (!atm_dev) { | 370 | if (!atm_dev) { |
| 371 | err = -ENODEV; | 371 | err = -ENODEV; |
| 372 | goto init_one_failure; | 372 | goto init_one_failure; |
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index a95790452a6..24761e1d664 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c | |||
| @@ -2733,7 +2733,8 @@ static int __devinit hrz_probe(struct pci_dev *pci_dev, const struct pci_device_ | |||
| 2733 | PRINTD(DBG_INFO, "found Madge ATM adapter (hrz) at: IO %x, IRQ %u, MEM %p", | 2733 | PRINTD(DBG_INFO, "found Madge ATM adapter (hrz) at: IO %x, IRQ %u, MEM %p", |
| 2734 | iobase, irq, membase); | 2734 | iobase, irq, membase); |
| 2735 | 2735 | ||
| 2736 | dev->atm_dev = atm_dev_register(DEV_LABEL, &hrz_ops, -1, NULL); | 2736 | dev->atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &hrz_ops, -1, |
| 2737 | NULL); | ||
| 2737 | if (!(dev->atm_dev)) { | 2738 | if (!(dev->atm_dev)) { |
| 2738 | PRINTD(DBG_ERR, "failed to register Madge ATM adapter"); | 2739 | PRINTD(DBG_ERR, "failed to register Madge ATM adapter"); |
| 2739 | err = -EINVAL; | 2740 | err = -EINVAL; |
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index bce57328ddd..bfb7feee040 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c | |||
| @@ -3698,7 +3698,8 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id) | |||
| 3698 | goto err_out_iounmap; | 3698 | goto err_out_iounmap; |
| 3699 | } | 3699 | } |
| 3700 | 3700 | ||
| 3701 | dev = atm_dev_register("idt77252", &idt77252_ops, -1, NULL); | 3701 | dev = atm_dev_register("idt77252", &pcidev->dev, &idt77252_ops, -1, |
| 3702 | NULL); | ||
| 3702 | if (!dev) { | 3703 | if (!dev) { |
| 3703 | printk("%s: can't register atm device\n", card->name); | 3704 | printk("%s: can't register atm device\n", card->name); |
| 3704 | err = -EIO; | 3705 | err = -EIO; |
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index 9309d4724e1..72925405375 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c | |||
| @@ -3172,7 +3172,7 @@ static int __devinit ia_init_one(struct pci_dev *pdev, | |||
| 3172 | ret = -ENODEV; | 3172 | ret = -ENODEV; |
| 3173 | goto err_out_free_iadev; | 3173 | goto err_out_free_iadev; |
| 3174 | } | 3174 | } |
| 3175 | dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL); | 3175 | dev = atm_dev_register(DEV_LABEL, &pdev->dev, &ops, -1, NULL); |
| 3176 | if (!dev) { | 3176 | if (!dev) { |
| 3177 | ret = -ENOMEM; | 3177 | ret = -ENOMEM; |
| 3178 | goto err_out_disable_dev; | 3178 | goto err_out_disable_dev; |
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index cbe15a86c66..a395c9aab14 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c | |||
| @@ -2591,7 +2591,7 @@ static int __devinit lanai_init_one(struct pci_dev *pci, | |||
| 2591 | return -ENOMEM; | 2591 | return -ENOMEM; |
| 2592 | } | 2592 | } |
| 2593 | 2593 | ||
| 2594 | atmdev = atm_dev_register(DEV_LABEL, &ops, -1, NULL); | 2594 | atmdev = atm_dev_register(DEV_LABEL, &pci->dev, &ops, -1, NULL); |
| 2595 | if (atmdev == NULL) { | 2595 | if (atmdev == NULL) { |
| 2596 | printk(KERN_ERR DEV_LABEL | 2596 | printk(KERN_ERR DEV_LABEL |
| 2597 | ": couldn't register atm device!\n"); | 2597 | ": couldn't register atm device!\n"); |
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 2f3516b7f11..6b313ee9231 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c | |||
| @@ -771,7 +771,8 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev) | |||
| 771 | } | 771 | } |
| 772 | 772 | ||
| 773 | /* Register device */ | 773 | /* Register device */ |
| 774 | card->atmdev = atm_dev_register("nicstar", &atm_ops, -1, NULL); | 774 | card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops, |
| 775 | -1, NULL); | ||
| 775 | if (card->atmdev == NULL) { | 776 | if (card->atmdev == NULL) { |
| 776 | printk("nicstar%d: can't register device.\n", i); | 777 | printk("nicstar%d: can't register device.\n", i); |
| 777 | error = 17; | 778 | error = 17; |
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 2e08c996fd3..73fb1c4f4cd 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c | |||
| @@ -166,7 +166,7 @@ static irqreturn_t solos_irq(int irq, void *dev_id); | |||
| 166 | static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci); | 166 | static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci); |
| 167 | static int list_vccs(int vci); | 167 | static int list_vccs(int vci); |
| 168 | static void release_vccs(struct atm_dev *dev); | 168 | static void release_vccs(struct atm_dev *dev); |
| 169 | static int atm_init(struct solos_card *); | 169 | static int atm_init(struct solos_card *, struct device *); |
| 170 | static void atm_remove(struct solos_card *); | 170 | static void atm_remove(struct solos_card *); |
| 171 | static int send_command(struct solos_card *card, int dev, const char *buf, size_t size); | 171 | static int send_command(struct solos_card *card, int dev, const char *buf, size_t size); |
| 172 | static void solos_bh(unsigned long); | 172 | static void solos_bh(unsigned long); |
| @@ -1210,7 +1210,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 1210 | if (db_firmware_upgrade) | 1210 | if (db_firmware_upgrade) |
| 1211 | flash_upgrade(card, 3); | 1211 | flash_upgrade(card, 3); |
| 1212 | 1212 | ||
| 1213 | err = atm_init(card); | 1213 | err = atm_init(card, &dev->dev); |
| 1214 | if (err) | 1214 | if (err) |
| 1215 | goto out_free_irq; | 1215 | goto out_free_irq; |
| 1216 | 1216 | ||
| @@ -1233,7 +1233,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 1233 | return err; | 1233 | return err; |
| 1234 | } | 1234 | } |
| 1235 | 1235 | ||
| 1236 | static int atm_init(struct solos_card *card) | 1236 | static int atm_init(struct solos_card *card, struct device *parent) |
| 1237 | { | 1237 | { |
| 1238 | int i; | 1238 | int i; |
| 1239 | 1239 | ||
| @@ -1244,7 +1244,7 @@ static int atm_init(struct solos_card *card) | |||
| 1244 | skb_queue_head_init(&card->tx_queue[i]); | 1244 | skb_queue_head_init(&card->tx_queue[i]); |
| 1245 | skb_queue_head_init(&card->cli_queue[i]); | 1245 | skb_queue_head_init(&card->cli_queue[i]); |
| 1246 | 1246 | ||
| 1247 | card->atmdev[i] = atm_dev_register("solos-pci", &fpga_ops, -1, NULL); | 1247 | card->atmdev[i] = atm_dev_register("solos-pci", parent, &fpga_ops, -1, NULL); |
| 1248 | if (!card->atmdev[i]) { | 1248 | if (!card->atmdev[i]) { |
| 1249 | dev_err(&card->dev->dev, "Could not register ATM device %d\n", i); | 1249 | dev_err(&card->dev->dev, "Could not register ATM device %d\n", i); |
| 1250 | atm_remove(card); | 1250 | atm_remove(card); |
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c index 4e885d2da49..624917902b6 100644 --- a/drivers/atm/zatm.c +++ b/drivers/atm/zatm.c | |||
| @@ -1597,7 +1597,7 @@ static int __devinit zatm_init_one(struct pci_dev *pci_dev, | |||
| 1597 | goto out; | 1597 | goto out; |
| 1598 | } | 1598 | } |
| 1599 | 1599 | ||
| 1600 | dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL); | 1600 | dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL); |
| 1601 | if (!dev) | 1601 | if (!dev) |
| 1602 | goto out_free; | 1602 | goto out_free; |
| 1603 | 1603 | ||
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 4f9e22f2913..657873e4328 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
| @@ -72,7 +72,7 @@ struct blk_shadow { | |||
| 72 | static DEFINE_MUTEX(blkfront_mutex); | 72 | static DEFINE_MUTEX(blkfront_mutex); |
| 73 | static const struct block_device_operations xlvbd_block_fops; | 73 | static const struct block_device_operations xlvbd_block_fops; |
| 74 | 74 | ||
| 75 | #define BLK_RING_SIZE __RING_SIZE((struct blkif_sring *)0, PAGE_SIZE) | 75 | #define BLK_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE) |
| 76 | 76 | ||
| 77 | /* | 77 | /* |
| 78 | * We have one of these per vbd, whether ide, scsi or 'other'. They | 78 | * We have one of these per vbd, whether ide, scsi or 'other'. They |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 128cae4e862..949ed09c636 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
| @@ -35,6 +35,10 @@ | |||
| 35 | static struct usb_device_id ath3k_table[] = { | 35 | static struct usb_device_id ath3k_table[] = { |
| 36 | /* Atheros AR3011 */ | 36 | /* Atheros AR3011 */ |
| 37 | { USB_DEVICE(0x0CF3, 0x3000) }, | 37 | { USB_DEVICE(0x0CF3, 0x3000) }, |
| 38 | |||
| 39 | /* Atheros AR3011 with sflash firmware*/ | ||
| 40 | { USB_DEVICE(0x0CF3, 0x3002) }, | ||
| 41 | |||
| 38 | { } /* Terminating entry */ | 42 | { } /* Terminating entry */ |
| 39 | }; | 43 | }; |
| 40 | 44 | ||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index ab3894f742c..1da773f899a 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
| @@ -99,6 +99,9 @@ static struct usb_device_id blacklist_table[] = { | |||
| 99 | /* Broadcom BCM2033 without firmware */ | 99 | /* Broadcom BCM2033 without firmware */ |
| 100 | { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE }, | 100 | { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE }, |
| 101 | 101 | ||
| 102 | /* Atheros 3011 with sflash firmware */ | ||
| 103 | { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, | ||
| 104 | |||
| 102 | /* Broadcom BCM2035 */ | 105 | /* Broadcom BCM2035 */ |
| 103 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, | 106 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, |
| 104 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, | 107 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, |
| @@ -239,7 +242,8 @@ static void btusb_intr_complete(struct urb *urb) | |||
| 239 | 242 | ||
| 240 | err = usb_submit_urb(urb, GFP_ATOMIC); | 243 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| 241 | if (err < 0) { | 244 | if (err < 0) { |
| 242 | BT_ERR("%s urb %p failed to resubmit (%d)", | 245 | if (err != -EPERM) |
| 246 | BT_ERR("%s urb %p failed to resubmit (%d)", | ||
| 243 | hdev->name, urb, -err); | 247 | hdev->name, urb, -err); |
| 244 | usb_unanchor_urb(urb); | 248 | usb_unanchor_urb(urb); |
| 245 | } | 249 | } |
| @@ -323,7 +327,8 @@ static void btusb_bulk_complete(struct urb *urb) | |||
| 323 | 327 | ||
| 324 | err = usb_submit_urb(urb, GFP_ATOMIC); | 328 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| 325 | if (err < 0) { | 329 | if (err < 0) { |
| 326 | BT_ERR("%s urb %p failed to resubmit (%d)", | 330 | if (err != -EPERM) |
| 331 | BT_ERR("%s urb %p failed to resubmit (%d)", | ||
| 327 | hdev->name, urb, -err); | 332 | hdev->name, urb, -err); |
| 328 | usb_unanchor_urb(urb); | 333 | usb_unanchor_urb(urb); |
| 329 | } | 334 | } |
| @@ -412,7 +417,8 @@ static void btusb_isoc_complete(struct urb *urb) | |||
| 412 | 417 | ||
| 413 | err = usb_submit_urb(urb, GFP_ATOMIC); | 418 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| 414 | if (err < 0) { | 419 | if (err < 0) { |
| 415 | BT_ERR("%s urb %p failed to resubmit (%d)", | 420 | if (err != -EPERM) |
| 421 | BT_ERR("%s urb %p failed to resubmit (%d)", | ||
| 416 | hdev->name, urb, -err); | 422 | hdev->name, urb, -err); |
| 417 | usb_unanchor_urb(urb); | 423 | usb_unanchor_urb(urb); |
| 418 | } | 424 | } |
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index e16c3fa8d2e..05117f1ad86 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
| 37 | MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); | 37 | MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); |
| 38 | MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); | 38 | MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); |
| 39 | MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_CONNECTOR); | ||
| 39 | 40 | ||
| 40 | static struct cn_dev cdev; | 41 | static struct cn_dev cdev; |
| 41 | 42 | ||
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index a8a84f4587f..64b21f5cd74 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | ifeq ($(CONFIG_DMADEVICES_DEBUG),y) | 1 | ifeq ($(CONFIG_DMADEVICES_DEBUG),y) |
| 2 | EXTRA_CFLAGS += -DDEBUG | 2 | ccflags-y += -DDEBUG |
| 3 | endif | 3 | endif |
| 4 | ifeq ($(CONFIG_DMADEVICES_VDEBUG),y) | 4 | ifeq ($(CONFIG_DMADEVICES_VDEBUG),y) |
| 5 | EXTRA_CFLAGS += -DVERBOSE_DEBUG | 5 | ccflags-y += -DVERBOSE_DEBUG |
| 6 | endif | 6 | endif |
| 7 | 7 | ||
| 8 | obj-$(CONFIG_DMA_ENGINE) += dmaengine.o | 8 | obj-$(CONFIG_DMA_ENGINE) += dmaengine.o |
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index a0f3e6a06e0..ea0ee81cff5 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c | |||
| @@ -722,7 +722,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
| 722 | desc->lli.daddr = mem; | 722 | desc->lli.daddr = mem; |
| 723 | desc->lli.ctrla = ctrla | 723 | desc->lli.ctrla = ctrla |
| 724 | | ATC_DST_WIDTH(mem_width) | 724 | | ATC_DST_WIDTH(mem_width) |
| 725 | | len >> mem_width; | 725 | | len >> reg_width; |
| 726 | desc->lli.ctrlb = ctrlb; | 726 | desc->lli.ctrlb = ctrlb; |
| 727 | 727 | ||
| 728 | if (!first) { | 728 | if (!first) { |
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 286c3ac6bdc..e5e172d2169 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c | |||
| @@ -50,9 +50,11 @@ static void dma_init(struct fsldma_chan *chan) | |||
| 50 | * EIE - Error interrupt enable | 50 | * EIE - Error interrupt enable |
| 51 | * EOSIE - End of segments interrupt enable (basic mode) | 51 | * EOSIE - End of segments interrupt enable (basic mode) |
| 52 | * EOLNIE - End of links interrupt enable | 52 | * EOLNIE - End of links interrupt enable |
| 53 | * BWC - Bandwidth sharing among channels | ||
| 53 | */ | 54 | */ |
| 54 | DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_EIE | 55 | DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_BWC |
| 55 | | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32); | 56 | | FSL_DMA_MR_EIE | FSL_DMA_MR_EOLNIE |
| 57 | | FSL_DMA_MR_EOSIE, 32); | ||
| 56 | break; | 58 | break; |
| 57 | case FSL_DMA_IP_83XX: | 59 | case FSL_DMA_IP_83XX: |
| 58 | /* Set the channel to below modes: | 60 | /* Set the channel to below modes: |
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h index cb4d6ff5159..ba9f403c0fb 100644 --- a/drivers/dma/fsldma.h +++ b/drivers/dma/fsldma.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. | 2 | * Copyright (C) 2007-2010 Freescale Semiconductor, Inc. All rights reserved. |
| 3 | * | 3 | * |
| 4 | * Author: | 4 | * Author: |
| 5 | * Zhang Wei <wei.zhang@freescale.com>, Jul 2007 | 5 | * Zhang Wei <wei.zhang@freescale.com>, Jul 2007 |
| @@ -36,6 +36,13 @@ | |||
| 36 | #define FSL_DMA_MR_DAHE 0x00002000 | 36 | #define FSL_DMA_MR_DAHE 0x00002000 |
| 37 | #define FSL_DMA_MR_SAHE 0x00001000 | 37 | #define FSL_DMA_MR_SAHE 0x00001000 |
| 38 | 38 | ||
| 39 | /* | ||
| 40 | * Bandwidth/pause control determines how many bytes a given | ||
| 41 | * channel is allowed to transfer before the DMA engine pauses | ||
| 42 | * the current channel and switches to the next channel | ||
| 43 | */ | ||
| 44 | #define FSL_DMA_MR_BWC 0x08000000 | ||
| 45 | |||
| 39 | /* Special MR definition for MPC8349 */ | 46 | /* Special MR definition for MPC8349 */ |
| 40 | #define FSL_DMA_MR_EOTIE 0x00000080 | 47 | #define FSL_DMA_MR_EOTIE 0x00000080 |
| 41 | #define FSL_DMA_MR_PRC_RM 0x00000800 | 48 | #define FSL_DMA_MR_PRC_RM 0x00000800 |
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index f629e4961af..e53d438142b 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c | |||
| @@ -379,7 +379,7 @@ static int __init imxdma_probe(struct platform_device *pdev) | |||
| 379 | return 0; | 379 | return 0; |
| 380 | 380 | ||
| 381 | err_init: | 381 | err_init: |
| 382 | while (i-- >= 0) { | 382 | while (--i >= 0) { |
| 383 | struct imxdma_channel *imxdmac = &imxdma->channel[i]; | 383 | struct imxdma_channel *imxdmac = &imxdma->channel[i]; |
| 384 | imx_dma_free(imxdmac->imxdma_channel); | 384 | imx_dma_free(imxdmac->imxdma_channel); |
| 385 | } | 385 | } |
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 0834323a059..d0602dd5d1b 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c | |||
| @@ -951,7 +951,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( | |||
| 951 | struct sdma_buffer_descriptor *bd = &sdmac->bd[i]; | 951 | struct sdma_buffer_descriptor *bd = &sdmac->bd[i]; |
| 952 | int param; | 952 | int param; |
| 953 | 953 | ||
| 954 | bd->buffer_addr = sgl->dma_address; | 954 | bd->buffer_addr = sg->dma_address; |
| 955 | 955 | ||
| 956 | count = sg->length; | 956 | count = sg->length; |
| 957 | 957 | ||
| @@ -1385,7 +1385,7 @@ static int __init sdma_module_init(void) | |||
| 1385 | { | 1385 | { |
| 1386 | return platform_driver_probe(&sdma_driver, sdma_probe); | 1386 | return platform_driver_probe(&sdma_driver, sdma_probe); |
| 1387 | } | 1387 | } |
| 1388 | subsys_initcall(sdma_module_init); | 1388 | module_init(sdma_module_init); |
| 1389 | 1389 | ||
| 1390 | MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>"); | 1390 | MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>"); |
| 1391 | MODULE_DESCRIPTION("i.MX SDMA driver"); | 1391 | MODULE_DESCRIPTION("i.MX SDMA driver"); |
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c index 338bc4eed1f..3109bd94bc4 100644 --- a/drivers/dma/intel_mid_dma.c +++ b/drivers/dma/intel_mid_dma.c | |||
| @@ -1075,7 +1075,6 @@ static int mid_setup_dma(struct pci_dev *pdev) | |||
| 1075 | if (NULL == dma->dma_pool) { | 1075 | if (NULL == dma->dma_pool) { |
| 1076 | pr_err("ERR_MDMA:pci_pool_create failed\n"); | 1076 | pr_err("ERR_MDMA:pci_pool_create failed\n"); |
| 1077 | err = -ENOMEM; | 1077 | err = -ENOMEM; |
| 1078 | kfree(dma); | ||
| 1079 | goto err_dma_pool; | 1078 | goto err_dma_pool; |
| 1080 | } | 1079 | } |
| 1081 | 1080 | ||
| @@ -1186,7 +1185,6 @@ err_engine: | |||
| 1186 | free_irq(pdev->irq, dma); | 1185 | free_irq(pdev->irq, dma); |
| 1187 | err_irq: | 1186 | err_irq: |
| 1188 | pci_pool_destroy(dma->dma_pool); | 1187 | pci_pool_destroy(dma->dma_pool); |
| 1189 | kfree(dma); | ||
| 1190 | err_dma_pool: | 1188 | err_dma_pool: |
| 1191 | pr_err("ERR_MDMA:setup_dma failed: %d\n", err); | 1189 | pr_err("ERR_MDMA:setup_dma failed: %d\n", err); |
| 1192 | return err; | 1190 | return err; |
| @@ -1413,7 +1411,7 @@ static const struct dev_pm_ops intel_mid_dma_pm = { | |||
| 1413 | .runtime_idle = dma_runtime_idle, | 1411 | .runtime_idle = dma_runtime_idle, |
| 1414 | }; | 1412 | }; |
| 1415 | 1413 | ||
| 1416 | static struct pci_driver intel_mid_dma_pci = { | 1414 | static struct pci_driver intel_mid_dma_pci_driver = { |
| 1417 | .name = "Intel MID DMA", | 1415 | .name = "Intel MID DMA", |
| 1418 | .id_table = intel_mid_dma_ids, | 1416 | .id_table = intel_mid_dma_ids, |
| 1419 | .probe = intel_mid_dma_probe, | 1417 | .probe = intel_mid_dma_probe, |
| @@ -1431,13 +1429,13 @@ static int __init intel_mid_dma_init(void) | |||
| 1431 | { | 1429 | { |
| 1432 | pr_debug("INFO_MDMA: LNW DMA Driver Version %s\n", | 1430 | pr_debug("INFO_MDMA: LNW DMA Driver Version %s\n", |
| 1433 | INTEL_MID_DMA_DRIVER_VERSION); | 1431 | INTEL_MID_DMA_DRIVER_VERSION); |
| 1434 | return pci_register_driver(&intel_mid_dma_pci); | 1432 | return pci_register_driver(&intel_mid_dma_pci_driver); |
| 1435 | } | 1433 | } |
| 1436 | fs_initcall(intel_mid_dma_init); | 1434 | fs_initcall(intel_mid_dma_init); |
| 1437 | 1435 | ||
| 1438 | static void __exit intel_mid_dma_exit(void) | 1436 | static void __exit intel_mid_dma_exit(void) |
| 1439 | { | 1437 | { |
| 1440 | pci_unregister_driver(&intel_mid_dma_pci); | 1438 | pci_unregister_driver(&intel_mid_dma_pci_driver); |
| 1441 | } | 1439 | } |
| 1442 | module_exit(intel_mid_dma_exit); | 1440 | module_exit(intel_mid_dma_exit); |
| 1443 | 1441 | ||
diff --git a/drivers/dma/ioat/Makefile b/drivers/dma/ioat/Makefile index 8997d3fb905..0ff7270af25 100644 --- a/drivers/dma/ioat/Makefile +++ b/drivers/dma/ioat/Makefile | |||
| @@ -1,2 +1,2 @@ | |||
| 1 | obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o | 1 | obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o |
| 2 | ioatdma-objs := pci.o dma.o dma_v2.o dma_v3.o dca.o | 2 | ioatdma-y := pci.o dma.o dma_v2.o dma_v3.o dca.o |
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index 92b679024fe..c064c89420d 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c | |||
| @@ -259,11 +259,6 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) | |||
| 259 | return; | 259 | return; |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr); | ||
| 263 | channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr); | ||
| 264 | channel_writel(pd_chan, SIZE, desc->regs.size); | ||
| 265 | channel_writel(pd_chan, NEXT, desc->regs.next); | ||
| 266 | |||
| 267 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n", | 262 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n", |
| 268 | pd_chan->chan.chan_id, desc->regs.dev_addr); | 263 | pd_chan->chan.chan_id, desc->regs.dev_addr); |
| 269 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n", | 264 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n", |
| @@ -273,10 +268,16 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) | |||
| 273 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n", | 268 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n", |
| 274 | pd_chan->chan.chan_id, desc->regs.next); | 269 | pd_chan->chan.chan_id, desc->regs.next); |
| 275 | 270 | ||
| 276 | if (list_empty(&desc->tx_list)) | 271 | if (list_empty(&desc->tx_list)) { |
| 272 | channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr); | ||
| 273 | channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr); | ||
| 274 | channel_writel(pd_chan, SIZE, desc->regs.size); | ||
| 275 | channel_writel(pd_chan, NEXT, desc->regs.next); | ||
| 277 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT); | 276 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT); |
| 278 | else | 277 | } else { |
| 278 | channel_writel(pd_chan, NEXT, desc->txd.phys); | ||
| 279 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); | 279 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); |
| 280 | } | ||
| 280 | 281 | ||
| 281 | val = dma_readl(pd, CTL2); | 282 | val = dma_readl(pd, CTL2); |
| 282 | val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id); | 283 | val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id); |
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index 0d58a4a4487..cef584533ee 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c | |||
| @@ -4449,9 +4449,8 @@ static int __devinit ppc440spe_adma_probe(struct platform_device *ofdev, | |||
| 4449 | 4449 | ||
| 4450 | if (!request_mem_region(res.start, resource_size(&res), | 4450 | if (!request_mem_region(res.start, resource_size(&res), |
| 4451 | dev_driver_string(&ofdev->dev))) { | 4451 | dev_driver_string(&ofdev->dev))) { |
| 4452 | dev_err(&ofdev->dev, "failed to request memory region " | 4452 | dev_err(&ofdev->dev, "failed to request memory region %pR\n", |
| 4453 | "(0x%016llx-0x%016llx)\n", | 4453 | &res); |
| 4454 | (u64)res.start, (u64)res.end); | ||
| 4455 | initcode = PPC_ADMA_INIT_MEMREG; | 4454 | initcode = PPC_ADMA_INIT_MEMREG; |
| 4456 | ret = -EBUSY; | 4455 | ret = -EBUSY; |
| 4457 | goto out; | 4456 | goto out; |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 8521401bbd7..eca9ba193e9 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
| @@ -1572,7 +1572,7 @@ static int f10_match_to_this_node(struct amd64_pvt *pvt, int dram_range, | |||
| 1572 | debugf1(" HoleOffset=0x%x HoleValid=0x%x IntlvSel=0x%x\n", | 1572 | debugf1(" HoleOffset=0x%x HoleValid=0x%x IntlvSel=0x%x\n", |
| 1573 | hole_off, hole_valid, intlv_sel); | 1573 | hole_off, hole_valid, intlv_sel); |
| 1574 | 1574 | ||
| 1575 | if (intlv_en || | 1575 | if (intlv_en && |
| 1576 | (intlv_sel != ((sys_addr >> 12) & intlv_en))) | 1576 | (intlv_sel != ((sys_addr >> 12) & intlv_en))) |
| 1577 | return -EINVAL; | 1577 | return -EINVAL; |
| 1578 | 1578 | ||
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index d7ca43a828b..251440cd50a 100644 --- a/drivers/edac/edac_core.h +++ b/drivers/edac/edac_core.h | |||
| @@ -41,10 +41,10 @@ | |||
| 41 | #define MC_PROC_NAME_MAX_LEN 7 | 41 | #define MC_PROC_NAME_MAX_LEN 7 |
| 42 | 42 | ||
| 43 | #if PAGE_SHIFT < 20 | 43 | #if PAGE_SHIFT < 20 |
| 44 | #define PAGES_TO_MiB( pages ) ( ( pages ) >> ( 20 - PAGE_SHIFT ) ) | 44 | #define PAGES_TO_MiB(pages) ((pages) >> (20 - PAGE_SHIFT)) |
| 45 | #define MiB_TO_PAGES(mb) ((mb) >> (20 - PAGE_SHIFT)) | 45 | #define MiB_TO_PAGES(mb) ((mb) << (20 - PAGE_SHIFT)) |
| 46 | #else /* PAGE_SHIFT > 20 */ | 46 | #else /* PAGE_SHIFT > 20 */ |
| 47 | #define PAGES_TO_MiB( pages ) ( ( pages ) << ( PAGE_SHIFT - 20 ) ) | 47 | #define PAGES_TO_MiB(pages) ((pages) << (PAGE_SHIFT - 20)) |
| 48 | #define MiB_TO_PAGES(mb) ((mb) >> (PAGE_SHIFT - 20)) | 48 | #define MiB_TO_PAGES(mb) ((mb) >> (PAGE_SHIFT - 20)) |
| 49 | #endif | 49 | #endif |
| 50 | 50 | ||
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index ba6586a69cc..795ea69c4d8 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
| @@ -586,14 +586,16 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev) | |||
| 586 | return NULL; | 586 | return NULL; |
| 587 | } | 587 | } |
| 588 | 588 | ||
| 589 | /* marking MCI offline */ | ||
| 590 | mci->op_state = OP_OFFLINE; | ||
| 591 | |||
| 592 | del_mc_from_global_list(mci); | 589 | del_mc_from_global_list(mci); |
| 593 | mutex_unlock(&mem_ctls_mutex); | 590 | mutex_unlock(&mem_ctls_mutex); |
| 594 | 591 | ||
| 595 | /* flush workq processes and remove sysfs */ | 592 | /* flush workq processes */ |
| 596 | edac_mc_workq_teardown(mci); | 593 | edac_mc_workq_teardown(mci); |
| 594 | |||
| 595 | /* marking MCI offline */ | ||
| 596 | mci->op_state = OP_OFFLINE; | ||
| 597 | |||
| 598 | /* remove from sysfs */ | ||
| 597 | edac_remove_sysfs_mci_device(mci); | 599 | edac_remove_sysfs_mci_device(mci); |
| 598 | 600 | ||
| 599 | edac_printk(KERN_INFO, EDAC_MC, | 601 | edac_printk(KERN_INFO, EDAC_MC, |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 84eb607d6c0..e3c8b60bd86 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
| @@ -242,6 +242,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) | |||
| 242 | 242 | ||
| 243 | static char ohci_driver_name[] = KBUILD_MODNAME; | 243 | static char ohci_driver_name[] = KBUILD_MODNAME; |
| 244 | 244 | ||
| 245 | #define PCI_DEVICE_ID_AGERE_FW643 0x5901 | ||
| 245 | #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 | 246 | #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 |
| 246 | #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 | 247 | #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 |
| 247 | 248 | ||
| @@ -253,18 +254,34 @@ static char ohci_driver_name[] = KBUILD_MODNAME; | |||
| 253 | 254 | ||
| 254 | /* In case of multiple matches in ohci_quirks[], only the first one is used. */ | 255 | /* In case of multiple matches in ohci_quirks[], only the first one is used. */ |
| 255 | static const struct { | 256 | static const struct { |
| 256 | unsigned short vendor, device, flags; | 257 | unsigned short vendor, device, revision, flags; |
| 257 | } ohci_quirks[] = { | 258 | } ohci_quirks[] = { |
| 258 | {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER | | 259 | {PCI_VENDOR_ID_AL, PCI_ANY_ID, PCI_ANY_ID, |
| 259 | QUIRK_RESET_PACKET | | 260 | QUIRK_CYCLE_TIMER}, |
| 260 | QUIRK_NO_1394A}, | 261 | |
| 261 | {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, | 262 | {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, PCI_ANY_ID, |
| 262 | {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 263 | QUIRK_BE_HEADERS}, |
| 263 | {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI}, | 264 | |
| 264 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 265 | {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6, |
| 265 | {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 266 | QUIRK_NO_MSI}, |
| 266 | {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 267 | |
| 267 | {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS}, | 268 | {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID, |
| 269 | QUIRK_NO_MSI}, | ||
| 270 | |||
| 271 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, PCI_ANY_ID, | ||
| 272 | QUIRK_CYCLE_TIMER}, | ||
| 273 | |||
| 274 | {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID, | ||
| 275 | QUIRK_CYCLE_TIMER}, | ||
| 276 | |||
| 277 | {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID, | ||
| 278 | QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A}, | ||
| 279 | |||
| 280 | {PCI_VENDOR_ID_TI, PCI_ANY_ID, PCI_ANY_ID, | ||
| 281 | QUIRK_RESET_PACKET}, | ||
| 282 | |||
| 283 | {PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID, | ||
| 284 | QUIRK_CYCLE_TIMER | QUIRK_NO_MSI}, | ||
| 268 | }; | 285 | }; |
| 269 | 286 | ||
| 270 | /* This overrides anything that was found in ohci_quirks[]. */ | 287 | /* This overrides anything that was found in ohci_quirks[]. */ |
| @@ -2927,9 +2944,11 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
| 2927 | } | 2944 | } |
| 2928 | 2945 | ||
| 2929 | for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++) | 2946 | for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++) |
| 2930 | if (ohci_quirks[i].vendor == dev->vendor && | 2947 | if ((ohci_quirks[i].vendor == dev->vendor) && |
| 2931 | (ohci_quirks[i].device == dev->device || | 2948 | (ohci_quirks[i].device == (unsigned short)PCI_ANY_ID || |
| 2932 | ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) { | 2949 | ohci_quirks[i].device == dev->device) && |
| 2950 | (ohci_quirks[i].revision == (unsigned short)PCI_ANY_ID || | ||
| 2951 | ohci_quirks[i].revision >= dev->revision)) { | ||
| 2933 | ohci->quirks = ohci_quirks[i].flags; | 2952 | ohci->quirks = ohci_quirks[i].flags; |
| 2934 | break; | 2953 | break; |
| 2935 | } | 2954 | } |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 6985cb1da72..2baa6708e44 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -156,12 +156,12 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = | |||
| 156 | { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 }, | 156 | { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 }, |
| 157 | { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 }, | 157 | { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 }, |
| 158 | { DRM_MODE_CONNECTOR_Component, "Component", 0 }, | 158 | { DRM_MODE_CONNECTOR_Component, "Component", 0 }, |
| 159 | { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 }, | 159 | { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 }, |
| 160 | { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 }, | 160 | { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 }, |
| 161 | { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 }, | 161 | { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 }, |
| 162 | { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 }, | 162 | { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 }, |
| 163 | { DRM_MODE_CONNECTOR_TV, "TV", 0 }, | 163 | { DRM_MODE_CONNECTOR_TV, "TV", 0 }, |
| 164 | { DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort", 0 }, | 164 | { DRM_MODE_CONNECTOR_eDP, "eDP", 0 }, |
| 165 | }; | 165 | }; |
| 166 | 166 | ||
| 167 | static struct drm_prop_enum_list drm_encoder_enum_list[] = | 167 | static struct drm_prop_enum_list drm_encoder_enum_list[] = |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 722700d5d73..16d5155edad 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
| @@ -628,7 +628,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
| 628 | if ((seq - vblwait->request.sequence) <= (1 << 23)) { | 628 | if ((seq - vblwait->request.sequence) <= (1 << 23)) { |
| 629 | e->event.tv_sec = now.tv_sec; | 629 | e->event.tv_sec = now.tv_sec; |
| 630 | e->event.tv_usec = now.tv_usec; | 630 | e->event.tv_usec = now.tv_usec; |
| 631 | drm_vblank_put(dev, e->pipe); | 631 | drm_vblank_put(dev, pipe); |
| 632 | list_add_tail(&e->base.link, &e->base.file_priv->event_list); | 632 | list_add_tail(&e->base.link, &e->base.file_priv->event_list); |
| 633 | wake_up_interruptible(&e->base.file_priv->event_wait); | 633 | wake_up_interruptible(&e->base.file_priv->event_wait); |
| 634 | trace_drm_vblank_event_delivered(current->pid, pipe, | 634 | trace_drm_vblank_event_delivered(current->pid, pipe, |
| @@ -645,7 +645,7 @@ err_unlock: | |||
| 645 | spin_unlock_irqrestore(&dev->event_lock, flags); | 645 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 646 | kfree(e); | 646 | kfree(e); |
| 647 | err_put: | 647 | err_put: |
| 648 | drm_vblank_put(dev, e->pipe); | 648 | drm_vblank_put(dev, pipe); |
| 649 | return ret; | 649 | return ret; |
| 650 | } | 650 | } |
| 651 | 651 | ||
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index a322d4f647b..4d7a2e1bdb9 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -878,12 +878,15 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
| 878 | u32 tmp; | 878 | u32 tmp; |
| 879 | 879 | ||
| 880 | /* flush hdp cache so updates hit vram */ | 880 | /* flush hdp cache so updates hit vram */ |
| 881 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { | 881 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && |
| 882 | !(rdev->flags & RADEON_IS_AGP)) { | ||
| 882 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | 883 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; |
| 883 | u32 tmp; | 884 | u32 tmp; |
| 884 | 885 | ||
| 885 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read | 886 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read |
| 886 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL | 887 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL |
| 888 | * This seems to cause problems on some AGP cards. Just use the old | ||
| 889 | * method for them. | ||
| 887 | */ | 890 | */ |
| 888 | WREG32(HDP_DEBUG1, 0); | 891 | WREG32(HDP_DEBUG1, 0); |
| 889 | tmp = readl((void __iomem *)ptr); | 892 | tmp = readl((void __iomem *)ptr); |
| @@ -3485,10 +3488,12 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev) | |||
| 3485 | void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | 3488 | void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) |
| 3486 | { | 3489 | { |
| 3487 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read | 3490 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read |
| 3488 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL | 3491 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL. |
| 3492 | * This seems to cause problems on some AGP cards. Just use the old | ||
| 3493 | * method for them. | ||
| 3489 | */ | 3494 | */ |
| 3490 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && | 3495 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && |
| 3491 | rdev->vram_scratch.ptr) { | 3496 | rdev->vram_scratch.ptr && !(rdev->flags & RADEON_IS_AGP)) { |
| 3492 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; | 3497 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; |
| 3493 | u32 tmp; | 3498 | u32 tmp; |
| 3494 | 3499 | ||
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 4bf969c0a32..be0fdd58aa2 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c | |||
| @@ -916,27 +916,27 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
| 916 | int nr = sensor_attr->index; | 916 | int nr = sensor_attr->index; |
| 917 | struct i2c_client *client = to_i2c_client(dev); | 917 | struct i2c_client *client = to_i2c_client(dev); |
| 918 | struct adm1026_data *data = i2c_get_clientdata(client); | 918 | struct adm1026_data *data = i2c_get_clientdata(client); |
| 919 | int val, orig_div, new_div, shift; | 919 | int val, orig_div, new_div; |
| 920 | 920 | ||
| 921 | val = simple_strtol(buf, NULL, 10); | 921 | val = simple_strtol(buf, NULL, 10); |
| 922 | new_div = DIV_TO_REG(val); | 922 | new_div = DIV_TO_REG(val); |
| 923 | if (new_div == 0) { | 923 | |
| 924 | return -EINVAL; | ||
| 925 | } | ||
| 926 | mutex_lock(&data->update_lock); | 924 | mutex_lock(&data->update_lock); |
| 927 | orig_div = data->fan_div[nr]; | 925 | orig_div = data->fan_div[nr]; |
| 928 | data->fan_div[nr] = DIV_FROM_REG(new_div); | 926 | data->fan_div[nr] = DIV_FROM_REG(new_div); |
| 929 | 927 | ||
| 930 | if (nr < 4) { /* 0 <= nr < 4 */ | 928 | if (nr < 4) { /* 0 <= nr < 4 */ |
| 931 | shift = 2 * nr; | ||
| 932 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3, | 929 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3, |
| 933 | ((DIV_TO_REG(orig_div) & (~(0x03 << shift))) | | 930 | (DIV_TO_REG(data->fan_div[0]) << 0) | |
| 934 | (new_div << shift))); | 931 | (DIV_TO_REG(data->fan_div[1]) << 2) | |
| 932 | (DIV_TO_REG(data->fan_div[2]) << 4) | | ||
| 933 | (DIV_TO_REG(data->fan_div[3]) << 6)); | ||
| 935 | } else { /* 3 < nr < 8 */ | 934 | } else { /* 3 < nr < 8 */ |
| 936 | shift = 2 * (nr - 4); | ||
| 937 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7, | 935 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7, |
| 938 | ((DIV_TO_REG(orig_div) & (~(0x03 << (2 * shift)))) | | 936 | (DIV_TO_REG(data->fan_div[4]) << 0) | |
| 939 | (new_div << shift))); | 937 | (DIV_TO_REG(data->fan_div[5]) << 2) | |
| 938 | (DIV_TO_REG(data->fan_div[6]) << 4) | | ||
| 939 | (DIV_TO_REG(data->fan_div[7]) << 6)); | ||
| 940 | } | 940 | } |
| 941 | 941 | ||
| 942 | if (data->fan_div[nr] != orig_div) { | 942 | if (data->fan_div[nr] != orig_div) { |
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 14a5d981be7..a428a926419 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
| @@ -187,6 +187,7 @@ static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 }; | |||
| 187 | #define IT87_REG_FAN_MAIN_CTRL 0x13 | 187 | #define IT87_REG_FAN_MAIN_CTRL 0x13 |
| 188 | #define IT87_REG_FAN_CTL 0x14 | 188 | #define IT87_REG_FAN_CTL 0x14 |
| 189 | #define IT87_REG_PWM(nr) (0x15 + (nr)) | 189 | #define IT87_REG_PWM(nr) (0x15 + (nr)) |
| 190 | #define IT87_REG_PWM_DUTY(nr) (0x63 + (nr) * 8) | ||
| 190 | 191 | ||
| 191 | #define IT87_REG_VIN(nr) (0x20 + (nr)) | 192 | #define IT87_REG_VIN(nr) (0x20 + (nr)) |
| 192 | #define IT87_REG_TEMP(nr) (0x29 + (nr)) | 193 | #define IT87_REG_TEMP(nr) (0x29 + (nr)) |
| @@ -251,12 +252,16 @@ struct it87_data { | |||
| 251 | u8 fan_main_ctrl; /* Register value */ | 252 | u8 fan_main_ctrl; /* Register value */ |
| 252 | u8 fan_ctl; /* Register value */ | 253 | u8 fan_ctl; /* Register value */ |
| 253 | 254 | ||
| 254 | /* The following 3 arrays correspond to the same registers. The | 255 | /* The following 3 arrays correspond to the same registers up to |
| 255 | * meaning of bits 6-0 depends on the value of bit 7, and we want | 256 | * the IT8720F. The meaning of bits 6-0 depends on the value of bit |
| 256 | * to preserve settings on mode changes, so we have to track all | 257 | * 7, and we want to preserve settings on mode changes, so we have |
| 257 | * values separately. */ | 258 | * to track all values separately. |
| 259 | * Starting with the IT8721F, the manual PWM duty cycles are stored | ||
| 260 | * in separate registers (8-bit values), so the separate tracking | ||
| 261 | * is no longer needed, but it is still done to keep the driver | ||
| 262 | * simple. */ | ||
| 258 | u8 pwm_ctrl[3]; /* Register value */ | 263 | u8 pwm_ctrl[3]; /* Register value */ |
| 259 | u8 pwm_duty[3]; /* Manual PWM value set by user (bit 6-0) */ | 264 | u8 pwm_duty[3]; /* Manual PWM value set by user */ |
| 260 | u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */ | 265 | u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */ |
| 261 | 266 | ||
| 262 | /* Automatic fan speed control registers */ | 267 | /* Automatic fan speed control registers */ |
| @@ -832,7 +837,9 @@ static ssize_t set_pwm_enable(struct device *dev, | |||
| 832 | data->fan_main_ctrl); | 837 | data->fan_main_ctrl); |
| 833 | } else { | 838 | } else { |
| 834 | if (val == 1) /* Manual mode */ | 839 | if (val == 1) /* Manual mode */ |
| 835 | data->pwm_ctrl[nr] = data->pwm_duty[nr]; | 840 | data->pwm_ctrl[nr] = data->type == it8721 ? |
| 841 | data->pwm_temp_map[nr] : | ||
| 842 | data->pwm_duty[nr]; | ||
| 836 | else /* Automatic mode */ | 843 | else /* Automatic mode */ |
| 837 | data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; | 844 | data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; |
| 838 | it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); | 845 | it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); |
| @@ -858,12 +865,25 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
| 858 | return -EINVAL; | 865 | return -EINVAL; |
| 859 | 866 | ||
| 860 | mutex_lock(&data->update_lock); | 867 | mutex_lock(&data->update_lock); |
| 861 | data->pwm_duty[nr] = pwm_to_reg(data, val); | 868 | if (data->type == it8721) { |
| 862 | /* If we are in manual mode, write the duty cycle immediately; | 869 | /* If we are in automatic mode, the PWM duty cycle register |
| 863 | * otherwise, just store it for later use. */ | 870 | * is read-only so we can't write the value */ |
| 864 | if (!(data->pwm_ctrl[nr] & 0x80)) { | 871 | if (data->pwm_ctrl[nr] & 0x80) { |
| 865 | data->pwm_ctrl[nr] = data->pwm_duty[nr]; | 872 | mutex_unlock(&data->update_lock); |
| 866 | it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); | 873 | return -EBUSY; |
| 874 | } | ||
| 875 | data->pwm_duty[nr] = pwm_to_reg(data, val); | ||
| 876 | it87_write_value(data, IT87_REG_PWM_DUTY(nr), | ||
| 877 | data->pwm_duty[nr]); | ||
| 878 | } else { | ||
| 879 | data->pwm_duty[nr] = pwm_to_reg(data, val); | ||
| 880 | /* If we are in manual mode, write the duty cycle immediately; | ||
| 881 | * otherwise, just store it for later use. */ | ||
| 882 | if (!(data->pwm_ctrl[nr] & 0x80)) { | ||
| 883 | data->pwm_ctrl[nr] = data->pwm_duty[nr]; | ||
| 884 | it87_write_value(data, IT87_REG_PWM(nr), | ||
| 885 | data->pwm_ctrl[nr]); | ||
| 886 | } | ||
| 867 | } | 887 | } |
| 868 | mutex_unlock(&data->update_lock); | 888 | mutex_unlock(&data->update_lock); |
| 869 | return count; | 889 | return count; |
| @@ -1958,7 +1978,10 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
| 1958 | * channels to use when later setting to automatic mode later. | 1978 | * channels to use when later setting to automatic mode later. |
| 1959 | * Use a 1:1 mapping by default (we are clueless.) | 1979 | * Use a 1:1 mapping by default (we are clueless.) |
| 1960 | * In both cases, the value can (and should) be changed by the user | 1980 | * In both cases, the value can (and should) be changed by the user |
| 1961 | * prior to switching to a different mode. */ | 1981 | * prior to switching to a different mode. |
| 1982 | * Note that this is no longer needed for the IT8721F and later, as | ||
| 1983 | * these have separate registers for the temperature mapping and the | ||
| 1984 | * manual duty cycle. */ | ||
| 1962 | for (i = 0; i < 3; i++) { | 1985 | for (i = 0; i < 3; i++) { |
| 1963 | data->pwm_temp_map[i] = i; | 1986 | data->pwm_temp_map[i] = i; |
| 1964 | data->pwm_duty[i] = 0x7f; /* Full speed */ | 1987 | data->pwm_duty[i] = 0x7f; /* Full speed */ |
| @@ -2034,10 +2057,16 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
| 2034 | static void it87_update_pwm_ctrl(struct it87_data *data, int nr) | 2057 | static void it87_update_pwm_ctrl(struct it87_data *data, int nr) |
| 2035 | { | 2058 | { |
| 2036 | data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr)); | 2059 | data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr)); |
| 2037 | if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */ | 2060 | if (data->type == it8721) { |
| 2038 | data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; | 2061 | data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; |
| 2039 | else /* Manual mode */ | 2062 | data->pwm_duty[nr] = it87_read_value(data, |
| 2040 | data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f; | 2063 | IT87_REG_PWM_DUTY(nr)); |
| 2064 | } else { | ||
| 2065 | if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */ | ||
| 2066 | data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; | ||
| 2067 | else /* Manual mode */ | ||
| 2068 | data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f; | ||
| 2069 | } | ||
| 2041 | 2070 | ||
| 2042 | if (has_old_autopwm(data)) { | 2071 | if (has_old_autopwm(data)) { |
| 2043 | int i; | 2072 | int i; |
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c index 00d975eb5b8..c7e6d8e8165 100644 --- a/drivers/hwmon/ltc4215.c +++ b/drivers/hwmon/ltc4215.c | |||
| @@ -205,7 +205,6 @@ LTC4215_ALARM(curr1_max_alarm, (1 << 2), LTC4215_STATUS); | |||
| 205 | 205 | ||
| 206 | /* Power (virtual) */ | 206 | /* Power (virtual) */ |
| 207 | LTC4215_POWER(power1_input); | 207 | LTC4215_POWER(power1_input); |
| 208 | LTC4215_ALARM(power1_alarm, (1 << 3), LTC4215_STATUS); | ||
| 209 | 208 | ||
| 210 | /* Input Voltage */ | 209 | /* Input Voltage */ |
| 211 | LTC4215_VOLTAGE(in1_input, LTC4215_ADIN); | 210 | LTC4215_VOLTAGE(in1_input, LTC4215_ADIN); |
| @@ -214,6 +213,7 @@ LTC4215_ALARM(in1_min_alarm, (1 << 1), LTC4215_STATUS); | |||
| 214 | 213 | ||
| 215 | /* Output Voltage */ | 214 | /* Output Voltage */ |
| 216 | LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE); | 215 | LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE); |
| 216 | LTC4215_ALARM(in2_min_alarm, (1 << 3), LTC4215_STATUS); | ||
| 217 | 217 | ||
| 218 | /* Finally, construct an array of pointers to members of the above objects, | 218 | /* Finally, construct an array of pointers to members of the above objects, |
| 219 | * as required for sysfs_create_group() | 219 | * as required for sysfs_create_group() |
| @@ -223,13 +223,13 @@ static struct attribute *ltc4215_attributes[] = { | |||
| 223 | &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, | 223 | &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, |
| 224 | 224 | ||
| 225 | &sensor_dev_attr_power1_input.dev_attr.attr, | 225 | &sensor_dev_attr_power1_input.dev_attr.attr, |
| 226 | &sensor_dev_attr_power1_alarm.dev_attr.attr, | ||
| 227 | 226 | ||
| 228 | &sensor_dev_attr_in1_input.dev_attr.attr, | 227 | &sensor_dev_attr_in1_input.dev_attr.attr, |
| 229 | &sensor_dev_attr_in1_max_alarm.dev_attr.attr, | 228 | &sensor_dev_attr_in1_max_alarm.dev_attr.attr, |
| 230 | &sensor_dev_attr_in1_min_alarm.dev_attr.attr, | 229 | &sensor_dev_attr_in1_min_alarm.dev_attr.attr, |
| 231 | 230 | ||
| 232 | &sensor_dev_attr_in2_input.dev_attr.attr, | 231 | &sensor_dev_attr_in2_input.dev_attr.attr, |
| 232 | &sensor_dev_attr_in2_min_alarm.dev_attr.attr, | ||
| 233 | 233 | ||
| 234 | NULL, | 234 | NULL, |
| 235 | }; | 235 | }; |
diff --git a/drivers/i2c/busses/i2c-intel-mid.c b/drivers/i2c/busses/i2c-intel-mid.c index 80f70d3a744..c71492782bb 100644 --- a/drivers/i2c/busses/i2c-intel-mid.c +++ b/drivers/i2c/busses/i2c-intel-mid.c | |||
| @@ -999,7 +999,7 @@ static int __devinit intel_mid_i2c_probe(struct pci_dev *dev, | |||
| 999 | 999 | ||
| 1000 | /* Initialize struct members */ | 1000 | /* Initialize struct members */ |
| 1001 | snprintf(mrst->adap.name, sizeof(mrst->adap.name), | 1001 | snprintf(mrst->adap.name, sizeof(mrst->adap.name), |
| 1002 | "MRST/Medfield I2C at %lx", start); | 1002 | "Intel MID I2C at %lx", start); |
| 1003 | mrst->adap.owner = THIS_MODULE; | 1003 | mrst->adap.owner = THIS_MODULE; |
| 1004 | mrst->adap.algo = &intel_mid_i2c_algorithm; | 1004 | mrst->adap.algo = &intel_mid_i2c_algorithm; |
| 1005 | mrst->adap.dev.parent = &dev->dev; | 1005 | mrst->adap.dev.parent = &dev->dev; |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 41665d2f9f9..c131d58bcb5 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
| @@ -273,8 +273,6 @@ static int intel_idle_probe(void) | |||
| 273 | 273 | ||
| 274 | pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates); | 274 | pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates); |
| 275 | 275 | ||
| 276 | if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ | ||
| 277 | lapic_timer_reliable_states = 0xFFFFFFFF; | ||
| 278 | 276 | ||
| 279 | if (boot_cpu_data.x86 != 6) /* family 6 */ | 277 | if (boot_cpu_data.x86 != 6) /* family 6 */ |
| 280 | return -ENODEV; | 278 | return -ENODEV; |
| @@ -286,8 +284,6 @@ static int intel_idle_probe(void) | |||
| 286 | case 0x1F: /* Core i7 and i5 Processor - Nehalem */ | 284 | case 0x1F: /* Core i7 and i5 Processor - Nehalem */ |
| 287 | case 0x2E: /* Nehalem-EX Xeon */ | 285 | case 0x2E: /* Nehalem-EX Xeon */ |
| 288 | case 0x2F: /* Westmere-EX Xeon */ | 286 | case 0x2F: /* Westmere-EX Xeon */ |
| 289 | lapic_timer_reliable_states = (1 << 1); /* C1 */ | ||
| 290 | |||
| 291 | case 0x25: /* Westmere */ | 287 | case 0x25: /* Westmere */ |
| 292 | case 0x2C: /* Westmere */ | 288 | case 0x2C: /* Westmere */ |
| 293 | cpuidle_state_table = nehalem_cstates; | 289 | cpuidle_state_table = nehalem_cstates; |
| @@ -295,7 +291,6 @@ static int intel_idle_probe(void) | |||
| 295 | 291 | ||
| 296 | case 0x1C: /* 28 - Atom Processor */ | 292 | case 0x1C: /* 28 - Atom Processor */ |
| 297 | case 0x26: /* 38 - Lincroft Atom Processor */ | 293 | case 0x26: /* 38 - Lincroft Atom Processor */ |
| 298 | lapic_timer_reliable_states = (1 << 1); /* C1 */ | ||
| 299 | cpuidle_state_table = atom_cstates; | 294 | cpuidle_state_table = atom_cstates; |
| 300 | break; | 295 | break; |
| 301 | 296 | ||
| @@ -303,10 +298,6 @@ static int intel_idle_probe(void) | |||
| 303 | case 0x2D: /* SNB Xeon */ | 298 | case 0x2D: /* SNB Xeon */ |
| 304 | cpuidle_state_table = snb_cstates; | 299 | cpuidle_state_table = snb_cstates; |
| 305 | break; | 300 | break; |
| 306 | #ifdef FUTURE_USE | ||
| 307 | case 0x17: /* 23 - Core 2 Duo */ | ||
| 308 | lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */ | ||
| 309 | #endif | ||
| 310 | 301 | ||
| 311 | default: | 302 | default: |
| 312 | pr_debug(PREFIX "does not run on family %d model %d\n", | 303 | pr_debug(PREFIX "does not run on family %d model %d\n", |
| @@ -314,6 +305,9 @@ static int intel_idle_probe(void) | |||
| 314 | return -ENODEV; | 305 | return -ENODEV; |
| 315 | } | 306 | } |
| 316 | 307 | ||
| 308 | if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ | ||
| 309 | lapic_timer_reliable_states = 0xFFFFFFFF; | ||
| 310 | |||
| 317 | pr_debug(PREFIX "v" INTEL_IDLE_VERSION | 311 | pr_debug(PREFIX "v" INTEL_IDLE_VERSION |
| 318 | " model 0x%X\n", boot_cpu_data.x86_model); | 312 | " model 0x%X\n", boot_cpu_data.x86_model); |
| 319 | 313 | ||
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index b342248aec0..c42699285f8 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
| @@ -893,68 +893,81 @@ out: | |||
| 893 | return ret ? ret : in_len; | 893 | return ret ? ret : in_len; |
| 894 | } | 894 | } |
| 895 | 895 | ||
| 896 | static int copy_wc_to_user(void __user *dest, struct ib_wc *wc) | ||
| 897 | { | ||
| 898 | struct ib_uverbs_wc tmp; | ||
| 899 | |||
| 900 | tmp.wr_id = wc->wr_id; | ||
| 901 | tmp.status = wc->status; | ||
| 902 | tmp.opcode = wc->opcode; | ||
| 903 | tmp.vendor_err = wc->vendor_err; | ||
| 904 | tmp.byte_len = wc->byte_len; | ||
| 905 | tmp.ex.imm_data = (__u32 __force) wc->ex.imm_data; | ||
| 906 | tmp.qp_num = wc->qp->qp_num; | ||
| 907 | tmp.src_qp = wc->src_qp; | ||
| 908 | tmp.wc_flags = wc->wc_flags; | ||
| 909 | tmp.pkey_index = wc->pkey_index; | ||
| 910 | tmp.slid = wc->slid; | ||
| 911 | tmp.sl = wc->sl; | ||
| 912 | tmp.dlid_path_bits = wc->dlid_path_bits; | ||
| 913 | tmp.port_num = wc->port_num; | ||
| 914 | tmp.reserved = 0; | ||
| 915 | |||
| 916 | if (copy_to_user(dest, &tmp, sizeof tmp)) | ||
| 917 | return -EFAULT; | ||
| 918 | |||
| 919 | return 0; | ||
| 920 | } | ||
| 921 | |||
| 896 | ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, | 922 | ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, |
| 897 | const char __user *buf, int in_len, | 923 | const char __user *buf, int in_len, |
| 898 | int out_len) | 924 | int out_len) |
| 899 | { | 925 | { |
| 900 | struct ib_uverbs_poll_cq cmd; | 926 | struct ib_uverbs_poll_cq cmd; |
| 901 | struct ib_uverbs_poll_cq_resp *resp; | 927 | struct ib_uverbs_poll_cq_resp resp; |
| 928 | u8 __user *header_ptr; | ||
| 929 | u8 __user *data_ptr; | ||
| 902 | struct ib_cq *cq; | 930 | struct ib_cq *cq; |
| 903 | struct ib_wc *wc; | 931 | struct ib_wc wc; |
| 904 | int ret = 0; | 932 | int ret; |
| 905 | int i; | ||
| 906 | int rsize; | ||
| 907 | 933 | ||
| 908 | if (copy_from_user(&cmd, buf, sizeof cmd)) | 934 | if (copy_from_user(&cmd, buf, sizeof cmd)) |
| 909 | return -EFAULT; | 935 | return -EFAULT; |
| 910 | 936 | ||
| 911 | wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL); | ||
| 912 | if (!wc) | ||
| 913 | return -ENOMEM; | ||
| 914 | |||
| 915 | rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc); | ||
| 916 | resp = kmalloc(rsize, GFP_KERNEL); | ||
| 917 | if (!resp) { | ||
| 918 | ret = -ENOMEM; | ||
| 919 | goto out_wc; | ||
| 920 | } | ||
| 921 | |||
| 922 | cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0); | 937 | cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0); |
| 923 | if (!cq) { | 938 | if (!cq) |
| 924 | ret = -EINVAL; | 939 | return -EINVAL; |
| 925 | goto out; | ||
| 926 | } | ||
| 927 | 940 | ||
| 928 | resp->count = ib_poll_cq(cq, cmd.ne, wc); | 941 | /* we copy a struct ib_uverbs_poll_cq_resp to user space */ |
| 942 | header_ptr = (void __user *)(unsigned long) cmd.response; | ||
| 943 | data_ptr = header_ptr + sizeof resp; | ||
| 929 | 944 | ||
| 930 | put_cq_read(cq); | 945 | memset(&resp, 0, sizeof resp); |
| 946 | while (resp.count < cmd.ne) { | ||
| 947 | ret = ib_poll_cq(cq, 1, &wc); | ||
| 948 | if (ret < 0) | ||
| 949 | goto out_put; | ||
| 950 | if (!ret) | ||
| 951 | break; | ||
| 952 | |||
| 953 | ret = copy_wc_to_user(data_ptr, &wc); | ||
| 954 | if (ret) | ||
| 955 | goto out_put; | ||
| 931 | 956 | ||
| 932 | for (i = 0; i < resp->count; i++) { | 957 | data_ptr += sizeof(struct ib_uverbs_wc); |
| 933 | resp->wc[i].wr_id = wc[i].wr_id; | 958 | ++resp.count; |
| 934 | resp->wc[i].status = wc[i].status; | ||
| 935 | resp->wc[i].opcode = wc[i].opcode; | ||
| 936 | resp->wc[i].vendor_err = wc[i].vendor_err; | ||
| 937 | resp->wc[i].byte_len = wc[i].byte_len; | ||
| 938 | resp->wc[i].ex.imm_data = (__u32 __force) wc[i].ex.imm_data; | ||
| 939 | resp->wc[i].qp_num = wc[i].qp->qp_num; | ||
| 940 | resp->wc[i].src_qp = wc[i].src_qp; | ||
| 941 | resp->wc[i].wc_flags = wc[i].wc_flags; | ||
| 942 | resp->wc[i].pkey_index = wc[i].pkey_index; | ||
| 943 | resp->wc[i].slid = wc[i].slid; | ||
| 944 | resp->wc[i].sl = wc[i].sl; | ||
| 945 | resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits; | ||
| 946 | resp->wc[i].port_num = wc[i].port_num; | ||
| 947 | } | 959 | } |
| 948 | 960 | ||
| 949 | if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize)) | 961 | if (copy_to_user(header_ptr, &resp, sizeof resp)) { |
| 950 | ret = -EFAULT; | 962 | ret = -EFAULT; |
| 963 | goto out_put; | ||
| 964 | } | ||
| 951 | 965 | ||
| 952 | out: | 966 | ret = in_len; |
| 953 | kfree(resp); | ||
| 954 | 967 | ||
| 955 | out_wc: | 968 | out_put: |
| 956 | kfree(wc); | 969 | put_cq_read(cq); |
| 957 | return ret ? ret : in_len; | 970 | return ret; |
| 958 | } | 971 | } |
| 959 | 972 | ||
| 960 | ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file, | 973 | ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file, |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index e3f7fc6f956..68f09a86843 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
| @@ -534,76 +534,73 @@ static int handle_eviocgbit(struct input_dev *dev, | |||
| 534 | } | 534 | } |
| 535 | #undef OLD_KEY_MAX | 535 | #undef OLD_KEY_MAX |
| 536 | 536 | ||
| 537 | static int evdev_handle_get_keycode(struct input_dev *dev, | 537 | static int evdev_handle_get_keycode(struct input_dev *dev, void __user *p) |
| 538 | void __user *p, size_t size) | ||
| 539 | { | 538 | { |
| 540 | struct input_keymap_entry ke; | 539 | struct input_keymap_entry ke = { |
| 540 | .len = sizeof(unsigned int), | ||
| 541 | .flags = 0, | ||
| 542 | }; | ||
| 543 | int __user *ip = (int __user *)p; | ||
| 541 | int error; | 544 | int error; |
| 542 | 545 | ||
| 543 | memset(&ke, 0, sizeof(ke)); | 546 | /* legacy case */ |
| 544 | 547 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | |
| 545 | if (size == sizeof(unsigned int[2])) { | 548 | return -EFAULT; |
| 546 | /* legacy case */ | ||
| 547 | int __user *ip = (int __user *)p; | ||
| 548 | 549 | ||
| 549 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | 550 | error = input_get_keycode(dev, &ke); |
| 550 | return -EFAULT; | 551 | if (error) |
| 552 | return error; | ||
| 551 | 553 | ||
| 552 | ke.len = sizeof(unsigned int); | 554 | if (put_user(ke.keycode, ip + 1)) |
| 553 | ke.flags = 0; | 555 | return -EFAULT; |
| 554 | 556 | ||
| 555 | error = input_get_keycode(dev, &ke); | 557 | return 0; |
| 556 | if (error) | 558 | } |
| 557 | return error; | ||
| 558 | 559 | ||
| 559 | if (put_user(ke.keycode, ip + 1)) | 560 | static int evdev_handle_get_keycode_v2(struct input_dev *dev, void __user *p) |
| 560 | return -EFAULT; | 561 | { |
| 562 | struct input_keymap_entry ke; | ||
| 563 | int error; | ||
| 561 | 564 | ||
| 562 | } else { | 565 | if (copy_from_user(&ke, p, sizeof(ke))) |
| 563 | size = min(size, sizeof(ke)); | 566 | return -EFAULT; |
| 564 | 567 | ||
| 565 | if (copy_from_user(&ke, p, size)) | 568 | error = input_get_keycode(dev, &ke); |
| 566 | return -EFAULT; | 569 | if (error) |
| 570 | return error; | ||
| 567 | 571 | ||
| 568 | error = input_get_keycode(dev, &ke); | 572 | if (copy_to_user(p, &ke, sizeof(ke))) |
| 569 | if (error) | 573 | return -EFAULT; |
| 570 | return error; | ||
| 571 | 574 | ||
| 572 | if (copy_to_user(p, &ke, size)) | ||
| 573 | return -EFAULT; | ||
| 574 | } | ||
| 575 | return 0; | 575 | return 0; |
| 576 | } | 576 | } |
| 577 | 577 | ||
| 578 | static int evdev_handle_set_keycode(struct input_dev *dev, | 578 | static int evdev_handle_set_keycode(struct input_dev *dev, void __user *p) |
| 579 | void __user *p, size_t size) | ||
| 580 | { | 579 | { |
| 581 | struct input_keymap_entry ke; | 580 | struct input_keymap_entry ke = { |
| 582 | 581 | .len = sizeof(unsigned int), | |
| 583 | memset(&ke, 0, sizeof(ke)); | 582 | .flags = 0, |
| 583 | }; | ||
| 584 | int __user *ip = (int __user *)p; | ||
| 584 | 585 | ||
| 585 | if (size == sizeof(unsigned int[2])) { | 586 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) |
| 586 | /* legacy case */ | 587 | return -EFAULT; |
| 587 | int __user *ip = (int __user *)p; | ||
| 588 | 588 | ||
| 589 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | 589 | if (get_user(ke.keycode, ip + 1)) |
| 590 | return -EFAULT; | 590 | return -EFAULT; |
| 591 | 591 | ||
| 592 | if (get_user(ke.keycode, ip + 1)) | 592 | return input_set_keycode(dev, &ke); |
| 593 | return -EFAULT; | 593 | } |
| 594 | 594 | ||
| 595 | ke.len = sizeof(unsigned int); | 595 | static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p) |
| 596 | ke.flags = 0; | 596 | { |
| 597 | struct input_keymap_entry ke; | ||
| 597 | 598 | ||
| 598 | } else { | 599 | if (copy_from_user(&ke, p, sizeof(ke))) |
| 599 | size = min(size, sizeof(ke)); | 600 | return -EFAULT; |
| 600 | 601 | ||
| 601 | if (copy_from_user(&ke, p, size)) | 602 | if (ke.len > sizeof(ke.scancode)) |
| 602 | return -EFAULT; | 603 | return -EINVAL; |
| 603 | |||
| 604 | if (ke.len > sizeof(ke.scancode)) | ||
| 605 | return -EINVAL; | ||
| 606 | } | ||
| 607 | 604 | ||
| 608 | return input_set_keycode(dev, &ke); | 605 | return input_set_keycode(dev, &ke); |
| 609 | } | 606 | } |
| @@ -669,6 +666,18 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
| 669 | return evdev_grab(evdev, client); | 666 | return evdev_grab(evdev, client); |
| 670 | else | 667 | else |
| 671 | return evdev_ungrab(evdev, client); | 668 | return evdev_ungrab(evdev, client); |
| 669 | |||
| 670 | case EVIOCGKEYCODE: | ||
| 671 | return evdev_handle_get_keycode(dev, p); | ||
| 672 | |||
| 673 | case EVIOCSKEYCODE: | ||
| 674 | return evdev_handle_set_keycode(dev, p); | ||
| 675 | |||
| 676 | case EVIOCGKEYCODE_V2: | ||
| 677 | return evdev_handle_get_keycode_v2(dev, p); | ||
| 678 | |||
| 679 | case EVIOCSKEYCODE_V2: | ||
| 680 | return evdev_handle_set_keycode_v2(dev, p); | ||
| 672 | } | 681 | } |
| 673 | 682 | ||
| 674 | size = _IOC_SIZE(cmd); | 683 | size = _IOC_SIZE(cmd); |
| @@ -708,12 +717,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
| 708 | return -EFAULT; | 717 | return -EFAULT; |
| 709 | 718 | ||
| 710 | return error; | 719 | return error; |
| 711 | |||
| 712 | case EVIOC_MASK_SIZE(EVIOCGKEYCODE): | ||
| 713 | return evdev_handle_get_keycode(dev, p, size); | ||
| 714 | |||
| 715 | case EVIOC_MASK_SIZE(EVIOCSKEYCODE): | ||
| 716 | return evdev_handle_set_keycode(dev, p, size); | ||
| 717 | } | 720 | } |
| 718 | 721 | ||
| 719 | /* Multi-number variable-length handlers */ | 722 | /* Multi-number variable-length handlers */ |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 4852b440960..435b0af401e 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
| @@ -1436,6 +1436,8 @@ static struct wacom_features wacom_features_0xD2 = | |||
| 1436 | { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | 1436 | { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; |
| 1437 | static struct wacom_features wacom_features_0xD3 = | 1437 | static struct wacom_features wacom_features_0xD3 = |
| 1438 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | 1438 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; |
| 1439 | static const struct wacom_features wacom_features_0xD4 = | ||
| 1440 | { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 255, 63, BAMBOO_PT }; | ||
| 1439 | static struct wacom_features wacom_features_0xD8 = | 1441 | static struct wacom_features wacom_features_0xD8 = |
| 1440 | { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | 1442 | { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; |
| 1441 | static struct wacom_features wacom_features_0xDA = | 1443 | static struct wacom_features wacom_features_0xDA = |
| @@ -1510,6 +1512,7 @@ const struct usb_device_id wacom_ids[] = { | |||
| 1510 | { USB_DEVICE_WACOM(0xD1) }, | 1512 | { USB_DEVICE_WACOM(0xD1) }, |
| 1511 | { USB_DEVICE_WACOM(0xD2) }, | 1513 | { USB_DEVICE_WACOM(0xD2) }, |
| 1512 | { USB_DEVICE_WACOM(0xD3) }, | 1514 | { USB_DEVICE_WACOM(0xD3) }, |
| 1515 | { USB_DEVICE_WACOM(0xD4) }, | ||
| 1513 | { USB_DEVICE_WACOM(0xD8) }, | 1516 | { USB_DEVICE_WACOM(0xD8) }, |
| 1514 | { USB_DEVICE_WACOM(0xDA) }, | 1517 | { USB_DEVICE_WACOM(0xDA) }, |
| 1515 | { USB_DEVICE_WACOM(0xDB) }, | 1518 | { USB_DEVICE_WACOM(0xDB) }, |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 84c46a16192..e71c5fa527f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -371,10 +371,15 @@ static void md_end_flush(struct bio *bio, int err) | |||
| 371 | bio_put(bio); | 371 | bio_put(bio); |
| 372 | } | 372 | } |
| 373 | 373 | ||
| 374 | static void submit_flushes(mddev_t *mddev) | 374 | static void md_submit_flush_data(struct work_struct *ws); |
| 375 | |||
| 376 | static void submit_flushes(struct work_struct *ws) | ||
| 375 | { | 377 | { |
| 378 | mddev_t *mddev = container_of(ws, mddev_t, flush_work); | ||
| 376 | mdk_rdev_t *rdev; | 379 | mdk_rdev_t *rdev; |
| 377 | 380 | ||
| 381 | INIT_WORK(&mddev->flush_work, md_submit_flush_data); | ||
| 382 | atomic_set(&mddev->flush_pending, 1); | ||
| 378 | rcu_read_lock(); | 383 | rcu_read_lock(); |
| 379 | list_for_each_entry_rcu(rdev, &mddev->disks, same_set) | 384 | list_for_each_entry_rcu(rdev, &mddev->disks, same_set) |
| 380 | if (rdev->raid_disk >= 0 && | 385 | if (rdev->raid_disk >= 0 && |
| @@ -397,6 +402,8 @@ static void submit_flushes(mddev_t *mddev) | |||
| 397 | rdev_dec_pending(rdev, mddev); | 402 | rdev_dec_pending(rdev, mddev); |
| 398 | } | 403 | } |
| 399 | rcu_read_unlock(); | 404 | rcu_read_unlock(); |
| 405 | if (atomic_dec_and_test(&mddev->flush_pending)) | ||
| 406 | queue_work(md_wq, &mddev->flush_work); | ||
| 400 | } | 407 | } |
| 401 | 408 | ||
| 402 | static void md_submit_flush_data(struct work_struct *ws) | 409 | static void md_submit_flush_data(struct work_struct *ws) |
| @@ -404,8 +411,6 @@ static void md_submit_flush_data(struct work_struct *ws) | |||
| 404 | mddev_t *mddev = container_of(ws, mddev_t, flush_work); | 411 | mddev_t *mddev = container_of(ws, mddev_t, flush_work); |
| 405 | struct bio *bio = mddev->flush_bio; | 412 | struct bio *bio = mddev->flush_bio; |
| 406 | 413 | ||
| 407 | atomic_set(&mddev->flush_pending, 1); | ||
| 408 | |||
| 409 | if (bio->bi_size == 0) | 414 | if (bio->bi_size == 0) |
| 410 | /* an empty barrier - all done */ | 415 | /* an empty barrier - all done */ |
| 411 | bio_endio(bio, 0); | 416 | bio_endio(bio, 0); |
| @@ -414,10 +419,9 @@ static void md_submit_flush_data(struct work_struct *ws) | |||
| 414 | if (mddev->pers->make_request(mddev, bio)) | 419 | if (mddev->pers->make_request(mddev, bio)) |
| 415 | generic_make_request(bio); | 420 | generic_make_request(bio); |
| 416 | } | 421 | } |
| 417 | if (atomic_dec_and_test(&mddev->flush_pending)) { | 422 | |
| 418 | mddev->flush_bio = NULL; | 423 | mddev->flush_bio = NULL; |
| 419 | wake_up(&mddev->sb_wait); | 424 | wake_up(&mddev->sb_wait); |
| 420 | } | ||
| 421 | } | 425 | } |
| 422 | 426 | ||
| 423 | void md_flush_request(mddev_t *mddev, struct bio *bio) | 427 | void md_flush_request(mddev_t *mddev, struct bio *bio) |
| @@ -429,13 +433,8 @@ void md_flush_request(mddev_t *mddev, struct bio *bio) | |||
| 429 | mddev->flush_bio = bio; | 433 | mddev->flush_bio = bio; |
| 430 | spin_unlock_irq(&mddev->write_lock); | 434 | spin_unlock_irq(&mddev->write_lock); |
| 431 | 435 | ||
| 432 | atomic_set(&mddev->flush_pending, 1); | 436 | INIT_WORK(&mddev->flush_work, submit_flushes); |
| 433 | INIT_WORK(&mddev->flush_work, md_submit_flush_data); | 437 | queue_work(md_wq, &mddev->flush_work); |
| 434 | |||
| 435 | submit_flushes(mddev); | ||
| 436 | |||
| 437 | if (atomic_dec_and_test(&mddev->flush_pending)) | ||
| 438 | queue_work(md_wq, &mddev->flush_work); | ||
| 439 | } | 438 | } |
| 440 | EXPORT_SYMBOL(md_flush_request); | 439 | EXPORT_SYMBOL(md_flush_request); |
| 441 | 440 | ||
| @@ -5160,7 +5159,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
| 5160 | PTR_ERR(rdev)); | 5159 | PTR_ERR(rdev)); |
| 5161 | return PTR_ERR(rdev); | 5160 | return PTR_ERR(rdev); |
| 5162 | } | 5161 | } |
| 5163 | /* set save_raid_disk if appropriate */ | 5162 | /* set saved_raid_disk if appropriate */ |
| 5164 | if (!mddev->persistent) { | 5163 | if (!mddev->persistent) { |
| 5165 | if (info->state & (1<<MD_DISK_SYNC) && | 5164 | if (info->state & (1<<MD_DISK_SYNC) && |
| 5166 | info->raid_disk < mddev->raid_disks) | 5165 | info->raid_disk < mddev->raid_disks) |
| @@ -5170,7 +5169,10 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
| 5170 | } else | 5169 | } else |
| 5171 | super_types[mddev->major_version]. | 5170 | super_types[mddev->major_version]. |
| 5172 | validate_super(mddev, rdev); | 5171 | validate_super(mddev, rdev); |
| 5173 | rdev->saved_raid_disk = rdev->raid_disk; | 5172 | if (test_bit(In_sync, &rdev->flags)) |
| 5173 | rdev->saved_raid_disk = rdev->raid_disk; | ||
| 5174 | else | ||
| 5175 | rdev->saved_raid_disk = -1; | ||
| 5174 | 5176 | ||
| 5175 | clear_bit(In_sync, &rdev->flags); /* just to be sure */ | 5177 | clear_bit(In_sync, &rdev->flags); /* just to be sure */ |
| 5176 | if (info->state & (1<<MD_DISK_WRITEMOSTLY)) | 5178 | if (info->state & (1<<MD_DISK_WRITEMOSTLY)) |
| @@ -6042,9 +6044,8 @@ static int md_thread(void * arg) | |||
| 6042 | || kthread_should_stop(), | 6044 | || kthread_should_stop(), |
| 6043 | thread->timeout); | 6045 | thread->timeout); |
| 6044 | 6046 | ||
| 6045 | clear_bit(THREAD_WAKEUP, &thread->flags); | 6047 | if (test_and_clear_bit(THREAD_WAKEUP, &thread->flags)) |
| 6046 | 6048 | thread->run(thread->mddev); | |
| 6047 | thread->run(thread->mddev); | ||
| 6048 | } | 6049 | } |
| 6049 | 6050 | ||
| 6050 | return 0; | 6051 | return 0; |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index c67aa54694a..0641674827f 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -2397,13 +2397,13 @@ static int run(mddev_t *mddev) | |||
| 2397 | return 0; | 2397 | return 0; |
| 2398 | 2398 | ||
| 2399 | out_free_conf: | 2399 | out_free_conf: |
| 2400 | md_unregister_thread(mddev->thread); | ||
| 2400 | if (conf->r10bio_pool) | 2401 | if (conf->r10bio_pool) |
| 2401 | mempool_destroy(conf->r10bio_pool); | 2402 | mempool_destroy(conf->r10bio_pool); |
| 2402 | safe_put_page(conf->tmppage); | 2403 | safe_put_page(conf->tmppage); |
| 2403 | kfree(conf->mirrors); | 2404 | kfree(conf->mirrors); |
| 2404 | kfree(conf); | 2405 | kfree(conf); |
| 2405 | mddev->private = NULL; | 2406 | mddev->private = NULL; |
| 2406 | md_unregister_thread(mddev->thread); | ||
| 2407 | out: | 2407 | out: |
| 2408 | return -EIO; | 2408 | return -EIO; |
| 2409 | } | 2409 | } |
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 5bf4985daed..05e832f61c3 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c | |||
| @@ -361,7 +361,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 361 | 361 | ||
| 362 | static const struct v4l2_file_operations rtrack_fops = { | 362 | static const struct v4l2_file_operations rtrack_fops = { |
| 363 | .owner = THIS_MODULE, | 363 | .owner = THIS_MODULE, |
| 364 | .ioctl = video_ioctl2, | 364 | .unlocked_ioctl = video_ioctl2, |
| 365 | }; | 365 | }; |
| 366 | 366 | ||
| 367 | static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { | 367 | static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { |
| @@ -412,13 +412,6 @@ static int __init rtrack_init(void) | |||
| 412 | rt->vdev.release = video_device_release_empty; | 412 | rt->vdev.release = video_device_release_empty; |
| 413 | video_set_drvdata(&rt->vdev, rt); | 413 | video_set_drvdata(&rt->vdev, rt); |
| 414 | 414 | ||
| 415 | if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 416 | v4l2_device_unregister(&rt->v4l2_dev); | ||
| 417 | release_region(rt->io, 2); | ||
| 418 | return -EINVAL; | ||
| 419 | } | ||
| 420 | v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n"); | ||
| 421 | |||
| 422 | /* Set up the I/O locking */ | 415 | /* Set up the I/O locking */ |
| 423 | 416 | ||
| 424 | mutex_init(&rt->lock); | 417 | mutex_init(&rt->lock); |
| @@ -430,6 +423,13 @@ static int __init rtrack_init(void) | |||
| 430 | sleep_delay(2000000); /* make sure it's totally down */ | 423 | sleep_delay(2000000); /* make sure it's totally down */ |
| 431 | outb(0xc0, rt->io); /* steady volume, mute card */ | 424 | outb(0xc0, rt->io); /* steady volume, mute card */ |
| 432 | 425 | ||
| 426 | if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 427 | v4l2_device_unregister(&rt->v4l2_dev); | ||
| 428 | release_region(rt->io, 2); | ||
| 429 | return -EINVAL; | ||
| 430 | } | ||
| 431 | v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n"); | ||
| 432 | |||
| 433 | return 0; | 433 | return 0; |
| 434 | } | 434 | } |
| 435 | 435 | ||
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index c2231139362..dd8a6ab0d43 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c | |||
| @@ -324,7 +324,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
| 324 | 324 | ||
| 325 | static const struct v4l2_file_operations aztech_fops = { | 325 | static const struct v4l2_file_operations aztech_fops = { |
| 326 | .owner = THIS_MODULE, | 326 | .owner = THIS_MODULE, |
| 327 | .ioctl = video_ioctl2, | 327 | .unlocked_ioctl = video_ioctl2, |
| 328 | }; | 328 | }; |
| 329 | 329 | ||
| 330 | static const struct v4l2_ioctl_ops aztech_ioctl_ops = { | 330 | static const struct v4l2_ioctl_ops aztech_ioctl_ops = { |
| @@ -375,6 +375,8 @@ static int __init aztech_init(void) | |||
| 375 | az->vdev.ioctl_ops = &aztech_ioctl_ops; | 375 | az->vdev.ioctl_ops = &aztech_ioctl_ops; |
| 376 | az->vdev.release = video_device_release_empty; | 376 | az->vdev.release = video_device_release_empty; |
| 377 | video_set_drvdata(&az->vdev, az); | 377 | video_set_drvdata(&az->vdev, az); |
| 378 | /* mute card - prevents noisy bootups */ | ||
| 379 | outb(0, az->io); | ||
| 378 | 380 | ||
| 379 | if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 381 | if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 380 | v4l2_device_unregister(v4l2_dev); | 382 | v4l2_device_unregister(v4l2_dev); |
| @@ -383,8 +385,6 @@ static int __init aztech_init(void) | |||
| 383 | } | 385 | } |
| 384 | 386 | ||
| 385 | v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); | 387 | v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); |
| 386 | /* mute card - prevents noisy bootups */ | ||
| 387 | outb(0, az->io); | ||
| 388 | return 0; | 388 | return 0; |
| 389 | } | 389 | } |
| 390 | 390 | ||
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index b701ea6e7c7..bc9ad0897c5 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c | |||
| @@ -328,11 +328,10 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo | |||
| 328 | unsigned char readbuf[RDS_BUFFER]; | 328 | unsigned char readbuf[RDS_BUFFER]; |
| 329 | int i = 0; | 329 | int i = 0; |
| 330 | 330 | ||
| 331 | mutex_lock(&dev->lock); | ||
| 331 | if (dev->rdsstat == 0) { | 332 | if (dev->rdsstat == 0) { |
| 332 | mutex_lock(&dev->lock); | ||
| 333 | dev->rdsstat = 1; | 333 | dev->rdsstat = 1; |
| 334 | outb(0x80, dev->io); /* Select RDS fifo */ | 334 | outb(0x80, dev->io); /* Select RDS fifo */ |
| 335 | mutex_unlock(&dev->lock); | ||
| 336 | init_timer(&dev->readtimer); | 335 | init_timer(&dev->readtimer); |
| 337 | dev->readtimer.function = cadet_handler; | 336 | dev->readtimer.function = cadet_handler; |
| 338 | dev->readtimer.data = (unsigned long)dev; | 337 | dev->readtimer.data = (unsigned long)dev; |
| @@ -340,12 +339,15 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo | |||
| 340 | add_timer(&dev->readtimer); | 339 | add_timer(&dev->readtimer); |
| 341 | } | 340 | } |
| 342 | if (dev->rdsin == dev->rdsout) { | 341 | if (dev->rdsin == dev->rdsout) { |
| 342 | mutex_unlock(&dev->lock); | ||
| 343 | if (file->f_flags & O_NONBLOCK) | 343 | if (file->f_flags & O_NONBLOCK) |
| 344 | return -EWOULDBLOCK; | 344 | return -EWOULDBLOCK; |
| 345 | interruptible_sleep_on(&dev->read_queue); | 345 | interruptible_sleep_on(&dev->read_queue); |
| 346 | mutex_lock(&dev->lock); | ||
| 346 | } | 347 | } |
| 347 | while (i < count && dev->rdsin != dev->rdsout) | 348 | while (i < count && dev->rdsin != dev->rdsout) |
| 348 | readbuf[i++] = dev->rdsbuf[dev->rdsout++]; | 349 | readbuf[i++] = dev->rdsbuf[dev->rdsout++]; |
| 350 | mutex_unlock(&dev->lock); | ||
| 349 | 351 | ||
| 350 | if (copy_to_user(data, readbuf, i)) | 352 | if (copy_to_user(data, readbuf, i)) |
| 351 | return -EFAULT; | 353 | return -EFAULT; |
| @@ -525,9 +527,11 @@ static int cadet_open(struct file *file) | |||
| 525 | { | 527 | { |
| 526 | struct cadet *dev = video_drvdata(file); | 528 | struct cadet *dev = video_drvdata(file); |
| 527 | 529 | ||
| 530 | mutex_lock(&dev->lock); | ||
| 528 | dev->users++; | 531 | dev->users++; |
| 529 | if (1 == dev->users) | 532 | if (1 == dev->users) |
| 530 | init_waitqueue_head(&dev->read_queue); | 533 | init_waitqueue_head(&dev->read_queue); |
| 534 | mutex_unlock(&dev->lock); | ||
| 531 | return 0; | 535 | return 0; |
| 532 | } | 536 | } |
| 533 | 537 | ||
| @@ -535,11 +539,13 @@ static int cadet_release(struct file *file) | |||
| 535 | { | 539 | { |
| 536 | struct cadet *dev = video_drvdata(file); | 540 | struct cadet *dev = video_drvdata(file); |
| 537 | 541 | ||
| 542 | mutex_lock(&dev->lock); | ||
| 538 | dev->users--; | 543 | dev->users--; |
| 539 | if (0 == dev->users) { | 544 | if (0 == dev->users) { |
| 540 | del_timer_sync(&dev->readtimer); | 545 | del_timer_sync(&dev->readtimer); |
| 541 | dev->rdsstat = 0; | 546 | dev->rdsstat = 0; |
| 542 | } | 547 | } |
| 548 | mutex_unlock(&dev->lock); | ||
| 543 | return 0; | 549 | return 0; |
| 544 | } | 550 | } |
| 545 | 551 | ||
| @@ -559,7 +565,7 @@ static const struct v4l2_file_operations cadet_fops = { | |||
| 559 | .open = cadet_open, | 565 | .open = cadet_open, |
| 560 | .release = cadet_release, | 566 | .release = cadet_release, |
| 561 | .read = cadet_read, | 567 | .read = cadet_read, |
| 562 | .ioctl = video_ioctl2, | 568 | .unlocked_ioctl = video_ioctl2, |
| 563 | .poll = cadet_poll, | 569 | .poll = cadet_poll, |
| 564 | }; | 570 | }; |
| 565 | 571 | ||
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index 79039674a0e..28fa85ba208 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c | |||
| @@ -361,7 +361,7 @@ MODULE_DEVICE_TABLE(pci, gemtek_pci_id); | |||
| 361 | 361 | ||
| 362 | static const struct v4l2_file_operations gemtek_pci_fops = { | 362 | static const struct v4l2_file_operations gemtek_pci_fops = { |
| 363 | .owner = THIS_MODULE, | 363 | .owner = THIS_MODULE, |
| 364 | .ioctl = video_ioctl2, | 364 | .unlocked_ioctl = video_ioctl2, |
| 365 | }; | 365 | }; |
| 366 | 366 | ||
| 367 | static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { | 367 | static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { |
| @@ -422,11 +422,11 @@ static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_dev | |||
| 422 | card->vdev.release = video_device_release_empty; | 422 | card->vdev.release = video_device_release_empty; |
| 423 | video_set_drvdata(&card->vdev, card); | 423 | video_set_drvdata(&card->vdev, card); |
| 424 | 424 | ||
| 425 | gemtek_pci_mute(card); | ||
| 426 | |||
| 425 | if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0) | 427 | if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0) |
| 426 | goto err_video; | 428 | goto err_video; |
| 427 | 429 | ||
| 428 | gemtek_pci_mute(card); | ||
| 429 | |||
| 430 | v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", | 430 | v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", |
| 431 | pdev->revision, card->iobase, card->iobase + card->length - 1); | 431 | pdev->revision, card->iobase, card->iobase + card->length - 1); |
| 432 | 432 | ||
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index 73985f641f0..259936422e4 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c | |||
| @@ -378,7 +378,7 @@ static int gemtek_probe(struct gemtek *gt) | |||
| 378 | 378 | ||
| 379 | static const struct v4l2_file_operations gemtek_fops = { | 379 | static const struct v4l2_file_operations gemtek_fops = { |
| 380 | .owner = THIS_MODULE, | 380 | .owner = THIS_MODULE, |
| 381 | .ioctl = video_ioctl2, | 381 | .unlocked_ioctl = video_ioctl2, |
| 382 | }; | 382 | }; |
| 383 | 383 | ||
| 384 | static int vidioc_querycap(struct file *file, void *priv, | 384 | static int vidioc_querycap(struct file *file, void *priv, |
| @@ -577,12 +577,6 @@ static int __init gemtek_init(void) | |||
| 577 | gt->vdev.release = video_device_release_empty; | 577 | gt->vdev.release = video_device_release_empty; |
| 578 | video_set_drvdata(>->vdev, gt); | 578 | video_set_drvdata(>->vdev, gt); |
| 579 | 579 | ||
| 580 | if (video_register_device(>->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 581 | v4l2_device_unregister(v4l2_dev); | ||
| 582 | release_region(gt->io, 1); | ||
| 583 | return -EBUSY; | ||
| 584 | } | ||
| 585 | |||
| 586 | /* Set defaults */ | 580 | /* Set defaults */ |
| 587 | gt->lastfreq = GEMTEK_LOWFREQ; | 581 | gt->lastfreq = GEMTEK_LOWFREQ; |
| 588 | gt->bu2614data = 0; | 582 | gt->bu2614data = 0; |
| @@ -590,6 +584,12 @@ static int __init gemtek_init(void) | |||
| 590 | if (initmute) | 584 | if (initmute) |
| 591 | gemtek_mute(gt); | 585 | gemtek_mute(gt); |
| 592 | 586 | ||
| 587 | if (video_register_device(>->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 588 | v4l2_device_unregister(v4l2_dev); | ||
| 589 | release_region(gt->io, 1); | ||
| 590 | return -EBUSY; | ||
| 591 | } | ||
| 592 | |||
| 593 | return 0; | 593 | return 0; |
| 594 | } | 594 | } |
| 595 | 595 | ||
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index 08f1051979c..6af61bfeb17 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c | |||
| @@ -299,7 +299,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 299 | 299 | ||
| 300 | static const struct v4l2_file_operations maestro_fops = { | 300 | static const struct v4l2_file_operations maestro_fops = { |
| 301 | .owner = THIS_MODULE, | 301 | .owner = THIS_MODULE, |
| 302 | .ioctl = video_ioctl2, | 302 | .unlocked_ioctl = video_ioctl2, |
| 303 | }; | 303 | }; |
| 304 | 304 | ||
| 305 | static const struct v4l2_ioctl_ops maestro_ioctl_ops = { | 305 | static const struct v4l2_ioctl_ops maestro_ioctl_ops = { |
| @@ -383,22 +383,20 @@ static int __devinit maestro_probe(struct pci_dev *pdev, | |||
| 383 | dev->vdev.release = video_device_release_empty; | 383 | dev->vdev.release = video_device_release_empty; |
| 384 | video_set_drvdata(&dev->vdev, dev); | 384 | video_set_drvdata(&dev->vdev, dev); |
| 385 | 385 | ||
| 386 | if (!radio_power_on(dev)) { | ||
| 387 | retval = -EIO; | ||
| 388 | goto errfr1; | ||
| 389 | } | ||
| 390 | |||
| 386 | retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr); | 391 | retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr); |
| 387 | if (retval) { | 392 | if (retval) { |
| 388 | v4l2_err(v4l2_dev, "can't register video device!\n"); | 393 | v4l2_err(v4l2_dev, "can't register video device!\n"); |
| 389 | goto errfr1; | 394 | goto errfr1; |
| 390 | } | 395 | } |
| 391 | 396 | ||
| 392 | if (!radio_power_on(dev)) { | ||
| 393 | retval = -EIO; | ||
| 394 | goto errunr; | ||
| 395 | } | ||
| 396 | |||
| 397 | v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n"); | 397 | v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n"); |
| 398 | 398 | ||
| 399 | return 0; | 399 | return 0; |
| 400 | errunr: | ||
| 401 | video_unregister_device(&dev->vdev); | ||
| 402 | errfr1: | 400 | errfr1: |
| 403 | v4l2_device_unregister(v4l2_dev); | 401 | v4l2_device_unregister(v4l2_dev); |
| 404 | errfr: | 402 | errfr: |
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 255d40df4b4..6459a220b0d 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c | |||
| @@ -346,7 +346,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
| 346 | 346 | ||
| 347 | static const struct v4l2_file_operations maxiradio_fops = { | 347 | static const struct v4l2_file_operations maxiradio_fops = { |
| 348 | .owner = THIS_MODULE, | 348 | .owner = THIS_MODULE, |
| 349 | .ioctl = video_ioctl2, | 349 | .unlocked_ioctl = video_ioctl2, |
| 350 | }; | 350 | }; |
| 351 | 351 | ||
| 352 | static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { | 352 | static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c index 4ff885445fd..3fb76e3834c 100644 --- a/drivers/media/radio/radio-miropcm20.c +++ b/drivers/media/radio/radio-miropcm20.c | |||
| @@ -33,6 +33,7 @@ struct pcm20 { | |||
| 33 | unsigned long freq; | 33 | unsigned long freq; |
| 34 | int muted; | 34 | int muted; |
| 35 | struct snd_miro_aci *aci; | 35 | struct snd_miro_aci *aci; |
| 36 | struct mutex lock; | ||
| 36 | }; | 37 | }; |
| 37 | 38 | ||
| 38 | static struct pcm20 pcm20_card = { | 39 | static struct pcm20 pcm20_card = { |
| @@ -72,7 +73,7 @@ static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq) | |||
| 72 | 73 | ||
| 73 | static const struct v4l2_file_operations pcm20_fops = { | 74 | static const struct v4l2_file_operations pcm20_fops = { |
| 74 | .owner = THIS_MODULE, | 75 | .owner = THIS_MODULE, |
| 75 | .ioctl = video_ioctl2, | 76 | .unlocked_ioctl = video_ioctl2, |
| 76 | }; | 77 | }; |
| 77 | 78 | ||
| 78 | static int vidioc_querycap(struct file *file, void *priv, | 79 | static int vidioc_querycap(struct file *file, void *priv, |
| @@ -229,7 +230,7 @@ static int __init pcm20_init(void) | |||
| 229 | return -ENODEV; | 230 | return -ENODEV; |
| 230 | } | 231 | } |
| 231 | strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name)); | 232 | strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name)); |
| 232 | 233 | mutex_init(&dev->lock); | |
| 233 | 234 | ||
| 234 | res = v4l2_device_register(NULL, v4l2_dev); | 235 | res = v4l2_device_register(NULL, v4l2_dev); |
| 235 | if (res < 0) { | 236 | if (res < 0) { |
| @@ -242,6 +243,7 @@ static int __init pcm20_init(void) | |||
| 242 | dev->vdev.fops = &pcm20_fops; | 243 | dev->vdev.fops = &pcm20_fops; |
| 243 | dev->vdev.ioctl_ops = &pcm20_ioctl_ops; | 244 | dev->vdev.ioctl_ops = &pcm20_ioctl_ops; |
| 244 | dev->vdev.release = video_device_release_empty; | 245 | dev->vdev.release = video_device_release_empty; |
| 246 | dev->vdev.lock = &dev->lock; | ||
| 245 | video_set_drvdata(&dev->vdev, dev); | 247 | video_set_drvdata(&dev->vdev, dev); |
| 246 | 248 | ||
| 247 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) | 249 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) |
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index a79296aac9a..8d6ea591bd1 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c | |||
| @@ -266,7 +266,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 266 | 266 | ||
| 267 | static const struct v4l2_file_operations rtrack2_fops = { | 267 | static const struct v4l2_file_operations rtrack2_fops = { |
| 268 | .owner = THIS_MODULE, | 268 | .owner = THIS_MODULE, |
| 269 | .ioctl = video_ioctl2, | 269 | .unlocked_ioctl = video_ioctl2, |
| 270 | }; | 270 | }; |
| 271 | 271 | ||
| 272 | static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { | 272 | static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { |
| @@ -315,6 +315,10 @@ static int __init rtrack2_init(void) | |||
| 315 | dev->vdev.release = video_device_release_empty; | 315 | dev->vdev.release = video_device_release_empty; |
| 316 | video_set_drvdata(&dev->vdev, dev); | 316 | video_set_drvdata(&dev->vdev, dev); |
| 317 | 317 | ||
| 318 | /* mute card - prevents noisy bootups */ | ||
| 319 | outb(1, dev->io); | ||
| 320 | dev->muted = 1; | ||
| 321 | |||
| 318 | mutex_init(&dev->lock); | 322 | mutex_init(&dev->lock); |
| 319 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 323 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 320 | v4l2_device_unregister(v4l2_dev); | 324 | v4l2_device_unregister(v4l2_dev); |
| @@ -324,10 +328,6 @@ static int __init rtrack2_init(void) | |||
| 324 | 328 | ||
| 325 | v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n"); | 329 | v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n"); |
| 326 | 330 | ||
| 327 | /* mute card - prevents noisy bootups */ | ||
| 328 | outb(1, dev->io); | ||
| 329 | dev->muted = 1; | ||
| 330 | |||
| 331 | return 0; | 331 | return 0; |
| 332 | } | 332 | } |
| 333 | 333 | ||
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 985359d18aa..b5a5f89e238 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c | |||
| @@ -260,7 +260,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 260 | 260 | ||
| 261 | static const struct v4l2_file_operations fmi_fops = { | 261 | static const struct v4l2_file_operations fmi_fops = { |
| 262 | .owner = THIS_MODULE, | 262 | .owner = THIS_MODULE, |
| 263 | .ioctl = video_ioctl2, | 263 | .unlocked_ioctl = video_ioctl2, |
| 264 | }; | 264 | }; |
| 265 | 265 | ||
| 266 | static const struct v4l2_ioctl_ops fmi_ioctl_ops = { | 266 | static const struct v4l2_ioctl_ops fmi_ioctl_ops = { |
| @@ -382,6 +382,9 @@ static int __init fmi_init(void) | |||
| 382 | 382 | ||
| 383 | mutex_init(&fmi->lock); | 383 | mutex_init(&fmi->lock); |
| 384 | 384 | ||
| 385 | /* mute card - prevents noisy bootups */ | ||
| 386 | fmi_mute(fmi); | ||
| 387 | |||
| 385 | if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 388 | if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 386 | v4l2_device_unregister(v4l2_dev); | 389 | v4l2_device_unregister(v4l2_dev); |
| 387 | release_region(fmi->io, 2); | 390 | release_region(fmi->io, 2); |
| @@ -391,8 +394,6 @@ static int __init fmi_init(void) | |||
| 391 | } | 394 | } |
| 392 | 395 | ||
| 393 | v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io); | 396 | v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io); |
| 394 | /* mute card - prevents noisy bootups */ | ||
| 395 | fmi_mute(fmi); | ||
| 396 | return 0; | 397 | return 0; |
| 397 | } | 398 | } |
| 398 | 399 | ||
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index 52c7bbb32b8..dc3f04c52d5 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c | |||
| @@ -376,7 +376,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 376 | 376 | ||
| 377 | static const struct v4l2_file_operations fmr2_fops = { | 377 | static const struct v4l2_file_operations fmr2_fops = { |
| 378 | .owner = THIS_MODULE, | 378 | .owner = THIS_MODULE, |
| 379 | .ioctl = video_ioctl2, | 379 | .unlocked_ioctl = video_ioctl2, |
| 380 | }; | 380 | }; |
| 381 | 381 | ||
| 382 | static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { | 382 | static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { |
| @@ -424,6 +424,10 @@ static int __init fmr2_init(void) | |||
| 424 | fmr2->vdev.release = video_device_release_empty; | 424 | fmr2->vdev.release = video_device_release_empty; |
| 425 | video_set_drvdata(&fmr2->vdev, fmr2); | 425 | video_set_drvdata(&fmr2->vdev, fmr2); |
| 426 | 426 | ||
| 427 | /* mute card - prevents noisy bootups */ | ||
| 428 | fmr2_mute(fmr2->io); | ||
| 429 | fmr2_product_info(fmr2); | ||
| 430 | |||
| 427 | if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 431 | if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 428 | v4l2_device_unregister(v4l2_dev); | 432 | v4l2_device_unregister(v4l2_dev); |
| 429 | release_region(fmr2->io, 2); | 433 | release_region(fmr2->io, 2); |
| @@ -431,11 +435,6 @@ static int __init fmr2_init(void) | |||
| 431 | } | 435 | } |
| 432 | 436 | ||
| 433 | v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io); | 437 | v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io); |
| 434 | /* mute card - prevents noisy bootups */ | ||
| 435 | mutex_lock(&fmr2->lock); | ||
| 436 | fmr2_mute(fmr2->io); | ||
| 437 | fmr2_product_info(fmr2); | ||
| 438 | mutex_unlock(&fmr2->lock); | ||
| 439 | debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type)); | 438 | debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type)); |
| 440 | return 0; | 439 | return 0; |
| 441 | } | 440 | } |
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c index 03829e6818b..726d367ad8d 100644 --- a/drivers/media/radio/radio-si4713.c +++ b/drivers/media/radio/radio-si4713.c | |||
| @@ -53,7 +53,8 @@ struct radio_si4713_device { | |||
| 53 | /* radio_si4713_fops - file operations interface */ | 53 | /* radio_si4713_fops - file operations interface */ |
| 54 | static const struct v4l2_file_operations radio_si4713_fops = { | 54 | static const struct v4l2_file_operations radio_si4713_fops = { |
| 55 | .owner = THIS_MODULE, | 55 | .owner = THIS_MODULE, |
| 56 | .ioctl = video_ioctl2, | 56 | /* Note: locking is done at the subdev level in the i2c driver. */ |
| 57 | .unlocked_ioctl = video_ioctl2, | ||
| 57 | }; | 58 | }; |
| 58 | 59 | ||
| 59 | /* Video4Linux Interface */ | 60 | /* Video4Linux Interface */ |
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c index 789d2ec66e1..0e71d816c72 100644 --- a/drivers/media/radio/radio-tea5764.c +++ b/drivers/media/radio/radio-tea5764.c | |||
| @@ -142,7 +142,6 @@ struct tea5764_device { | |||
| 142 | struct video_device *videodev; | 142 | struct video_device *videodev; |
| 143 | struct tea5764_regs regs; | 143 | struct tea5764_regs regs; |
| 144 | struct mutex mutex; | 144 | struct mutex mutex; |
| 145 | int users; | ||
| 146 | }; | 145 | }; |
| 147 | 146 | ||
| 148 | /* I2C code related */ | 147 | /* I2C code related */ |
| @@ -458,41 +457,10 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 458 | return 0; | 457 | return 0; |
| 459 | } | 458 | } |
| 460 | 459 | ||
| 461 | static int tea5764_open(struct file *file) | ||
| 462 | { | ||
| 463 | /* Currently we support only one device */ | ||
| 464 | struct tea5764_device *radio = video_drvdata(file); | ||
| 465 | |||
| 466 | mutex_lock(&radio->mutex); | ||
| 467 | /* Only exclusive access */ | ||
| 468 | if (radio->users) { | ||
| 469 | mutex_unlock(&radio->mutex); | ||
| 470 | return -EBUSY; | ||
| 471 | } | ||
| 472 | radio->users++; | ||
| 473 | mutex_unlock(&radio->mutex); | ||
| 474 | file->private_data = radio; | ||
| 475 | return 0; | ||
| 476 | } | ||
| 477 | |||
| 478 | static int tea5764_close(struct file *file) | ||
| 479 | { | ||
| 480 | struct tea5764_device *radio = video_drvdata(file); | ||
| 481 | |||
| 482 | if (!radio) | ||
| 483 | return -ENODEV; | ||
| 484 | mutex_lock(&radio->mutex); | ||
| 485 | radio->users--; | ||
| 486 | mutex_unlock(&radio->mutex); | ||
| 487 | return 0; | ||
| 488 | } | ||
| 489 | |||
| 490 | /* File system interface */ | 460 | /* File system interface */ |
| 491 | static const struct v4l2_file_operations tea5764_fops = { | 461 | static const struct v4l2_file_operations tea5764_fops = { |
| 492 | .owner = THIS_MODULE, | 462 | .owner = THIS_MODULE, |
| 493 | .open = tea5764_open, | 463 | .unlocked_ioctl = video_ioctl2, |
| 494 | .release = tea5764_close, | ||
| 495 | .ioctl = video_ioctl2, | ||
| 496 | }; | 464 | }; |
| 497 | 465 | ||
| 498 | static const struct v4l2_ioctl_ops tea5764_ioctl_ops = { | 466 | static const struct v4l2_ioctl_ops tea5764_ioctl_ops = { |
| @@ -527,7 +495,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client, | |||
| 527 | int ret; | 495 | int ret; |
| 528 | 496 | ||
| 529 | PDEBUG("probe"); | 497 | PDEBUG("probe"); |
| 530 | radio = kmalloc(sizeof(struct tea5764_device), GFP_KERNEL); | 498 | radio = kzalloc(sizeof(struct tea5764_device), GFP_KERNEL); |
| 531 | if (!radio) | 499 | if (!radio) |
| 532 | return -ENOMEM; | 500 | return -ENOMEM; |
| 533 | 501 | ||
| @@ -555,12 +523,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client, | |||
| 555 | 523 | ||
| 556 | i2c_set_clientdata(client, radio); | 524 | i2c_set_clientdata(client, radio); |
| 557 | video_set_drvdata(radio->videodev, radio); | 525 | video_set_drvdata(radio->videodev, radio); |
| 558 | 526 | radio->videodev->lock = &radio->mutex; | |
| 559 | ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); | ||
| 560 | if (ret < 0) { | ||
| 561 | PWARN("Could not register video device!"); | ||
| 562 | goto errrel; | ||
| 563 | } | ||
| 564 | 527 | ||
| 565 | /* initialize and power off the chip */ | 528 | /* initialize and power off the chip */ |
| 566 | tea5764_i2c_read(radio); | 529 | tea5764_i2c_read(radio); |
| @@ -568,6 +531,12 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client, | |||
| 568 | tea5764_mute(radio, 1); | 531 | tea5764_mute(radio, 1); |
| 569 | tea5764_power_down(radio); | 532 | tea5764_power_down(radio); |
| 570 | 533 | ||
| 534 | ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); | ||
| 535 | if (ret < 0) { | ||
| 536 | PWARN("Could not register video device!"); | ||
| 537 | goto errrel; | ||
| 538 | } | ||
| 539 | |||
| 571 | PINFO("registered."); | 540 | PINFO("registered."); |
| 572 | return 0; | 541 | return 0; |
| 573 | errrel: | 542 | errrel: |
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index fc1c860fd43..a3266391705 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c | |||
| @@ -338,7 +338,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 338 | 338 | ||
| 339 | static const struct v4l2_file_operations terratec_fops = { | 339 | static const struct v4l2_file_operations terratec_fops = { |
| 340 | .owner = THIS_MODULE, | 340 | .owner = THIS_MODULE, |
| 341 | .ioctl = video_ioctl2, | 341 | .unlocked_ioctl = video_ioctl2, |
| 342 | }; | 342 | }; |
| 343 | 343 | ||
| 344 | static const struct v4l2_ioctl_ops terratec_ioctl_ops = { | 344 | static const struct v4l2_ioctl_ops terratec_ioctl_ops = { |
| @@ -389,6 +389,9 @@ static int __init terratec_init(void) | |||
| 389 | 389 | ||
| 390 | mutex_init(&tt->lock); | 390 | mutex_init(&tt->lock); |
| 391 | 391 | ||
| 392 | /* mute card - prevents noisy bootups */ | ||
| 393 | tt_write_vol(tt, 0); | ||
| 394 | |||
| 392 | if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 395 | if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 393 | v4l2_device_unregister(&tt->v4l2_dev); | 396 | v4l2_device_unregister(&tt->v4l2_dev); |
| 394 | release_region(tt->io, 2); | 397 | release_region(tt->io, 2); |
| @@ -396,9 +399,6 @@ static int __init terratec_init(void) | |||
| 396 | } | 399 | } |
| 397 | 400 | ||
| 398 | v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n"); | 401 | v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n"); |
| 399 | |||
| 400 | /* mute card - prevents noisy bootups */ | ||
| 401 | tt_write_vol(tt, 0); | ||
| 402 | return 0; | 402 | return 0; |
| 403 | } | 403 | } |
| 404 | 404 | ||
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c index b8bb3ef47df..a185610b376 100644 --- a/drivers/media/radio/radio-timb.c +++ b/drivers/media/radio/radio-timb.c | |||
| @@ -34,6 +34,7 @@ struct timbradio { | |||
| 34 | struct v4l2_subdev *sd_dsp; | 34 | struct v4l2_subdev *sd_dsp; |
| 35 | struct video_device video_dev; | 35 | struct video_device video_dev; |
| 36 | struct v4l2_device v4l2_dev; | 36 | struct v4l2_device v4l2_dev; |
| 37 | struct mutex lock; | ||
| 37 | }; | 38 | }; |
| 38 | 39 | ||
| 39 | 40 | ||
| @@ -142,7 +143,7 @@ static const struct v4l2_ioctl_ops timbradio_ioctl_ops = { | |||
| 142 | 143 | ||
| 143 | static const struct v4l2_file_operations timbradio_fops = { | 144 | static const struct v4l2_file_operations timbradio_fops = { |
| 144 | .owner = THIS_MODULE, | 145 | .owner = THIS_MODULE, |
| 145 | .ioctl = video_ioctl2, | 146 | .unlocked_ioctl = video_ioctl2, |
| 146 | }; | 147 | }; |
| 147 | 148 | ||
| 148 | static int __devinit timbradio_probe(struct platform_device *pdev) | 149 | static int __devinit timbradio_probe(struct platform_device *pdev) |
| @@ -164,6 +165,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev) | |||
| 164 | } | 165 | } |
| 165 | 166 | ||
| 166 | tr->pdata = *pdata; | 167 | tr->pdata = *pdata; |
| 168 | mutex_init(&tr->lock); | ||
| 167 | 169 | ||
| 168 | strlcpy(tr->video_dev.name, "Timberdale Radio", | 170 | strlcpy(tr->video_dev.name, "Timberdale Radio", |
| 169 | sizeof(tr->video_dev.name)); | 171 | sizeof(tr->video_dev.name)); |
| @@ -171,6 +173,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev) | |||
| 171 | tr->video_dev.ioctl_ops = &timbradio_ioctl_ops; | 173 | tr->video_dev.ioctl_ops = &timbradio_ioctl_ops; |
| 172 | tr->video_dev.release = video_device_release_empty; | 174 | tr->video_dev.release = video_device_release_empty; |
| 173 | tr->video_dev.minor = -1; | 175 | tr->video_dev.minor = -1; |
| 176 | tr->video_dev.lock = &tr->lock; | ||
| 174 | 177 | ||
| 175 | strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name)); | 178 | strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name)); |
| 176 | err = v4l2_device_register(NULL, &tr->v4l2_dev); | 179 | err = v4l2_device_register(NULL, &tr->v4l2_dev); |
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index 9d6dcf8af5b..22fa9cc28ab 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c | |||
| @@ -344,7 +344,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 344 | 344 | ||
| 345 | static const struct v4l2_file_operations trust_fops = { | 345 | static const struct v4l2_file_operations trust_fops = { |
| 346 | .owner = THIS_MODULE, | 346 | .owner = THIS_MODULE, |
| 347 | .ioctl = video_ioctl2, | 347 | .unlocked_ioctl = video_ioctl2, |
| 348 | }; | 348 | }; |
| 349 | 349 | ||
| 350 | static const struct v4l2_ioctl_ops trust_ioctl_ops = { | 350 | static const struct v4l2_ioctl_ops trust_ioctl_ops = { |
| @@ -396,14 +396,6 @@ static int __init trust_init(void) | |||
| 396 | tr->vdev.release = video_device_release_empty; | 396 | tr->vdev.release = video_device_release_empty; |
| 397 | video_set_drvdata(&tr->vdev, tr); | 397 | video_set_drvdata(&tr->vdev, tr); |
| 398 | 398 | ||
| 399 | if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 400 | v4l2_device_unregister(v4l2_dev); | ||
| 401 | release_region(tr->io, 2); | ||
| 402 | return -EINVAL; | ||
| 403 | } | ||
| 404 | |||
| 405 | v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n"); | ||
| 406 | |||
| 407 | write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */ | 399 | write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */ |
| 408 | write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */ | 400 | write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */ |
| 409 | write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */ | 401 | write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */ |
| @@ -418,6 +410,14 @@ static int __init trust_init(void) | |||
| 418 | /* mute card - prevents noisy bootups */ | 410 | /* mute card - prevents noisy bootups */ |
| 419 | tr_setmute(tr, 1); | 411 | tr_setmute(tr, 1); |
| 420 | 412 | ||
| 413 | if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 414 | v4l2_device_unregister(v4l2_dev); | ||
| 415 | release_region(tr->io, 2); | ||
| 416 | return -EINVAL; | ||
| 417 | } | ||
| 418 | |||
| 419 | v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n"); | ||
| 420 | |||
| 421 | return 0; | 421 | return 0; |
| 422 | } | 422 | } |
| 423 | 423 | ||
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index b1f630527dc..8dbbf08f220 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c | |||
| @@ -317,7 +317,7 @@ static int vidioc_log_status(struct file *file, void *priv) | |||
| 317 | 317 | ||
| 318 | static const struct v4l2_file_operations typhoon_fops = { | 318 | static const struct v4l2_file_operations typhoon_fops = { |
| 319 | .owner = THIS_MODULE, | 319 | .owner = THIS_MODULE, |
| 320 | .ioctl = video_ioctl2, | 320 | .unlocked_ioctl = video_ioctl2, |
| 321 | }; | 321 | }; |
| 322 | 322 | ||
| 323 | static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { | 323 | static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { |
| @@ -344,18 +344,18 @@ static int __init typhoon_init(void) | |||
| 344 | 344 | ||
| 345 | strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name)); | 345 | strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name)); |
| 346 | dev->io = io; | 346 | dev->io = io; |
| 347 | dev->curfreq = dev->mutefreq = mutefreq; | ||
| 348 | 347 | ||
| 349 | if (dev->io == -1) { | 348 | if (dev->io == -1) { |
| 350 | v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n"); | 349 | v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n"); |
| 351 | return -EINVAL; | 350 | return -EINVAL; |
| 352 | } | 351 | } |
| 353 | 352 | ||
| 354 | if (dev->mutefreq < 87000 || dev->mutefreq > 108500) { | 353 | if (mutefreq < 87000 || mutefreq > 108500) { |
| 355 | v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n"); | 354 | v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n"); |
| 356 | v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n"); | 355 | v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n"); |
| 357 | return -EINVAL; | 356 | return -EINVAL; |
| 358 | } | 357 | } |
| 358 | dev->curfreq = dev->mutefreq = mutefreq << 4; | ||
| 359 | 359 | ||
| 360 | mutex_init(&dev->lock); | 360 | mutex_init(&dev->lock); |
| 361 | if (!request_region(dev->io, 8, "typhoon")) { | 361 | if (!request_region(dev->io, 8, "typhoon")) { |
| @@ -378,17 +378,17 @@ static int __init typhoon_init(void) | |||
| 378 | dev->vdev.ioctl_ops = &typhoon_ioctl_ops; | 378 | dev->vdev.ioctl_ops = &typhoon_ioctl_ops; |
| 379 | dev->vdev.release = video_device_release_empty; | 379 | dev->vdev.release = video_device_release_empty; |
| 380 | video_set_drvdata(&dev->vdev, dev); | 380 | video_set_drvdata(&dev->vdev, dev); |
| 381 | |||
| 382 | /* mute card - prevents noisy bootups */ | ||
| 383 | typhoon_mute(dev); | ||
| 384 | |||
| 381 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 385 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
| 382 | v4l2_device_unregister(&dev->v4l2_dev); | 386 | v4l2_device_unregister(&dev->v4l2_dev); |
| 383 | release_region(dev->io, 8); | 387 | release_region(dev->io, 8); |
| 384 | return -EINVAL; | 388 | return -EINVAL; |
| 385 | } | 389 | } |
| 386 | v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io); | 390 | v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io); |
| 387 | v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", dev->mutefreq); | 391 | v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", mutefreq); |
| 388 | dev->mutefreq <<= 4; | ||
| 389 | |||
| 390 | /* mute card - prevents noisy bootups */ | ||
| 391 | typhoon_mute(dev); | ||
| 392 | 392 | ||
| 393 | return 0; | 393 | return 0; |
| 394 | } | 394 | } |
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index f31eab99c94..af99c5bd88c 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c | |||
| @@ -377,7 +377,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
| 377 | static const struct v4l2_file_operations zoltrix_fops = | 377 | static const struct v4l2_file_operations zoltrix_fops = |
| 378 | { | 378 | { |
| 379 | .owner = THIS_MODULE, | 379 | .owner = THIS_MODULE, |
| 380 | .ioctl = video_ioctl2, | 380 | .unlocked_ioctl = video_ioctl2, |
| 381 | }; | 381 | }; |
| 382 | 382 | ||
| 383 | static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { | 383 | static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { |
| @@ -424,20 +424,6 @@ static int __init zoltrix_init(void) | |||
| 424 | return res; | 424 | return res; |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name)); | ||
| 428 | zol->vdev.v4l2_dev = v4l2_dev; | ||
| 429 | zol->vdev.fops = &zoltrix_fops; | ||
| 430 | zol->vdev.ioctl_ops = &zoltrix_ioctl_ops; | ||
| 431 | zol->vdev.release = video_device_release_empty; | ||
| 432 | video_set_drvdata(&zol->vdev, zol); | ||
| 433 | |||
| 434 | if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 435 | v4l2_device_unregister(v4l2_dev); | ||
| 436 | release_region(zol->io, 2); | ||
| 437 | return -EINVAL; | ||
| 438 | } | ||
| 439 | v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n"); | ||
| 440 | |||
| 441 | mutex_init(&zol->lock); | 427 | mutex_init(&zol->lock); |
| 442 | 428 | ||
| 443 | /* mute card - prevents noisy bootups */ | 429 | /* mute card - prevents noisy bootups */ |
| @@ -452,6 +438,20 @@ static int __init zoltrix_init(void) | |||
| 452 | zol->curvol = 0; | 438 | zol->curvol = 0; |
| 453 | zol->stereo = 1; | 439 | zol->stereo = 1; |
| 454 | 440 | ||
| 441 | strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name)); | ||
| 442 | zol->vdev.v4l2_dev = v4l2_dev; | ||
| 443 | zol->vdev.fops = &zoltrix_fops; | ||
| 444 | zol->vdev.ioctl_ops = &zoltrix_ioctl_ops; | ||
| 445 | zol->vdev.release = video_device_release_empty; | ||
| 446 | video_set_drvdata(&zol->vdev, zol); | ||
| 447 | |||
| 448 | if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
| 449 | v4l2_device_unregister(v4l2_dev); | ||
| 450 | release_region(zol->io, 2); | ||
| 451 | return -EINVAL; | ||
| 452 | } | ||
| 453 | v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n"); | ||
| 454 | |||
| 455 | return 0; | 455 | return 0; |
| 456 | } | 456 | } |
| 457 | 457 | ||
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index 31e7a123d19..f989f2820d8 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c | |||
| @@ -712,7 +712,7 @@ static int ar_initialize(struct ar *ar) | |||
| 712 | static const struct v4l2_file_operations ar_fops = { | 712 | static const struct v4l2_file_operations ar_fops = { |
| 713 | .owner = THIS_MODULE, | 713 | .owner = THIS_MODULE, |
| 714 | .read = ar_read, | 714 | .read = ar_read, |
| 715 | .ioctl = video_ioctl2, | 715 | .unlocked_ioctl = video_ioctl2, |
| 716 | }; | 716 | }; |
| 717 | 717 | ||
| 718 | static const struct v4l2_ioctl_ops ar_ioctl_ops = { | 718 | static const struct v4l2_ioctl_ops ar_ioctl_ops = { |
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 935e0c9a967..c1193506131 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c | |||
| @@ -860,7 +860,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf, | |||
| 860 | 860 | ||
| 861 | static const struct v4l2_file_operations qcam_fops = { | 861 | static const struct v4l2_file_operations qcam_fops = { |
| 862 | .owner = THIS_MODULE, | 862 | .owner = THIS_MODULE, |
| 863 | .ioctl = video_ioctl2, | 863 | .unlocked_ioctl = video_ioctl2, |
| 864 | .read = qcam_read, | 864 | .read = qcam_read, |
| 865 | }; | 865 | }; |
| 866 | 866 | ||
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 6e4b19698c1..24fc00965a1 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c | |||
| @@ -718,7 +718,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf, | |||
| 718 | 718 | ||
| 719 | static const struct v4l2_file_operations qcam_fops = { | 719 | static const struct v4l2_file_operations qcam_fops = { |
| 720 | .owner = THIS_MODULE, | 720 | .owner = THIS_MODULE, |
| 721 | .ioctl = video_ioctl2, | 721 | .unlocked_ioctl = video_ioctl2, |
| 722 | .read = qcam_read, | 722 | .read = qcam_read, |
| 723 | }; | 723 | }; |
| 724 | 724 | ||
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 260c666ce93..0dfff50891e 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c | |||
| @@ -1775,7 +1775,7 @@ static const struct v4l2_file_operations cafe_v4l_fops = { | |||
| 1775 | .read = cafe_v4l_read, | 1775 | .read = cafe_v4l_read, |
| 1776 | .poll = cafe_v4l_poll, | 1776 | .poll = cafe_v4l_poll, |
| 1777 | .mmap = cafe_v4l_mmap, | 1777 | .mmap = cafe_v4l_mmap, |
| 1778 | .ioctl = video_ioctl2, | 1778 | .unlocked_ioctl = video_ioctl2, |
| 1779 | }; | 1779 | }; |
| 1780 | 1780 | ||
| 1781 | static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { | 1781 | static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { |
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.c b/drivers/media/video/cx18/cx18-alsa-pcm.c index 8f55692db36..82d195be919 100644 --- a/drivers/media/video/cx18/cx18-alsa-pcm.c +++ b/drivers/media/video/cx18/cx18-alsa-pcm.c | |||
| @@ -218,7 +218,13 @@ static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream) | |||
| 218 | static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream, | 218 | static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream, |
| 219 | unsigned int cmd, void *arg) | 219 | unsigned int cmd, void *arg) |
| 220 | { | 220 | { |
| 221 | return snd_pcm_lib_ioctl(substream, cmd, arg); | 221 | struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); |
| 222 | int ret; | ||
| 223 | |||
| 224 | snd_cx18_lock(cxsc); | ||
| 225 | ret = snd_pcm_lib_ioctl(substream, cmd, arg); | ||
| 226 | snd_cx18_unlock(cxsc); | ||
| 227 | return ret; | ||
| 222 | } | 228 | } |
| 223 | 229 | ||
| 224 | 230 | ||
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 9045f1ece0e..ab461e27d9d 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
| @@ -41,7 +41,7 @@ static struct v4l2_file_operations cx18_v4l2_enc_fops = { | |||
| 41 | .read = cx18_v4l2_read, | 41 | .read = cx18_v4l2_read, |
| 42 | .open = cx18_v4l2_open, | 42 | .open = cx18_v4l2_open, |
| 43 | /* FIXME change to video_ioctl2 if serialization lock can be removed */ | 43 | /* FIXME change to video_ioctl2 if serialization lock can be removed */ |
| 44 | .ioctl = cx18_v4l2_ioctl, | 44 | .unlocked_ioctl = cx18_v4l2_ioctl, |
| 45 | .release = cx18_v4l2_close, | 45 | .release = cx18_v4l2_close, |
| 46 | .poll = cx18_v4l2_enc_poll, | 46 | .poll = cx18_v4l2_enc_poll, |
| 47 | }; | 47 | }; |
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index a5cfc76b40b..bb164099ea2 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c | |||
| @@ -2530,7 +2530,7 @@ static const struct v4l2_file_operations et61x251_fops = { | |||
| 2530 | .owner = THIS_MODULE, | 2530 | .owner = THIS_MODULE, |
| 2531 | .open = et61x251_open, | 2531 | .open = et61x251_open, |
| 2532 | .release = et61x251_release, | 2532 | .release = et61x251_release, |
| 2533 | .ioctl = et61x251_ioctl, | 2533 | .unlocked_ioctl = et61x251_ioctl, |
| 2534 | .read = et61x251_read, | 2534 | .read = et61x251_read, |
| 2535 | .poll = et61x251_poll, | 2535 | .poll = et61x251_poll, |
| 2536 | .mmap = et61x251_mmap, | 2536 | .mmap = et61x251_mmap, |
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 2be23bccd3c..48d2c2419c1 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c | |||
| @@ -1659,7 +1659,7 @@ static const struct v4l2_file_operations meye_fops = { | |||
| 1659 | .open = meye_open, | 1659 | .open = meye_open, |
| 1660 | .release = meye_release, | 1660 | .release = meye_release, |
| 1661 | .mmap = meye_mmap, | 1661 | .mmap = meye_mmap, |
| 1662 | .ioctl = video_ioctl2, | 1662 | .unlocked_ioctl = video_ioctl2, |
| 1663 | .poll = meye_poll, | 1663 | .poll = meye_poll, |
| 1664 | }; | 1664 | }; |
| 1665 | 1665 | ||
| @@ -1831,12 +1831,6 @@ static int __devinit meye_probe(struct pci_dev *pcidev, | |||
| 1831 | msleep(1); | 1831 | msleep(1); |
| 1832 | mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK); | 1832 | mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK); |
| 1833 | 1833 | ||
| 1834 | if (video_register_device(meye.vdev, VFL_TYPE_GRABBER, | ||
| 1835 | video_nr) < 0) { | ||
| 1836 | v4l2_err(v4l2_dev, "video_register_device failed\n"); | ||
| 1837 | goto outvideoreg; | ||
| 1838 | } | ||
| 1839 | |||
| 1840 | mutex_init(&meye.lock); | 1834 | mutex_init(&meye.lock); |
| 1841 | init_waitqueue_head(&meye.proc_list); | 1835 | init_waitqueue_head(&meye.proc_list); |
| 1842 | meye.brightness = 32 << 10; | 1836 | meye.brightness = 32 << 10; |
| @@ -1858,6 +1852,12 @@ static int __devinit meye_probe(struct pci_dev *pcidev, | |||
| 1858 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0); | 1852 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0); |
| 1859 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48); | 1853 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48); |
| 1860 | 1854 | ||
| 1855 | if (video_register_device(meye.vdev, VFL_TYPE_GRABBER, | ||
| 1856 | video_nr) < 0) { | ||
| 1857 | v4l2_err(v4l2_dev, "video_register_device failed\n"); | ||
| 1858 | goto outvideoreg; | ||
| 1859 | } | ||
| 1860 | |||
| 1861 | v4l2_info(v4l2_dev, "Motion Eye Camera Driver v%s.\n", | 1861 | v4l2_info(v4l2_dev, "Motion Eye Camera Driver v%s.\n", |
| 1862 | MEYE_DRIVER_VERSION); | 1862 | MEYE_DRIVER_VERSION); |
| 1863 | v4l2_info(v4l2_dev, "mchip KL5A72002 rev. %d, base %lx, irq %d\n", | 1863 | v4l2_info(v4l2_dev, "mchip KL5A72002 rev. %d, base %lx, irq %d\n", |
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 7129b50757d..7551907f8c2 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c | |||
| @@ -932,7 +932,7 @@ static ssize_t pms_read(struct file *file, char __user *buf, | |||
| 932 | 932 | ||
| 933 | static const struct v4l2_file_operations pms_fops = { | 933 | static const struct v4l2_file_operations pms_fops = { |
| 934 | .owner = THIS_MODULE, | 934 | .owner = THIS_MODULE, |
| 935 | .ioctl = video_ioctl2, | 935 | .unlocked_ioctl = video_ioctl2, |
| 936 | .read = pms_read, | 936 | .read = pms_read, |
| 937 | }; | 937 | }; |
| 938 | 938 | ||
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c index 4e5a8cf76de..07cf0c6c7c1 100644 --- a/drivers/media/video/sh_vou.c +++ b/drivers/media/video/sh_vou.c | |||
| @@ -75,6 +75,7 @@ struct sh_vou_device { | |||
| 75 | int pix_idx; | 75 | int pix_idx; |
| 76 | struct videobuf_buffer *active; | 76 | struct videobuf_buffer *active; |
| 77 | enum sh_vou_status status; | 77 | enum sh_vou_status status; |
| 78 | struct mutex fop_lock; | ||
| 78 | }; | 79 | }; |
| 79 | 80 | ||
| 80 | struct sh_vou_file { | 81 | struct sh_vou_file { |
| @@ -235,7 +236,7 @@ static void free_buffer(struct videobuf_queue *vq, struct videobuf_buffer *vb) | |||
| 235 | vb->state = VIDEOBUF_NEEDS_INIT; | 236 | vb->state = VIDEOBUF_NEEDS_INIT; |
| 236 | } | 237 | } |
| 237 | 238 | ||
| 238 | /* Locking: caller holds vq->vb_lock mutex */ | 239 | /* Locking: caller holds fop_lock mutex */ |
| 239 | static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count, | 240 | static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count, |
| 240 | unsigned int *size) | 241 | unsigned int *size) |
| 241 | { | 242 | { |
| @@ -257,7 +258,7 @@ static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count, | |||
| 257 | return 0; | 258 | return 0; |
| 258 | } | 259 | } |
| 259 | 260 | ||
| 260 | /* Locking: caller holds vq->vb_lock mutex */ | 261 | /* Locking: caller holds fop_lock mutex */ |
| 261 | static int sh_vou_buf_prepare(struct videobuf_queue *vq, | 262 | static int sh_vou_buf_prepare(struct videobuf_queue *vq, |
| 262 | struct videobuf_buffer *vb, | 263 | struct videobuf_buffer *vb, |
| 263 | enum v4l2_field field) | 264 | enum v4l2_field field) |
| @@ -306,7 +307,7 @@ static int sh_vou_buf_prepare(struct videobuf_queue *vq, | |||
| 306 | return 0; | 307 | return 0; |
| 307 | } | 308 | } |
| 308 | 309 | ||
| 309 | /* Locking: caller holds vq->vb_lock mutex and vq->irqlock spinlock */ | 310 | /* Locking: caller holds fop_lock mutex and vq->irqlock spinlock */ |
| 310 | static void sh_vou_buf_queue(struct videobuf_queue *vq, | 311 | static void sh_vou_buf_queue(struct videobuf_queue *vq, |
| 311 | struct videobuf_buffer *vb) | 312 | struct videobuf_buffer *vb) |
| 312 | { | 313 | { |
| @@ -1190,7 +1191,7 @@ static int sh_vou_open(struct file *file) | |||
| 1190 | V4L2_BUF_TYPE_VIDEO_OUTPUT, | 1191 | V4L2_BUF_TYPE_VIDEO_OUTPUT, |
| 1191 | V4L2_FIELD_NONE, | 1192 | V4L2_FIELD_NONE, |
| 1192 | sizeof(struct videobuf_buffer), vdev, | 1193 | sizeof(struct videobuf_buffer), vdev, |
| 1193 | NULL); | 1194 | &vou_dev->fop_lock); |
| 1194 | 1195 | ||
| 1195 | return 0; | 1196 | return 0; |
| 1196 | } | 1197 | } |
| @@ -1292,7 +1293,7 @@ static const struct v4l2_file_operations sh_vou_fops = { | |||
| 1292 | .owner = THIS_MODULE, | 1293 | .owner = THIS_MODULE, |
| 1293 | .open = sh_vou_open, | 1294 | .open = sh_vou_open, |
| 1294 | .release = sh_vou_release, | 1295 | .release = sh_vou_release, |
| 1295 | .ioctl = video_ioctl2, | 1296 | .unlocked_ioctl = video_ioctl2, |
| 1296 | .mmap = sh_vou_mmap, | 1297 | .mmap = sh_vou_mmap, |
| 1297 | .poll = sh_vou_poll, | 1298 | .poll = sh_vou_poll, |
| 1298 | }; | 1299 | }; |
| @@ -1331,6 +1332,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev) | |||
| 1331 | 1332 | ||
| 1332 | INIT_LIST_HEAD(&vou_dev->queue); | 1333 | INIT_LIST_HEAD(&vou_dev->queue); |
| 1333 | spin_lock_init(&vou_dev->lock); | 1334 | spin_lock_init(&vou_dev->lock); |
| 1335 | mutex_init(&vou_dev->fop_lock); | ||
| 1334 | atomic_set(&vou_dev->use_count, 0); | 1336 | atomic_set(&vou_dev->use_count, 0); |
| 1335 | vou_dev->pdata = vou_pdata; | 1337 | vou_dev->pdata = vou_pdata; |
| 1336 | vou_dev->status = SH_VOU_IDLE; | 1338 | vou_dev->status = SH_VOU_IDLE; |
| @@ -1388,6 +1390,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev) | |||
| 1388 | vdev->tvnorms |= V4L2_STD_PAL; | 1390 | vdev->tvnorms |= V4L2_STD_PAL; |
| 1389 | vdev->v4l2_dev = &vou_dev->v4l2_dev; | 1391 | vdev->v4l2_dev = &vou_dev->v4l2_dev; |
| 1390 | vdev->release = video_device_release; | 1392 | vdev->release = video_device_release; |
| 1393 | vdev->lock = &vou_dev->fop_lock; | ||
| 1391 | 1394 | ||
| 1392 | vou_dev->vdev = vdev; | 1395 | vou_dev->vdev = vdev; |
| 1393 | video_set_drvdata(vdev, vou_dev); | 1396 | video_set_drvdata(vdev, vou_dev); |
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index 28e19daadec..f49fbfb7dc1 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c | |||
| @@ -3238,7 +3238,7 @@ static const struct v4l2_file_operations sn9c102_fops = { | |||
| 3238 | .owner = THIS_MODULE, | 3238 | .owner = THIS_MODULE, |
| 3239 | .open = sn9c102_open, | 3239 | .open = sn9c102_open, |
| 3240 | .release = sn9c102_release, | 3240 | .release = sn9c102_release, |
| 3241 | .ioctl = sn9c102_ioctl, | 3241 | .unlocked_ioctl = sn9c102_ioctl, |
| 3242 | .read = sn9c102_read, | 3242 | .read = sn9c102_read, |
| 3243 | .poll = sn9c102_poll, | 3243 | .poll = sn9c102_poll, |
| 3244 | .mmap = sn9c102_mmap, | 3244 | .mmap = sn9c102_mmap, |
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index f169f773667..59f8a9ad379 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c | |||
| @@ -785,7 +785,7 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id, | |||
| 785 | } | 785 | } |
| 786 | } | 786 | } |
| 787 | 787 | ||
| 788 | struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, | 788 | static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, |
| 789 | __u32 v4l2_id, struct uvc_control_mapping **mapping) | 789 | __u32 v4l2_id, struct uvc_control_mapping **mapping) |
| 790 | { | 790 | { |
| 791 | struct uvc_control *ctrl = NULL; | 791 | struct uvc_control *ctrl = NULL; |
| @@ -944,6 +944,52 @@ done: | |||
| 944 | return ret; | 944 | return ret; |
| 945 | } | 945 | } |
| 946 | 946 | ||
| 947 | /* | ||
| 948 | * Mapping V4L2 controls to UVC controls can be straighforward if done well. | ||
| 949 | * Most of the UVC controls exist in V4L2, and can be mapped directly. Some | ||
| 950 | * must be grouped (for instance the Red Balance, Blue Balance and Do White | ||
| 951 | * Balance V4L2 controls use the White Balance Component UVC control) or | ||
| 952 | * otherwise translated. The approach we take here is to use a translation | ||
| 953 | * table for the controls that can be mapped directly, and handle the others | ||
| 954 | * manually. | ||
| 955 | */ | ||
| 956 | int uvc_query_v4l2_menu(struct uvc_video_chain *chain, | ||
| 957 | struct v4l2_querymenu *query_menu) | ||
| 958 | { | ||
| 959 | struct uvc_menu_info *menu_info; | ||
| 960 | struct uvc_control_mapping *mapping; | ||
| 961 | struct uvc_control *ctrl; | ||
| 962 | u32 index = query_menu->index; | ||
| 963 | u32 id = query_menu->id; | ||
| 964 | int ret; | ||
| 965 | |||
| 966 | memset(query_menu, 0, sizeof(*query_menu)); | ||
| 967 | query_menu->id = id; | ||
| 968 | query_menu->index = index; | ||
| 969 | |||
| 970 | ret = mutex_lock_interruptible(&chain->ctrl_mutex); | ||
| 971 | if (ret < 0) | ||
| 972 | return -ERESTARTSYS; | ||
| 973 | |||
| 974 | ctrl = uvc_find_control(chain, query_menu->id, &mapping); | ||
| 975 | if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) { | ||
| 976 | ret = -EINVAL; | ||
| 977 | goto done; | ||
| 978 | } | ||
| 979 | |||
| 980 | if (query_menu->index >= mapping->menu_count) { | ||
| 981 | ret = -EINVAL; | ||
| 982 | goto done; | ||
| 983 | } | ||
| 984 | |||
| 985 | menu_info = &mapping->menu_info[query_menu->index]; | ||
| 986 | strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); | ||
| 987 | |||
| 988 | done: | ||
| 989 | mutex_unlock(&chain->ctrl_mutex); | ||
| 990 | return ret; | ||
| 991 | } | ||
| 992 | |||
| 947 | 993 | ||
| 948 | /* -------------------------------------------------------------------------- | 994 | /* -------------------------------------------------------------------------- |
| 949 | * Control transactions | 995 | * Control transactions |
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index ed6d5449741..f14581bd707 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c | |||
| @@ -90,6 +90,39 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, | |||
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | /* | 92 | /* |
| 93 | * Free the video buffers. | ||
| 94 | * | ||
| 95 | * This function must be called with the queue lock held. | ||
| 96 | */ | ||
| 97 | static int __uvc_free_buffers(struct uvc_video_queue *queue) | ||
| 98 | { | ||
| 99 | unsigned int i; | ||
| 100 | |||
| 101 | for (i = 0; i < queue->count; ++i) { | ||
| 102 | if (queue->buffer[i].vma_use_count != 0) | ||
| 103 | return -EBUSY; | ||
| 104 | } | ||
| 105 | |||
| 106 | if (queue->count) { | ||
| 107 | vfree(queue->mem); | ||
| 108 | queue->count = 0; | ||
| 109 | } | ||
| 110 | |||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | |||
| 114 | int uvc_free_buffers(struct uvc_video_queue *queue) | ||
| 115 | { | ||
| 116 | int ret; | ||
| 117 | |||
| 118 | mutex_lock(&queue->mutex); | ||
| 119 | ret = __uvc_free_buffers(queue); | ||
| 120 | mutex_unlock(&queue->mutex); | ||
| 121 | |||
| 122 | return ret; | ||
| 123 | } | ||
| 124 | |||
| 125 | /* | ||
| 93 | * Allocate the video buffers. | 126 | * Allocate the video buffers. |
| 94 | * | 127 | * |
| 95 | * Pages are reserved to make sure they will not be swapped, as they will be | 128 | * Pages are reserved to make sure they will not be swapped, as they will be |
| @@ -110,7 +143,7 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers, | |||
| 110 | 143 | ||
| 111 | mutex_lock(&queue->mutex); | 144 | mutex_lock(&queue->mutex); |
| 112 | 145 | ||
| 113 | if ((ret = uvc_free_buffers(queue)) < 0) | 146 | if ((ret = __uvc_free_buffers(queue)) < 0) |
| 114 | goto done; | 147 | goto done; |
| 115 | 148 | ||
| 116 | /* Bail out if no buffers should be allocated. */ | 149 | /* Bail out if no buffers should be allocated. */ |
| @@ -152,28 +185,6 @@ done: | |||
| 152 | } | 185 | } |
| 153 | 186 | ||
| 154 | /* | 187 | /* |
| 155 | * Free the video buffers. | ||
| 156 | * | ||
| 157 | * This function must be called with the queue lock held. | ||
| 158 | */ | ||
| 159 | int uvc_free_buffers(struct uvc_video_queue *queue) | ||
| 160 | { | ||
| 161 | unsigned int i; | ||
| 162 | |||
| 163 | for (i = 0; i < queue->count; ++i) { | ||
| 164 | if (queue->buffer[i].vma_use_count != 0) | ||
| 165 | return -EBUSY; | ||
| 166 | } | ||
| 167 | |||
| 168 | if (queue->count) { | ||
| 169 | vfree(queue->mem); | ||
| 170 | queue->count = 0; | ||
| 171 | } | ||
| 172 | |||
| 173 | return 0; | ||
| 174 | } | ||
| 175 | |||
| 176 | /* | ||
| 177 | * Check if buffers have been allocated. | 188 | * Check if buffers have been allocated. |
| 178 | */ | 189 | */ |
| 179 | int uvc_queue_allocated(struct uvc_video_queue *queue) | 190 | int uvc_queue_allocated(struct uvc_video_queue *queue) |
| @@ -369,6 +380,82 @@ done: | |||
| 369 | } | 380 | } |
| 370 | 381 | ||
| 371 | /* | 382 | /* |
| 383 | * VMA operations. | ||
| 384 | */ | ||
| 385 | static void uvc_vm_open(struct vm_area_struct *vma) | ||
| 386 | { | ||
| 387 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
| 388 | buffer->vma_use_count++; | ||
| 389 | } | ||
| 390 | |||
| 391 | static void uvc_vm_close(struct vm_area_struct *vma) | ||
| 392 | { | ||
| 393 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
| 394 | buffer->vma_use_count--; | ||
| 395 | } | ||
| 396 | |||
| 397 | static const struct vm_operations_struct uvc_vm_ops = { | ||
| 398 | .open = uvc_vm_open, | ||
| 399 | .close = uvc_vm_close, | ||
| 400 | }; | ||
| 401 | |||
| 402 | /* | ||
| 403 | * Memory-map a video buffer. | ||
| 404 | * | ||
| 405 | * This function implements video buffers memory mapping and is intended to be | ||
| 406 | * used by the device mmap handler. | ||
| 407 | */ | ||
| 408 | int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) | ||
| 409 | { | ||
| 410 | struct uvc_buffer *uninitialized_var(buffer); | ||
| 411 | struct page *page; | ||
| 412 | unsigned long addr, start, size; | ||
| 413 | unsigned int i; | ||
| 414 | int ret = 0; | ||
| 415 | |||
| 416 | start = vma->vm_start; | ||
| 417 | size = vma->vm_end - vma->vm_start; | ||
| 418 | |||
| 419 | mutex_lock(&queue->mutex); | ||
| 420 | |||
| 421 | for (i = 0; i < queue->count; ++i) { | ||
| 422 | buffer = &queue->buffer[i]; | ||
| 423 | if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) | ||
| 424 | break; | ||
| 425 | } | ||
| 426 | |||
| 427 | if (i == queue->count || size != queue->buf_size) { | ||
| 428 | ret = -EINVAL; | ||
| 429 | goto done; | ||
| 430 | } | ||
| 431 | |||
| 432 | /* | ||
| 433 | * VM_IO marks the area as being an mmaped region for I/O to a | ||
| 434 | * device. It also prevents the region from being core dumped. | ||
| 435 | */ | ||
| 436 | vma->vm_flags |= VM_IO; | ||
| 437 | |||
| 438 | addr = (unsigned long)queue->mem + buffer->buf.m.offset; | ||
| 439 | while (size > 0) { | ||
| 440 | page = vmalloc_to_page((void *)addr); | ||
| 441 | if ((ret = vm_insert_page(vma, start, page)) < 0) | ||
| 442 | goto done; | ||
| 443 | |||
| 444 | start += PAGE_SIZE; | ||
| 445 | addr += PAGE_SIZE; | ||
| 446 | size -= PAGE_SIZE; | ||
| 447 | } | ||
| 448 | |||
| 449 | vma->vm_ops = &uvc_vm_ops; | ||
| 450 | vma->vm_private_data = buffer; | ||
| 451 | uvc_vm_open(vma); | ||
| 452 | |||
| 453 | done: | ||
| 454 | mutex_unlock(&queue->mutex); | ||
| 455 | return ret; | ||
| 456 | } | ||
| 457 | |||
| 458 | /* | ||
| 372 | * Poll the video queue. | 459 | * Poll the video queue. |
| 373 | * | 460 | * |
| 374 | * This function implements video queue polling and is intended to be used by | 461 | * This function implements video queue polling and is intended to be used by |
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 6d15de9b520..8cf61e8a634 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c | |||
| @@ -101,40 +101,6 @@ done: | |||
| 101 | */ | 101 | */ |
| 102 | 102 | ||
| 103 | /* | 103 | /* |
| 104 | * Mapping V4L2 controls to UVC controls can be straighforward if done well. | ||
| 105 | * Most of the UVC controls exist in V4L2, and can be mapped directly. Some | ||
| 106 | * must be grouped (for instance the Red Balance, Blue Balance and Do White | ||
| 107 | * Balance V4L2 controls use the White Balance Component UVC control) or | ||
| 108 | * otherwise translated. The approach we take here is to use a translation | ||
| 109 | * table for the controls that can be mapped directly, and handle the others | ||
| 110 | * manually. | ||
| 111 | */ | ||
| 112 | static int uvc_v4l2_query_menu(struct uvc_video_chain *chain, | ||
| 113 | struct v4l2_querymenu *query_menu) | ||
| 114 | { | ||
| 115 | struct uvc_menu_info *menu_info; | ||
| 116 | struct uvc_control_mapping *mapping; | ||
| 117 | struct uvc_control *ctrl; | ||
| 118 | u32 index = query_menu->index; | ||
| 119 | u32 id = query_menu->id; | ||
| 120 | |||
| 121 | ctrl = uvc_find_control(chain, query_menu->id, &mapping); | ||
| 122 | if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) | ||
| 123 | return -EINVAL; | ||
| 124 | |||
| 125 | if (query_menu->index >= mapping->menu_count) | ||
| 126 | return -EINVAL; | ||
| 127 | |||
| 128 | memset(query_menu, 0, sizeof(*query_menu)); | ||
| 129 | query_menu->id = id; | ||
| 130 | query_menu->index = index; | ||
| 131 | |||
| 132 | menu_info = &mapping->menu_info[query_menu->index]; | ||
| 133 | strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); | ||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | |||
| 137 | /* | ||
| 138 | * Find the frame interval closest to the requested frame interval for the | 104 | * Find the frame interval closest to the requested frame interval for the |
| 139 | * given frame format and size. This should be done by the device as part of | 105 | * given frame format and size. This should be done by the device as part of |
| 140 | * the Video Probe and Commit negotiation, but some hardware don't implement | 106 | * the Video Probe and Commit negotiation, but some hardware don't implement |
| @@ -260,12 +226,14 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, | |||
| 260 | * developers test their webcams with the Linux driver as well as with | 226 | * developers test their webcams with the Linux driver as well as with |
| 261 | * the Windows driver). | 227 | * the Windows driver). |
| 262 | */ | 228 | */ |
| 229 | mutex_lock(&stream->mutex); | ||
| 263 | if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS) | 230 | if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS) |
| 264 | probe->dwMaxVideoFrameSize = | 231 | probe->dwMaxVideoFrameSize = |
| 265 | stream->ctrl.dwMaxVideoFrameSize; | 232 | stream->ctrl.dwMaxVideoFrameSize; |
| 266 | 233 | ||
| 267 | /* Probe the device. */ | 234 | /* Probe the device. */ |
| 268 | ret = uvc_probe_video(stream, probe); | 235 | ret = uvc_probe_video(stream, probe); |
| 236 | mutex_unlock(&stream->mutex); | ||
| 269 | if (ret < 0) | 237 | if (ret < 0) |
| 270 | goto done; | 238 | goto done; |
| 271 | 239 | ||
| @@ -289,14 +257,21 @@ done: | |||
| 289 | static int uvc_v4l2_get_format(struct uvc_streaming *stream, | 257 | static int uvc_v4l2_get_format(struct uvc_streaming *stream, |
| 290 | struct v4l2_format *fmt) | 258 | struct v4l2_format *fmt) |
| 291 | { | 259 | { |
| 292 | struct uvc_format *format = stream->cur_format; | 260 | struct uvc_format *format; |
| 293 | struct uvc_frame *frame = stream->cur_frame; | 261 | struct uvc_frame *frame; |
| 262 | int ret = 0; | ||
| 294 | 263 | ||
| 295 | if (fmt->type != stream->type) | 264 | if (fmt->type != stream->type) |
| 296 | return -EINVAL; | 265 | return -EINVAL; |
| 297 | 266 | ||
| 298 | if (format == NULL || frame == NULL) | 267 | mutex_lock(&stream->mutex); |
| 299 | return -EINVAL; | 268 | format = stream->cur_format; |
| 269 | frame = stream->cur_frame; | ||
| 270 | |||
| 271 | if (format == NULL || frame == NULL) { | ||
| 272 | ret = -EINVAL; | ||
| 273 | goto done; | ||
| 274 | } | ||
| 300 | 275 | ||
| 301 | fmt->fmt.pix.pixelformat = format->fcc; | 276 | fmt->fmt.pix.pixelformat = format->fcc; |
| 302 | fmt->fmt.pix.width = frame->wWidth; | 277 | fmt->fmt.pix.width = frame->wWidth; |
| @@ -307,7 +282,9 @@ static int uvc_v4l2_get_format(struct uvc_streaming *stream, | |||
| 307 | fmt->fmt.pix.colorspace = format->colorspace; | 282 | fmt->fmt.pix.colorspace = format->colorspace; |
| 308 | fmt->fmt.pix.priv = 0; | 283 | fmt->fmt.pix.priv = 0; |
| 309 | 284 | ||
| 310 | return 0; | 285 | done: |
| 286 | mutex_unlock(&stream->mutex); | ||
| 287 | return ret; | ||
| 311 | } | 288 | } |
| 312 | 289 | ||
| 313 | static int uvc_v4l2_set_format(struct uvc_streaming *stream, | 290 | static int uvc_v4l2_set_format(struct uvc_streaming *stream, |
| @@ -321,18 +298,24 @@ static int uvc_v4l2_set_format(struct uvc_streaming *stream, | |||
| 321 | if (fmt->type != stream->type) | 298 | if (fmt->type != stream->type) |
| 322 | return -EINVAL; | 299 | return -EINVAL; |
| 323 | 300 | ||
| 324 | if (uvc_queue_allocated(&stream->queue)) | ||
| 325 | return -EBUSY; | ||
| 326 | |||
| 327 | ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame); | 301 | ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame); |
| 328 | if (ret < 0) | 302 | if (ret < 0) |
| 329 | return ret; | 303 | return ret; |
| 330 | 304 | ||
| 305 | mutex_lock(&stream->mutex); | ||
| 306 | |||
| 307 | if (uvc_queue_allocated(&stream->queue)) { | ||
| 308 | ret = -EBUSY; | ||
| 309 | goto done; | ||
| 310 | } | ||
| 311 | |||
| 331 | memcpy(&stream->ctrl, &probe, sizeof probe); | 312 | memcpy(&stream->ctrl, &probe, sizeof probe); |
| 332 | stream->cur_format = format; | 313 | stream->cur_format = format; |
| 333 | stream->cur_frame = frame; | 314 | stream->cur_frame = frame; |
| 334 | 315 | ||
| 335 | return 0; | 316 | done: |
| 317 | mutex_unlock(&stream->mutex); | ||
| 318 | return ret; | ||
| 336 | } | 319 | } |
| 337 | 320 | ||
| 338 | static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, | 321 | static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, |
| @@ -343,7 +326,10 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, | |||
| 343 | if (parm->type != stream->type) | 326 | if (parm->type != stream->type) |
| 344 | return -EINVAL; | 327 | return -EINVAL; |
| 345 | 328 | ||
| 329 | mutex_lock(&stream->mutex); | ||
| 346 | numerator = stream->ctrl.dwFrameInterval; | 330 | numerator = stream->ctrl.dwFrameInterval; |
| 331 | mutex_unlock(&stream->mutex); | ||
| 332 | |||
| 347 | denominator = 10000000; | 333 | denominator = 10000000; |
| 348 | uvc_simplify_fraction(&numerator, &denominator, 8, 333); | 334 | uvc_simplify_fraction(&numerator, &denominator, 8, 333); |
| 349 | 335 | ||
| @@ -370,7 +356,6 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, | |||
| 370 | static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, | 356 | static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, |
| 371 | struct v4l2_streamparm *parm) | 357 | struct v4l2_streamparm *parm) |
| 372 | { | 358 | { |
| 373 | struct uvc_frame *frame = stream->cur_frame; | ||
| 374 | struct uvc_streaming_control probe; | 359 | struct uvc_streaming_control probe; |
| 375 | struct v4l2_fract timeperframe; | 360 | struct v4l2_fract timeperframe; |
| 376 | uint32_t interval; | 361 | uint32_t interval; |
| @@ -379,28 +364,36 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, | |||
| 379 | if (parm->type != stream->type) | 364 | if (parm->type != stream->type) |
| 380 | return -EINVAL; | 365 | return -EINVAL; |
| 381 | 366 | ||
| 382 | if (uvc_queue_streaming(&stream->queue)) | ||
| 383 | return -EBUSY; | ||
| 384 | |||
| 385 | if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | 367 | if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
| 386 | timeperframe = parm->parm.capture.timeperframe; | 368 | timeperframe = parm->parm.capture.timeperframe; |
| 387 | else | 369 | else |
| 388 | timeperframe = parm->parm.output.timeperframe; | 370 | timeperframe = parm->parm.output.timeperframe; |
| 389 | 371 | ||
| 390 | memcpy(&probe, &stream->ctrl, sizeof probe); | ||
| 391 | interval = uvc_fraction_to_interval(timeperframe.numerator, | 372 | interval = uvc_fraction_to_interval(timeperframe.numerator, |
| 392 | timeperframe.denominator); | 373 | timeperframe.denominator); |
| 393 | |||
| 394 | uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n", | 374 | uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n", |
| 395 | timeperframe.numerator, timeperframe.denominator, interval); | 375 | timeperframe.numerator, timeperframe.denominator, interval); |
| 396 | probe.dwFrameInterval = uvc_try_frame_interval(frame, interval); | 376 | |
| 377 | mutex_lock(&stream->mutex); | ||
| 378 | |||
| 379 | if (uvc_queue_streaming(&stream->queue)) { | ||
| 380 | mutex_unlock(&stream->mutex); | ||
| 381 | return -EBUSY; | ||
| 382 | } | ||
| 383 | |||
| 384 | memcpy(&probe, &stream->ctrl, sizeof probe); | ||
| 385 | probe.dwFrameInterval = | ||
| 386 | uvc_try_frame_interval(stream->cur_frame, interval); | ||
| 397 | 387 | ||
| 398 | /* Probe the device with the new settings. */ | 388 | /* Probe the device with the new settings. */ |
| 399 | ret = uvc_probe_video(stream, &probe); | 389 | ret = uvc_probe_video(stream, &probe); |
| 400 | if (ret < 0) | 390 | if (ret < 0) { |
| 391 | mutex_unlock(&stream->mutex); | ||
| 401 | return ret; | 392 | return ret; |
| 393 | } | ||
| 402 | 394 | ||
| 403 | memcpy(&stream->ctrl, &probe, sizeof probe); | 395 | memcpy(&stream->ctrl, &probe, sizeof probe); |
| 396 | mutex_unlock(&stream->mutex); | ||
| 404 | 397 | ||
| 405 | /* Return the actual frame period. */ | 398 | /* Return the actual frame period. */ |
| 406 | timeperframe.numerator = probe.dwFrameInterval; | 399 | timeperframe.numerator = probe.dwFrameInterval; |
| @@ -528,11 +521,9 @@ static int uvc_v4l2_release(struct file *file) | |||
| 528 | if (uvc_has_privileges(handle)) { | 521 | if (uvc_has_privileges(handle)) { |
| 529 | uvc_video_enable(stream, 0); | 522 | uvc_video_enable(stream, 0); |
| 530 | 523 | ||
| 531 | mutex_lock(&stream->queue.mutex); | ||
| 532 | if (uvc_free_buffers(&stream->queue) < 0) | 524 | if (uvc_free_buffers(&stream->queue) < 0) |
| 533 | uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to " | 525 | uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to " |
| 534 | "free buffers.\n"); | 526 | "free buffers.\n"); |
| 535 | mutex_unlock(&stream->queue.mutex); | ||
| 536 | } | 527 | } |
| 537 | 528 | ||
| 538 | /* Release the file handle. */ | 529 | /* Release the file handle. */ |
| @@ -624,7 +615,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 624 | } | 615 | } |
| 625 | 616 | ||
| 626 | case VIDIOC_QUERYMENU: | 617 | case VIDIOC_QUERYMENU: |
| 627 | return uvc_v4l2_query_menu(chain, arg); | 618 | return uvc_query_v4l2_menu(chain, arg); |
| 628 | 619 | ||
| 629 | case VIDIOC_G_EXT_CTRLS: | 620 | case VIDIOC_G_EXT_CTRLS: |
| 630 | { | 621 | { |
| @@ -905,15 +896,17 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 905 | case VIDIOC_CROPCAP: | 896 | case VIDIOC_CROPCAP: |
| 906 | { | 897 | { |
| 907 | struct v4l2_cropcap *ccap = arg; | 898 | struct v4l2_cropcap *ccap = arg; |
| 908 | struct uvc_frame *frame = stream->cur_frame; | ||
| 909 | 899 | ||
| 910 | if (ccap->type != stream->type) | 900 | if (ccap->type != stream->type) |
| 911 | return -EINVAL; | 901 | return -EINVAL; |
| 912 | 902 | ||
| 913 | ccap->bounds.left = 0; | 903 | ccap->bounds.left = 0; |
| 914 | ccap->bounds.top = 0; | 904 | ccap->bounds.top = 0; |
| 915 | ccap->bounds.width = frame->wWidth; | 905 | |
| 916 | ccap->bounds.height = frame->wHeight; | 906 | mutex_lock(&stream->mutex); |
| 907 | ccap->bounds.width = stream->cur_frame->wWidth; | ||
| 908 | ccap->bounds.height = stream->cur_frame->wHeight; | ||
| 909 | mutex_unlock(&stream->mutex); | ||
| 917 | 910 | ||
| 918 | ccap->defrect = ccap->bounds; | 911 | ccap->defrect = ccap->bounds; |
| 919 | 912 | ||
| @@ -930,8 +923,6 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 930 | case VIDIOC_REQBUFS: | 923 | case VIDIOC_REQBUFS: |
| 931 | { | 924 | { |
| 932 | struct v4l2_requestbuffers *rb = arg; | 925 | struct v4l2_requestbuffers *rb = arg; |
| 933 | unsigned int bufsize = | ||
| 934 | stream->ctrl.dwMaxVideoFrameSize; | ||
| 935 | 926 | ||
| 936 | if (rb->type != stream->type || | 927 | if (rb->type != stream->type || |
| 937 | rb->memory != V4L2_MEMORY_MMAP) | 928 | rb->memory != V4L2_MEMORY_MMAP) |
| @@ -940,7 +931,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 940 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 931 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
| 941 | return ret; | 932 | return ret; |
| 942 | 933 | ||
| 943 | ret = uvc_alloc_buffers(&stream->queue, rb->count, bufsize); | 934 | mutex_lock(&stream->mutex); |
| 935 | ret = uvc_alloc_buffers(&stream->queue, rb->count, | ||
| 936 | stream->ctrl.dwMaxVideoFrameSize); | ||
| 937 | mutex_unlock(&stream->mutex); | ||
| 944 | if (ret < 0) | 938 | if (ret < 0) |
| 945 | return ret; | 939 | return ret; |
| 946 | 940 | ||
| @@ -988,7 +982,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 988 | if (!uvc_has_privileges(handle)) | 982 | if (!uvc_has_privileges(handle)) |
| 989 | return -EBUSY; | 983 | return -EBUSY; |
| 990 | 984 | ||
| 985 | mutex_lock(&stream->mutex); | ||
| 991 | ret = uvc_video_enable(stream, 1); | 986 | ret = uvc_video_enable(stream, 1); |
| 987 | mutex_unlock(&stream->mutex); | ||
| 992 | if (ret < 0) | 988 | if (ret < 0) |
| 993 | return ret; | 989 | return ret; |
| 994 | break; | 990 | break; |
| @@ -1068,79 +1064,14 @@ static ssize_t uvc_v4l2_read(struct file *file, char __user *data, | |||
| 1068 | return -EINVAL; | 1064 | return -EINVAL; |
| 1069 | } | 1065 | } |
| 1070 | 1066 | ||
| 1071 | /* | ||
| 1072 | * VMA operations. | ||
| 1073 | */ | ||
| 1074 | static void uvc_vm_open(struct vm_area_struct *vma) | ||
| 1075 | { | ||
| 1076 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
| 1077 | buffer->vma_use_count++; | ||
| 1078 | } | ||
| 1079 | |||
| 1080 | static void uvc_vm_close(struct vm_area_struct *vma) | ||
| 1081 | { | ||
| 1082 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
| 1083 | buffer->vma_use_count--; | ||
| 1084 | } | ||
| 1085 | |||
| 1086 | static const struct vm_operations_struct uvc_vm_ops = { | ||
| 1087 | .open = uvc_vm_open, | ||
| 1088 | .close = uvc_vm_close, | ||
| 1089 | }; | ||
| 1090 | |||
| 1091 | static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | 1067 | static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) |
| 1092 | { | 1068 | { |
| 1093 | struct uvc_fh *handle = file->private_data; | 1069 | struct uvc_fh *handle = file->private_data; |
| 1094 | struct uvc_streaming *stream = handle->stream; | 1070 | struct uvc_streaming *stream = handle->stream; |
| 1095 | struct uvc_video_queue *queue = &stream->queue; | ||
| 1096 | struct uvc_buffer *uninitialized_var(buffer); | ||
| 1097 | struct page *page; | ||
| 1098 | unsigned long addr, start, size; | ||
| 1099 | unsigned int i; | ||
| 1100 | int ret = 0; | ||
| 1101 | 1071 | ||
| 1102 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n"); | 1072 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n"); |
| 1103 | 1073 | ||
| 1104 | start = vma->vm_start; | 1074 | return uvc_queue_mmap(&stream->queue, vma); |
| 1105 | size = vma->vm_end - vma->vm_start; | ||
| 1106 | |||
| 1107 | mutex_lock(&queue->mutex); | ||
| 1108 | |||
| 1109 | for (i = 0; i < queue->count; ++i) { | ||
| 1110 | buffer = &queue->buffer[i]; | ||
| 1111 | if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) | ||
| 1112 | break; | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | if (i == queue->count || size != queue->buf_size) { | ||
| 1116 | ret = -EINVAL; | ||
| 1117 | goto done; | ||
| 1118 | } | ||
| 1119 | |||
| 1120 | /* | ||
| 1121 | * VM_IO marks the area as being an mmaped region for I/O to a | ||
| 1122 | * device. It also prevents the region from being core dumped. | ||
| 1123 | */ | ||
| 1124 | vma->vm_flags |= VM_IO; | ||
| 1125 | |||
| 1126 | addr = (unsigned long)queue->mem + buffer->buf.m.offset; | ||
| 1127 | while (size > 0) { | ||
| 1128 | page = vmalloc_to_page((void *)addr); | ||
| 1129 | if ((ret = vm_insert_page(vma, start, page)) < 0) | ||
| 1130 | goto done; | ||
| 1131 | |||
| 1132 | start += PAGE_SIZE; | ||
| 1133 | addr += PAGE_SIZE; | ||
| 1134 | size -= PAGE_SIZE; | ||
| 1135 | } | ||
| 1136 | |||
| 1137 | vma->vm_ops = &uvc_vm_ops; | ||
| 1138 | vma->vm_private_data = buffer; | ||
| 1139 | uvc_vm_open(vma); | ||
| 1140 | |||
| 1141 | done: | ||
| 1142 | mutex_unlock(&queue->mutex); | ||
| 1143 | return ret; | ||
| 1144 | } | 1075 | } |
| 1145 | 1076 | ||
| 1146 | static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) | 1077 | static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) |
| @@ -1157,7 +1088,7 @@ const struct v4l2_file_operations uvc_fops = { | |||
| 1157 | .owner = THIS_MODULE, | 1088 | .owner = THIS_MODULE, |
| 1158 | .open = uvc_v4l2_open, | 1089 | .open = uvc_v4l2_open, |
| 1159 | .release = uvc_v4l2_release, | 1090 | .release = uvc_v4l2_release, |
| 1160 | .ioctl = uvc_v4l2_ioctl, | 1091 | .unlocked_ioctl = uvc_v4l2_ioctl, |
| 1161 | .read = uvc_v4l2_read, | 1092 | .read = uvc_v4l2_read, |
| 1162 | .mmap = uvc_v4l2_mmap, | 1093 | .mmap = uvc_v4l2_mmap, |
| 1163 | .poll = uvc_v4l2_poll, | 1094 | .poll = uvc_v4l2_poll, |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 5555f010283..5673d673504 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
| @@ -293,8 +293,6 @@ int uvc_probe_video(struct uvc_streaming *stream, | |||
| 293 | unsigned int i; | 293 | unsigned int i; |
| 294 | int ret; | 294 | int ret; |
| 295 | 295 | ||
| 296 | mutex_lock(&stream->mutex); | ||
| 297 | |||
| 298 | /* Perform probing. The device should adjust the requested values | 296 | /* Perform probing. The device should adjust the requested values |
| 299 | * according to its capabilities. However, some devices, namely the | 297 | * according to its capabilities. However, some devices, namely the |
| 300 | * first generation UVC Logitech webcams, don't implement the Video | 298 | * first generation UVC Logitech webcams, don't implement the Video |
| @@ -346,7 +344,6 @@ int uvc_probe_video(struct uvc_streaming *stream, | |||
| 346 | } | 344 | } |
| 347 | 345 | ||
| 348 | done: | 346 | done: |
| 349 | mutex_unlock(&stream->mutex); | ||
| 350 | return ret; | 347 | return ret; |
| 351 | } | 348 | } |
| 352 | 349 | ||
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index d97cf6d6a4f..45f01e7e13d 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
| @@ -436,7 +436,9 @@ struct uvc_streaming { | |||
| 436 | struct uvc_streaming_control ctrl; | 436 | struct uvc_streaming_control ctrl; |
| 437 | struct uvc_format *cur_format; | 437 | struct uvc_format *cur_format; |
| 438 | struct uvc_frame *cur_frame; | 438 | struct uvc_frame *cur_frame; |
| 439 | 439 | /* Protect access to ctrl, cur_format, cur_frame and hardware video | |
| 440 | * probe control. | ||
| 441 | */ | ||
| 440 | struct mutex mutex; | 442 | struct mutex mutex; |
| 441 | 443 | ||
| 442 | unsigned int frozen : 1; | 444 | unsigned int frozen : 1; |
| @@ -574,6 +576,8 @@ extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable); | |||
| 574 | extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); | 576 | extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); |
| 575 | extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | 577 | extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, |
| 576 | struct uvc_buffer *buf); | 578 | struct uvc_buffer *buf); |
| 579 | extern int uvc_queue_mmap(struct uvc_video_queue *queue, | ||
| 580 | struct vm_area_struct *vma); | ||
| 577 | extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, | 581 | extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, |
| 578 | struct file *file, poll_table *wait); | 582 | struct file *file, poll_table *wait); |
| 579 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); | 583 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); |
| @@ -606,10 +610,10 @@ extern int uvc_status_suspend(struct uvc_device *dev); | |||
| 606 | extern int uvc_status_resume(struct uvc_device *dev); | 610 | extern int uvc_status_resume(struct uvc_device *dev); |
| 607 | 611 | ||
| 608 | /* Controls */ | 612 | /* Controls */ |
| 609 | extern struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, | ||
| 610 | __u32 v4l2_id, struct uvc_control_mapping **mapping); | ||
| 611 | extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | 613 | extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, |
| 612 | struct v4l2_queryctrl *v4l2_ctrl); | 614 | struct v4l2_queryctrl *v4l2_ctrl); |
| 615 | extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain, | ||
| 616 | struct v4l2_querymenu *query_menu); | ||
| 613 | 617 | ||
| 614 | extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, | 618 | extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, |
| 615 | const struct uvc_control_mapping *mapping); | 619 | const struct uvc_control_mapping *mapping); |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 03f7f4670e9..359e23290a7 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
| @@ -186,12 +186,12 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf, | |||
| 186 | size_t sz, loff_t *off) | 186 | size_t sz, loff_t *off) |
| 187 | { | 187 | { |
| 188 | struct video_device *vdev = video_devdata(filp); | 188 | struct video_device *vdev = video_devdata(filp); |
| 189 | int ret = -EIO; | 189 | int ret = -ENODEV; |
| 190 | 190 | ||
| 191 | if (!vdev->fops->read) | 191 | if (!vdev->fops->read) |
| 192 | return -EINVAL; | 192 | return -EINVAL; |
| 193 | if (vdev->lock) | 193 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
| 194 | mutex_lock(vdev->lock); | 194 | return -ERESTARTSYS; |
| 195 | if (video_is_registered(vdev)) | 195 | if (video_is_registered(vdev)) |
| 196 | ret = vdev->fops->read(filp, buf, sz, off); | 196 | ret = vdev->fops->read(filp, buf, sz, off); |
| 197 | if (vdev->lock) | 197 | if (vdev->lock) |
| @@ -203,12 +203,12 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, | |||
| 203 | size_t sz, loff_t *off) | 203 | size_t sz, loff_t *off) |
| 204 | { | 204 | { |
| 205 | struct video_device *vdev = video_devdata(filp); | 205 | struct video_device *vdev = video_devdata(filp); |
| 206 | int ret = -EIO; | 206 | int ret = -ENODEV; |
| 207 | 207 | ||
| 208 | if (!vdev->fops->write) | 208 | if (!vdev->fops->write) |
| 209 | return -EINVAL; | 209 | return -EINVAL; |
| 210 | if (vdev->lock) | 210 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
| 211 | mutex_lock(vdev->lock); | 211 | return -ERESTARTSYS; |
| 212 | if (video_is_registered(vdev)) | 212 | if (video_is_registered(vdev)) |
| 213 | ret = vdev->fops->write(filp, buf, sz, off); | 213 | ret = vdev->fops->write(filp, buf, sz, off); |
| 214 | if (vdev->lock) | 214 | if (vdev->lock) |
| @@ -219,10 +219,10 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, | |||
| 219 | static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) | 219 | static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) |
| 220 | { | 220 | { |
| 221 | struct video_device *vdev = video_devdata(filp); | 221 | struct video_device *vdev = video_devdata(filp); |
| 222 | int ret = DEFAULT_POLLMASK; | 222 | int ret = POLLERR | POLLHUP; |
| 223 | 223 | ||
| 224 | if (!vdev->fops->poll) | 224 | if (!vdev->fops->poll) |
| 225 | return ret; | 225 | return DEFAULT_POLLMASK; |
| 226 | if (vdev->lock) | 226 | if (vdev->lock) |
| 227 | mutex_lock(vdev->lock); | 227 | mutex_lock(vdev->lock); |
| 228 | if (video_is_registered(vdev)) | 228 | if (video_is_registered(vdev)) |
| @@ -238,20 +238,45 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 238 | int ret = -ENODEV; | 238 | int ret = -ENODEV; |
| 239 | 239 | ||
| 240 | if (vdev->fops->unlocked_ioctl) { | 240 | if (vdev->fops->unlocked_ioctl) { |
| 241 | if (vdev->lock) | 241 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
| 242 | mutex_lock(vdev->lock); | 242 | return -ERESTARTSYS; |
| 243 | if (video_is_registered(vdev)) | 243 | if (video_is_registered(vdev)) |
| 244 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); | 244 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); |
| 245 | if (vdev->lock) | 245 | if (vdev->lock) |
| 246 | mutex_unlock(vdev->lock); | 246 | mutex_unlock(vdev->lock); |
| 247 | } else if (vdev->fops->ioctl) { | 247 | } else if (vdev->fops->ioctl) { |
| 248 | /* TODO: convert all drivers to unlocked_ioctl */ | 248 | /* This code path is a replacement for the BKL. It is a major |
| 249 | * hack but it will have to do for those drivers that are not | ||
| 250 | * yet converted to use unlocked_ioctl. | ||
| 251 | * | ||
| 252 | * There are two options: if the driver implements struct | ||
| 253 | * v4l2_device, then the lock defined there is used to | ||
| 254 | * serialize the ioctls. Otherwise the v4l2 core lock defined | ||
| 255 | * below is used. This lock is really bad since it serializes | ||
| 256 | * completely independent devices. | ||
| 257 | * | ||
| 258 | * Both variants suffer from the same problem: if the driver | ||
| 259 | * sleeps, then it blocks all ioctls since the lock is still | ||
| 260 | * held. This is very common for VIDIOC_DQBUF since that | ||
| 261 | * normally waits for a frame to arrive. As a result any other | ||
| 262 | * ioctl calls will proceed very, very slowly since each call | ||
| 263 | * will have to wait for the VIDIOC_QBUF to finish. Things that | ||
| 264 | * should take 0.01s may now take 10-20 seconds. | ||
| 265 | * | ||
| 266 | * The workaround is to *not* take the lock for VIDIOC_DQBUF. | ||
| 267 | * This actually works OK for videobuf-based drivers, since | ||
| 268 | * videobuf will take its own internal lock. | ||
| 269 | */ | ||
| 249 | static DEFINE_MUTEX(v4l2_ioctl_mutex); | 270 | static DEFINE_MUTEX(v4l2_ioctl_mutex); |
| 271 | struct mutex *m = vdev->v4l2_dev ? | ||
| 272 | &vdev->v4l2_dev->ioctl_lock : &v4l2_ioctl_mutex; | ||
| 250 | 273 | ||
| 251 | mutex_lock(&v4l2_ioctl_mutex); | 274 | if (cmd != VIDIOC_DQBUF && mutex_lock_interruptible(m)) |
| 275 | return -ERESTARTSYS; | ||
| 252 | if (video_is_registered(vdev)) | 276 | if (video_is_registered(vdev)) |
| 253 | ret = vdev->fops->ioctl(filp, cmd, arg); | 277 | ret = vdev->fops->ioctl(filp, cmd, arg); |
| 254 | mutex_unlock(&v4l2_ioctl_mutex); | 278 | if (cmd != VIDIOC_DQBUF) |
| 279 | mutex_unlock(m); | ||
| 255 | } else | 280 | } else |
| 256 | ret = -ENOTTY; | 281 | ret = -ENOTTY; |
| 257 | 282 | ||
| @@ -265,8 +290,8 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) | |||
| 265 | 290 | ||
| 266 | if (!vdev->fops->mmap) | 291 | if (!vdev->fops->mmap) |
| 267 | return ret; | 292 | return ret; |
| 268 | if (vdev->lock) | 293 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
| 269 | mutex_lock(vdev->lock); | 294 | return -ERESTARTSYS; |
| 270 | if (video_is_registered(vdev)) | 295 | if (video_is_registered(vdev)) |
| 271 | ret = vdev->fops->mmap(filp, vm); | 296 | ret = vdev->fops->mmap(filp, vm); |
| 272 | if (vdev->lock) | 297 | if (vdev->lock) |
| @@ -284,7 +309,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
| 284 | mutex_lock(&videodev_lock); | 309 | mutex_lock(&videodev_lock); |
| 285 | vdev = video_devdata(filp); | 310 | vdev = video_devdata(filp); |
| 286 | /* return ENODEV if the video device has already been removed. */ | 311 | /* return ENODEV if the video device has already been removed. */ |
| 287 | if (vdev == NULL) { | 312 | if (vdev == NULL || !video_is_registered(vdev)) { |
| 288 | mutex_unlock(&videodev_lock); | 313 | mutex_unlock(&videodev_lock); |
| 289 | return -ENODEV; | 314 | return -ENODEV; |
| 290 | } | 315 | } |
| @@ -292,8 +317,10 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
| 292 | video_get(vdev); | 317 | video_get(vdev); |
| 293 | mutex_unlock(&videodev_lock); | 318 | mutex_unlock(&videodev_lock); |
| 294 | if (vdev->fops->open) { | 319 | if (vdev->fops->open) { |
| 295 | if (vdev->lock) | 320 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) { |
| 296 | mutex_lock(vdev->lock); | 321 | ret = -ERESTARTSYS; |
| 322 | goto err; | ||
| 323 | } | ||
| 297 | if (video_is_registered(vdev)) | 324 | if (video_is_registered(vdev)) |
| 298 | ret = vdev->fops->open(filp); | 325 | ret = vdev->fops->open(filp); |
| 299 | else | 326 | else |
| @@ -302,6 +329,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
| 302 | mutex_unlock(vdev->lock); | 329 | mutex_unlock(vdev->lock); |
| 303 | } | 330 | } |
| 304 | 331 | ||
| 332 | err: | ||
| 305 | /* decrease the refcount in case of an error */ | 333 | /* decrease the refcount in case of an error */ |
| 306 | if (ret) | 334 | if (ret) |
| 307 | video_put(vdev); | 335 | video_put(vdev); |
| @@ -596,7 +624,12 @@ void video_unregister_device(struct video_device *vdev) | |||
| 596 | if (!vdev || !video_is_registered(vdev)) | 624 | if (!vdev || !video_is_registered(vdev)) |
| 597 | return; | 625 | return; |
| 598 | 626 | ||
| 627 | mutex_lock(&videodev_lock); | ||
| 628 | /* This must be in a critical section to prevent a race with v4l2_open. | ||
| 629 | * Once this bit has been cleared video_get may never be called again. | ||
| 630 | */ | ||
| 599 | clear_bit(V4L2_FL_REGISTERED, &vdev->flags); | 631 | clear_bit(V4L2_FL_REGISTERED, &vdev->flags); |
| 632 | mutex_unlock(&videodev_lock); | ||
| 600 | device_unregister(&vdev->dev); | 633 | device_unregister(&vdev->dev); |
| 601 | } | 634 | } |
| 602 | EXPORT_SYMBOL(video_unregister_device); | 635 | EXPORT_SYMBOL(video_unregister_device); |
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c index 0b08f96b74a..7fe6f92af48 100644 --- a/drivers/media/video/v4l2-device.c +++ b/drivers/media/video/v4l2-device.c | |||
| @@ -35,6 +35,7 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) | |||
| 35 | 35 | ||
| 36 | INIT_LIST_HEAD(&v4l2_dev->subdevs); | 36 | INIT_LIST_HEAD(&v4l2_dev->subdevs); |
| 37 | spin_lock_init(&v4l2_dev->lock); | 37 | spin_lock_init(&v4l2_dev->lock); |
| 38 | mutex_init(&v4l2_dev->ioctl_lock); | ||
| 38 | v4l2_dev->dev = dev; | 39 | v4l2_dev->dev = dev; |
| 39 | if (dev == NULL) { | 40 | if (dev == NULL) { |
| 40 | /* If dev == NULL, then name must be filled in by the caller */ | 41 | /* If dev == NULL, then name must be filled in by the caller */ |
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 635420d8d84..019ee206cbe 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c | |||
| @@ -815,7 +815,7 @@ out: | |||
| 815 | 815 | ||
| 816 | static const struct v4l2_file_operations w9966_fops = { | 816 | static const struct v4l2_file_operations w9966_fops = { |
| 817 | .owner = THIS_MODULE, | 817 | .owner = THIS_MODULE, |
| 818 | .ioctl = video_ioctl2, | 818 | .unlocked_ioctl = video_ioctl2, |
| 819 | .read = w9966_v4l_read, | 819 | .read = w9966_v4l_read, |
| 820 | }; | 820 | }; |
| 821 | 821 | ||
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index dd90880048c..d8ae634d347 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c | |||
| @@ -51,7 +51,7 @@ struct pxa2xx_flash_info { | |||
| 51 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; | 51 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; |
| 52 | 52 | ||
| 53 | 53 | ||
| 54 | static int __init pxa2xx_flash_probe(struct platform_device *pdev) | 54 | static int __devinit pxa2xx_flash_probe(struct platform_device *pdev) |
| 55 | { | 55 | { |
| 56 | struct flash_platform_data *flash = pdev->dev.platform_data; | 56 | struct flash_platform_data *flash = pdev->dev.platform_data; |
| 57 | struct pxa2xx_flash_info *info; | 57 | struct pxa2xx_flash_info *info; |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index cd41c58b5bb..15682ec8530 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
| @@ -7,7 +7,6 @@ | |||
| 7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
| 8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
| 9 | */ | 9 | */ |
| 10 | #define CONFIG_MTD_NAND_OMAP_HWECC | ||
| 11 | 10 | ||
| 12 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
| 13 | #include <linux/dma-mapping.h> | 12 | #include <linux/dma-mapping.h> |
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index c6e86315b3f..2e2b76258ab 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
| @@ -381,11 +381,11 @@ static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote) | |||
| 381 | __b44_set_flow_ctrl(bp, pause_enab); | 381 | __b44_set_flow_ctrl(bp, pause_enab); |
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | #ifdef SSB_DRIVER_MIPS | 384 | #ifdef CONFIG_BCM47XX |
| 385 | extern char *nvram_get(char *name); | 385 | #include <asm/mach-bcm47xx/nvram.h> |
| 386 | static void b44_wap54g10_workaround(struct b44 *bp) | 386 | static void b44_wap54g10_workaround(struct b44 *bp) |
| 387 | { | 387 | { |
| 388 | const char *str; | 388 | char buf[20]; |
| 389 | u32 val; | 389 | u32 val; |
| 390 | int err; | 390 | int err; |
| 391 | 391 | ||
| @@ -394,10 +394,9 @@ static void b44_wap54g10_workaround(struct b44 *bp) | |||
| 394 | * see https://dev.openwrt.org/ticket/146 | 394 | * see https://dev.openwrt.org/ticket/146 |
| 395 | * check and reset bit "isolate" | 395 | * check and reset bit "isolate" |
| 396 | */ | 396 | */ |
| 397 | str = nvram_get("boardnum"); | 397 | if (nvram_getenv("boardnum", buf, sizeof(buf)) < 0) |
| 398 | if (!str) | ||
| 399 | return; | 398 | return; |
| 400 | if (simple_strtoul(str, NULL, 0) == 2) { | 399 | if (simple_strtoul(buf, NULL, 0) == 2) { |
| 401 | err = __b44_readphy(bp, 0, MII_BMCR, &val); | 400 | err = __b44_readphy(bp, 0, MII_BMCR, &val); |
| 402 | if (err) | 401 | if (err) |
| 403 | goto error; | 402 | goto error; |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 36eca1ce75d..e4465d222a7 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
| @@ -1235,7 +1235,7 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, | |||
| 1235 | 1235 | ||
| 1236 | i = 0; | 1236 | i = 0; |
| 1237 | netdev_for_each_mc_addr(ha, netdev) | 1237 | netdev_for_each_mc_addr(ha, netdev) |
| 1238 | memcpy(req->mac[i].byte, ha->addr, ETH_ALEN); | 1238 | memcpy(req->mac[i++].byte, ha->addr, ETH_ALEN); |
| 1239 | } else { | 1239 | } else { |
| 1240 | req->promiscuous = 1; | 1240 | req->promiscuous = 1; |
| 1241 | } | 1241 | } |
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 863e73a85fb..d255428122f 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
| @@ -20,8 +20,8 @@ | |||
| 20 | * (you will need to reboot afterwards) */ | 20 | * (you will need to reboot afterwards) */ |
| 21 | /* #define BNX2X_STOP_ON_ERROR */ | 21 | /* #define BNX2X_STOP_ON_ERROR */ |
| 22 | 22 | ||
| 23 | #define DRV_MODULE_VERSION "1.60.00-4" | 23 | #define DRV_MODULE_VERSION "1.60.01-0" |
| 24 | #define DRV_MODULE_RELDATE "2010/11/01" | 24 | #define DRV_MODULE_RELDATE "2010/11/12" |
| 25 | #define BNX2X_BC_VER 0x040200 | 25 | #define BNX2X_BC_VER 0x040200 |
| 26 | 26 | ||
| 27 | #define BNX2X_MULTI_QUEUE | 27 | #define BNX2X_MULTI_QUEUE |
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 94d5f59d5a6..0af361e4e3d 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c | |||
| @@ -1782,15 +1782,15 @@ exit_lbl: | |||
| 1782 | } | 1782 | } |
| 1783 | #endif | 1783 | #endif |
| 1784 | 1784 | ||
| 1785 | static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, | 1785 | static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data, |
| 1786 | struct eth_tx_parse_bd_e2 *pbd, | 1786 | u32 xmit_type) |
| 1787 | u32 xmit_type) | ||
| 1788 | { | 1787 | { |
| 1789 | pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) << | 1788 | *parsing_data |= (skb_shinfo(skb)->gso_size << |
| 1790 | ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT; | 1789 | ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) & |
| 1790 | ETH_TX_PARSE_BD_E2_LSO_MSS; | ||
| 1791 | if ((xmit_type & XMIT_GSO_V6) && | 1791 | if ((xmit_type & XMIT_GSO_V6) && |
| 1792 | (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6)) | 1792 | (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6)) |
| 1793 | pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; | 1793 | *parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; |
| 1794 | } | 1794 | } |
| 1795 | 1795 | ||
| 1796 | /** | 1796 | /** |
| @@ -1835,15 +1835,15 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, | |||
| 1835 | * @return header len | 1835 | * @return header len |
| 1836 | */ | 1836 | */ |
| 1837 | static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, | 1837 | static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, |
| 1838 | struct eth_tx_parse_bd_e2 *pbd, | 1838 | u32 *parsing_data, u32 xmit_type) |
| 1839 | u32 xmit_type) | ||
| 1840 | { | 1839 | { |
| 1841 | pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) << | 1840 | *parsing_data |= ((tcp_hdrlen(skb)/4) << |
| 1842 | ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT; | 1841 | ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) & |
| 1842 | ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW; | ||
| 1843 | 1843 | ||
| 1844 | pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) - | 1844 | *parsing_data |= ((((u8 *)tcp_hdr(skb) - skb->data) / 2) << |
| 1845 | skb->data) / 2) << | 1845 | ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) & |
| 1846 | ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT; | 1846 | ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W; |
| 1847 | 1847 | ||
| 1848 | return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; | 1848 | return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; |
| 1849 | } | 1849 | } |
| @@ -1912,6 +1912,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1912 | struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; | 1912 | struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; |
| 1913 | struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; | 1913 | struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; |
| 1914 | struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; | 1914 | struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; |
| 1915 | u32 pbd_e2_parsing_data = 0; | ||
| 1915 | u16 pkt_prod, bd_prod; | 1916 | u16 pkt_prod, bd_prod; |
| 1916 | int nbd, fp_index; | 1917 | int nbd, fp_index; |
| 1917 | dma_addr_t mapping; | 1918 | dma_addr_t mapping; |
| @@ -2033,8 +2034,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 2033 | memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); | 2034 | memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); |
| 2034 | /* Set PBD in checksum offload case */ | 2035 | /* Set PBD in checksum offload case */ |
| 2035 | if (xmit_type & XMIT_CSUM) | 2036 | if (xmit_type & XMIT_CSUM) |
| 2036 | hlen = bnx2x_set_pbd_csum_e2(bp, | 2037 | hlen = bnx2x_set_pbd_csum_e2(bp, skb, |
| 2037 | skb, pbd_e2, xmit_type); | 2038 | &pbd_e2_parsing_data, |
| 2039 | xmit_type); | ||
| 2038 | } else { | 2040 | } else { |
| 2039 | pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; | 2041 | pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; |
| 2040 | memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); | 2042 | memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); |
| @@ -2076,10 +2078,18 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 2076 | bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, | 2078 | bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, |
| 2077 | hlen, bd_prod, ++nbd); | 2079 | hlen, bd_prod, ++nbd); |
| 2078 | if (CHIP_IS_E2(bp)) | 2080 | if (CHIP_IS_E2(bp)) |
| 2079 | bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type); | 2081 | bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data, |
| 2082 | xmit_type); | ||
| 2080 | else | 2083 | else |
| 2081 | bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type); | 2084 | bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type); |
| 2082 | } | 2085 | } |
| 2086 | |||
| 2087 | /* Set the PBD's parsing_data field if not zero | ||
| 2088 | * (for the chips newer than 57711). | ||
| 2089 | */ | ||
| 2090 | if (pbd_e2_parsing_data) | ||
| 2091 | pbd_e2->parsing_data = cpu_to_le32(pbd_e2_parsing_data); | ||
| 2092 | |||
| 2083 | tx_data_bd = (struct eth_tx_bd *)tx_start_bd; | 2093 | tx_data_bd = (struct eth_tx_bd *)tx_start_bd; |
| 2084 | 2094 | ||
| 2085 | /* Handle fragmented skb */ | 2095 | /* Handle fragmented skb */ |
diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h index a306b0e46b6..66df29fcf75 100644 --- a/drivers/net/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/bnx2x/bnx2x_init_ops.h | |||
| @@ -838,7 +838,7 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count, | |||
| 838 | /**************************************************************************** | 838 | /**************************************************************************** |
| 839 | * SRC initializations | 839 | * SRC initializations |
| 840 | ****************************************************************************/ | 840 | ****************************************************************************/ |
| 841 | 841 | #ifdef BCM_CNIC | |
| 842 | /* called during init func stage */ | 842 | /* called during init func stage */ |
| 843 | static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, | 843 | static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, |
| 844 | dma_addr_t t2_mapping, int src_cid_count) | 844 | dma_addr_t t2_mapping, int src_cid_count) |
| @@ -862,5 +862,5 @@ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, | |||
| 862 | U64_HI((u64)t2_mapping + | 862 | U64_HI((u64)t2_mapping + |
| 863 | (src_cid_count-1) * sizeof(struct src_ent))); | 863 | (src_cid_count-1) * sizeof(struct src_ent))); |
| 864 | } | 864 | } |
| 865 | 865 | #endif | |
| 866 | #endif /* BNX2X_INIT_OPS_H */ | 866 | #endif /* BNX2X_INIT_OPS_H */ |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 71a169740d0..d0ea760ce41 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -171,7 +171,7 @@ MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link | |||
| 171 | /*----------------------------- Global variables ----------------------------*/ | 171 | /*----------------------------- Global variables ----------------------------*/ |
| 172 | 172 | ||
| 173 | #ifdef CONFIG_NET_POLL_CONTROLLER | 173 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 174 | cpumask_var_t netpoll_block_tx; | 174 | atomic_t netpoll_block_tx = ATOMIC_INIT(0); |
| 175 | #endif | 175 | #endif |
| 176 | 176 | ||
| 177 | static const char * const version = | 177 | static const char * const version = |
| @@ -1576,7 +1576,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1576 | 1576 | ||
| 1577 | /* If this is the first slave, then we need to set the master's hardware | 1577 | /* If this is the first slave, then we need to set the master's hardware |
| 1578 | * address to be the same as the slave's. */ | 1578 | * address to be the same as the slave's. */ |
| 1579 | if (bond->slave_cnt == 0) | 1579 | if (is_zero_ether_addr(bond->dev->dev_addr)) |
| 1580 | memcpy(bond->dev->dev_addr, slave_dev->dev_addr, | 1580 | memcpy(bond->dev->dev_addr, slave_dev->dev_addr, |
| 1581 | slave_dev->addr_len); | 1581 | slave_dev->addr_len); |
| 1582 | 1582 | ||
| @@ -5299,13 +5299,6 @@ static int __init bonding_init(void) | |||
| 5299 | if (res) | 5299 | if (res) |
| 5300 | goto out; | 5300 | goto out; |
| 5301 | 5301 | ||
| 5302 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 5303 | if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) { | ||
| 5304 | res = -ENOMEM; | ||
| 5305 | goto out; | ||
| 5306 | } | ||
| 5307 | #endif | ||
| 5308 | |||
| 5309 | res = register_pernet_subsys(&bond_net_ops); | 5302 | res = register_pernet_subsys(&bond_net_ops); |
| 5310 | if (res) | 5303 | if (res) |
| 5311 | goto out; | 5304 | goto out; |
| @@ -5334,9 +5327,6 @@ err: | |||
| 5334 | rtnl_link_unregister(&bond_link_ops); | 5327 | rtnl_link_unregister(&bond_link_ops); |
| 5335 | err_link: | 5328 | err_link: |
| 5336 | unregister_pernet_subsys(&bond_net_ops); | 5329 | unregister_pernet_subsys(&bond_net_ops); |
| 5337 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 5338 | free_cpumask_var(netpoll_block_tx); | ||
| 5339 | #endif | ||
| 5340 | goto out; | 5330 | goto out; |
| 5341 | 5331 | ||
| 5342 | } | 5332 | } |
| @@ -5353,7 +5343,10 @@ static void __exit bonding_exit(void) | |||
| 5353 | unregister_pernet_subsys(&bond_net_ops); | 5343 | unregister_pernet_subsys(&bond_net_ops); |
| 5354 | 5344 | ||
| 5355 | #ifdef CONFIG_NET_POLL_CONTROLLER | 5345 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 5356 | free_cpumask_var(netpoll_block_tx); | 5346 | /* |
| 5347 | * Make sure we don't have an imbalance on our netpoll blocking | ||
| 5348 | */ | ||
| 5349 | WARN_ON(atomic_read(&netpoll_block_tx)); | ||
| 5357 | #endif | 5350 | #endif |
| 5358 | } | 5351 | } |
| 5359 | 5352 | ||
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 4eedb12df6c..c2f081352a0 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
| @@ -119,26 +119,22 @@ | |||
| 119 | 119 | ||
| 120 | 120 | ||
| 121 | #ifdef CONFIG_NET_POLL_CONTROLLER | 121 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 122 | extern cpumask_var_t netpoll_block_tx; | 122 | extern atomic_t netpoll_block_tx; |
| 123 | 123 | ||
| 124 | static inline void block_netpoll_tx(void) | 124 | static inline void block_netpoll_tx(void) |
| 125 | { | 125 | { |
| 126 | preempt_disable(); | 126 | atomic_inc(&netpoll_block_tx); |
| 127 | BUG_ON(cpumask_test_and_set_cpu(smp_processor_id(), | ||
| 128 | netpoll_block_tx)); | ||
| 129 | } | 127 | } |
| 130 | 128 | ||
| 131 | static inline void unblock_netpoll_tx(void) | 129 | static inline void unblock_netpoll_tx(void) |
| 132 | { | 130 | { |
| 133 | BUG_ON(!cpumask_test_and_clear_cpu(smp_processor_id(), | 131 | atomic_dec(&netpoll_block_tx); |
| 134 | netpoll_block_tx)); | ||
| 135 | preempt_enable(); | ||
| 136 | } | 132 | } |
| 137 | 133 | ||
| 138 | static inline int is_netpoll_tx_blocked(struct net_device *dev) | 134 | static inline int is_netpoll_tx_blocked(struct net_device *dev) |
| 139 | { | 135 | { |
| 140 | if (unlikely(dev->priv_flags & IFF_IN_NETPOLL)) | 136 | if (unlikely(dev->priv_flags & IFF_IN_NETPOLL)) |
| 141 | return cpumask_test_cpu(smp_processor_id(), netpoll_block_tx); | 137 | return atomic_read(&netpoll_block_tx); |
| 142 | return 0; | 138 | return 0; |
| 143 | } | 139 | } |
| 144 | #else | 140 | #else |
diff --git a/drivers/net/caif/caif_shm_u5500.c b/drivers/net/caif/caif_shm_u5500.c index 1cd90da86f1..32b1c6fb2de 100644 --- a/drivers/net/caif/caif_shm_u5500.c +++ b/drivers/net/caif/caif_shm_u5500.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * License terms: GNU General Public License (GPL) version 2 | 5 | * License terms: GNU General Public License (GPL) version 2 |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ":" fmt |
| 9 | 9 | ||
| 10 | #include <linux/version.h> | 10 | #include <linux/version.h> |
| 11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
diff --git a/drivers/net/caif/caif_shmcore.c b/drivers/net/caif/caif_shmcore.c index 19f9c065666..80511167f35 100644 --- a/drivers/net/caif/caif_shmcore.c +++ b/drivers/net/caif/caif_shmcore.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * License terms: GNU General Public License (GPL) version 2 | 6 | * License terms: GNU General Public License (GPL) version 2 |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt | 9 | #define pr_fmt(fmt) KBUILD_MODNAME ":" fmt |
| 10 | 10 | ||
| 11 | #include <linux/spinlock.h> | 11 | #include <linux/spinlock.h> |
| 12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c index bb813d94aea..e97521c801e 100644 --- a/drivers/net/cxgb4/t4_hw.c +++ b/drivers/net/cxgb4/t4_hw.c | |||
| @@ -2408,7 +2408,7 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, | |||
| 2408 | if (index < NEXACT_MAC) | 2408 | if (index < NEXACT_MAC) |
| 2409 | ret++; | 2409 | ret++; |
| 2410 | else if (hash) | 2410 | else if (hash) |
| 2411 | *hash |= (1 << hash_mac_addr(addr[i])); | 2411 | *hash |= (1ULL << hash_mac_addr(addr[i])); |
| 2412 | } | 2412 | } |
| 2413 | return ret; | 2413 | return ret; |
| 2414 | } | 2414 | } |
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index d887a76cd39..6bf464afa90 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c | |||
| @@ -2269,6 +2269,7 @@ static void __devinit cfg_queues(struct adapter *adapter) | |||
| 2269 | { | 2269 | { |
| 2270 | struct sge *s = &adapter->sge; | 2270 | struct sge *s = &adapter->sge; |
| 2271 | int q10g, n10g, qidx, pidx, qs; | 2271 | int q10g, n10g, qidx, pidx, qs; |
| 2272 | size_t iqe_size; | ||
| 2272 | 2273 | ||
| 2273 | /* | 2274 | /* |
| 2274 | * We should not be called till we know how many Queue Sets we can | 2275 | * We should not be called till we know how many Queue Sets we can |
| @@ -2313,6 +2314,13 @@ static void __devinit cfg_queues(struct adapter *adapter) | |||
| 2313 | s->ethqsets = qidx; | 2314 | s->ethqsets = qidx; |
| 2314 | 2315 | ||
| 2315 | /* | 2316 | /* |
| 2317 | * The Ingress Queue Entry Size for our various Response Queues needs | ||
| 2318 | * to be big enough to accommodate the largest message we can receive | ||
| 2319 | * from the chip/firmware; which is 64 bytes ... | ||
| 2320 | */ | ||
| 2321 | iqe_size = 64; | ||
| 2322 | |||
| 2323 | /* | ||
| 2316 | * Set up default Queue Set parameters ... Start off with the | 2324 | * Set up default Queue Set parameters ... Start off with the |
| 2317 | * shortest interrupt holdoff timer. | 2325 | * shortest interrupt holdoff timer. |
| 2318 | */ | 2326 | */ |
| @@ -2320,7 +2328,7 @@ static void __devinit cfg_queues(struct adapter *adapter) | |||
| 2320 | struct sge_eth_rxq *rxq = &s->ethrxq[qs]; | 2328 | struct sge_eth_rxq *rxq = &s->ethrxq[qs]; |
| 2321 | struct sge_eth_txq *txq = &s->ethtxq[qs]; | 2329 | struct sge_eth_txq *txq = &s->ethtxq[qs]; |
| 2322 | 2330 | ||
| 2323 | init_rspq(&rxq->rspq, 0, 0, 1024, L1_CACHE_BYTES); | 2331 | init_rspq(&rxq->rspq, 0, 0, 1024, iqe_size); |
| 2324 | rxq->fl.size = 72; | 2332 | rxq->fl.size = 72; |
| 2325 | txq->q.size = 1024; | 2333 | txq->q.size = 1024; |
| 2326 | } | 2334 | } |
| @@ -2329,8 +2337,7 @@ static void __devinit cfg_queues(struct adapter *adapter) | |||
| 2329 | * The firmware event queue is used for link state changes and | 2337 | * The firmware event queue is used for link state changes and |
| 2330 | * notifications of TX DMA completions. | 2338 | * notifications of TX DMA completions. |
| 2331 | */ | 2339 | */ |
| 2332 | init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512, | 2340 | init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512, iqe_size); |
| 2333 | L1_CACHE_BYTES); | ||
| 2334 | 2341 | ||
| 2335 | /* | 2342 | /* |
| 2336 | * The forwarded interrupt queue is used when we're in MSI interrupt | 2343 | * The forwarded interrupt queue is used when we're in MSI interrupt |
| @@ -2346,7 +2353,7 @@ static void __devinit cfg_queues(struct adapter *adapter) | |||
| 2346 | * any time ... | 2353 | * any time ... |
| 2347 | */ | 2354 | */ |
| 2348 | init_rspq(&s->intrq, SGE_TIMER_RSTRT_CNTR, 0, MSIX_ENTRIES + 1, | 2355 | init_rspq(&s->intrq, SGE_TIMER_RSTRT_CNTR, 0, MSIX_ENTRIES + 1, |
| 2349 | L1_CACHE_BYTES); | 2356 | iqe_size); |
| 2350 | } | 2357 | } |
| 2351 | 2358 | ||
| 2352 | /* | 2359 | /* |
diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c index 75b099ce49c..1f37ee6b2a2 100644 --- a/drivers/net/ehea/ehea_ethtool.c +++ b/drivers/net/ehea/ehea_ethtool.c | |||
| @@ -261,6 +261,13 @@ static void ehea_get_ethtool_stats(struct net_device *dev, | |||
| 261 | 261 | ||
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | static int ehea_set_flags(struct net_device *dev, u32 data) | ||
| 265 | { | ||
| 266 | return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO | ||
| 267 | | ETH_FLAG_TXVLAN | ||
| 268 | | ETH_FLAG_RXVLAN); | ||
| 269 | } | ||
| 270 | |||
| 264 | const struct ethtool_ops ehea_ethtool_ops = { | 271 | const struct ethtool_ops ehea_ethtool_ops = { |
| 265 | .get_settings = ehea_get_settings, | 272 | .get_settings = ehea_get_settings, |
| 266 | .get_drvinfo = ehea_get_drvinfo, | 273 | .get_drvinfo = ehea_get_drvinfo, |
| @@ -273,6 +280,8 @@ const struct ethtool_ops ehea_ethtool_ops = { | |||
| 273 | .get_ethtool_stats = ehea_get_ethtool_stats, | 280 | .get_ethtool_stats = ehea_get_ethtool_stats, |
| 274 | .get_rx_csum = ehea_get_rx_csum, | 281 | .get_rx_csum = ehea_get_rx_csum, |
| 275 | .set_settings = ehea_set_settings, | 282 | .set_settings = ehea_set_settings, |
| 283 | .get_flags = ethtool_op_get_flags, | ||
| 284 | .set_flags = ehea_set_flags, | ||
| 276 | .nway_reset = ehea_nway_reset, /* Restart autonegotiation */ | 285 | .nway_reset = ehea_nway_reset, /* Restart autonegotiation */ |
| 277 | }; | 286 | }; |
| 278 | 287 | ||
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 3d0af08483a..b95f087cd5a 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
| @@ -683,7 +683,7 @@ static void ehea_proc_skb(struct ehea_port_res *pr, struct ehea_cqe *cqe, | |||
| 683 | int vlan_extracted = ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) && | 683 | int vlan_extracted = ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) && |
| 684 | pr->port->vgrp); | 684 | pr->port->vgrp); |
| 685 | 685 | ||
| 686 | if (use_lro) { | 686 | if (skb->dev->features & NETIF_F_LRO) { |
| 687 | if (vlan_extracted) | 687 | if (vlan_extracted) |
| 688 | lro_vlan_hwaccel_receive_skb(&pr->lro_mgr, skb, | 688 | lro_vlan_hwaccel_receive_skb(&pr->lro_mgr, skb, |
| 689 | pr->port->vgrp, | 689 | pr->port->vgrp, |
| @@ -787,7 +787,7 @@ static int ehea_proc_rwqes(struct net_device *dev, | |||
| 787 | } | 787 | } |
| 788 | cqe = ehea_poll_rq1(qp, &wqe_index); | 788 | cqe = ehea_poll_rq1(qp, &wqe_index); |
| 789 | } | 789 | } |
| 790 | if (use_lro) | 790 | if (dev->features & NETIF_F_LRO) |
| 791 | lro_flush_all(&pr->lro_mgr); | 791 | lro_flush_all(&pr->lro_mgr); |
| 792 | 792 | ||
| 793 | pr->rx_packets += processed; | 793 | pr->rx_packets += processed; |
| @@ -3278,6 +3278,9 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, | |||
| 3278 | | NETIF_F_LLTX; | 3278 | | NETIF_F_LLTX; |
| 3279 | dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; | 3279 | dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; |
| 3280 | 3280 | ||
| 3281 | if (use_lro) | ||
| 3282 | dev->features |= NETIF_F_LRO; | ||
| 3283 | |||
| 3281 | INIT_WORK(&port->reset_task, ehea_reset_port); | 3284 | INIT_WORK(&port->reset_task, ehea_reset_port); |
| 3282 | 3285 | ||
| 3283 | ret = register_netdev(dev); | 3286 | ret = register_netdev(dev); |
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index a466ef91dd4..aa28b270c04 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c | |||
| @@ -1962,7 +1962,8 @@ static void enic_poll_controller(struct net_device *netdev) | |||
| 1962 | case VNIC_DEV_INTR_MODE_MSIX: | 1962 | case VNIC_DEV_INTR_MODE_MSIX: |
| 1963 | for (i = 0; i < enic->rq_count; i++) { | 1963 | for (i = 0; i < enic->rq_count; i++) { |
| 1964 | intr = enic_msix_rq_intr(enic, i); | 1964 | intr = enic_msix_rq_intr(enic, i); |
| 1965 | enic_isr_msix_rq(enic->msix_entry[intr].vector, enic); | 1965 | enic_isr_msix_rq(enic->msix_entry[intr].vector, |
| 1966 | &enic->napi[i]); | ||
| 1966 | } | 1967 | } |
| 1967 | intr = enic_msix_wq_intr(enic, i); | 1968 | intr = enic_msix_wq_intr(enic, i); |
| 1968 | enic_isr_msix_wq(enic->msix_entry[intr].vector, enic); | 1969 | enic_isr_msix_wq(enic->msix_entry[intr].vector, enic); |
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index ab9f675c5b8..fe337bd121a 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c | |||
| @@ -104,6 +104,8 @@ static void ri_tasklet(unsigned long dev) | |||
| 104 | rcu_read_unlock(); | 104 | rcu_read_unlock(); |
| 105 | dev_kfree_skb(skb); | 105 | dev_kfree_skb(skb); |
| 106 | stats->tx_dropped++; | 106 | stats->tx_dropped++; |
| 107 | if (skb_queue_len(&dp->tq) != 0) | ||
| 108 | goto resched; | ||
| 107 | break; | 109 | break; |
| 108 | } | 110 | } |
| 109 | rcu_read_unlock(); | 111 | rcu_read_unlock(); |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fbad4d81960..eee0b298bd3 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
| @@ -4771,6 +4771,9 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter) | |||
| 4771 | adapter->rx_ring[i] = NULL; | 4771 | adapter->rx_ring[i] = NULL; |
| 4772 | } | 4772 | } |
| 4773 | 4773 | ||
| 4774 | adapter->num_tx_queues = 0; | ||
| 4775 | adapter->num_rx_queues = 0; | ||
| 4776 | |||
| 4774 | ixgbe_free_q_vectors(adapter); | 4777 | ixgbe_free_q_vectors(adapter); |
| 4775 | ixgbe_reset_interrupt_capability(adapter); | 4778 | ixgbe_reset_interrupt_capability(adapter); |
| 4776 | } | 4779 | } |
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index cb3d13e4e07..35fda5ac812 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig | |||
| @@ -64,7 +64,7 @@ config BCM63XX_PHY | |||
| 64 | config ICPLUS_PHY | 64 | config ICPLUS_PHY |
| 65 | tristate "Drivers for ICPlus PHYs" | 65 | tristate "Drivers for ICPlus PHYs" |
| 66 | ---help--- | 66 | ---help--- |
| 67 | Currently supports the IP175C PHY. | 67 | Currently supports the IP175C and IP1001 PHYs. |
| 68 | 68 | ||
| 69 | config REALTEK_PHY | 69 | config REALTEK_PHY |
| 70 | tristate "Drivers for Realtek PHYs" | 70 | tristate "Drivers for Realtek PHYs" |
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index c1d2d251fe8..9a09e24c30b 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | #include <asm/irq.h> | 30 | #include <asm/irq.h> |
| 31 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
| 32 | 32 | ||
| 33 | MODULE_DESCRIPTION("ICPlus IP175C PHY driver"); | 33 | MODULE_DESCRIPTION("ICPlus IP175C/IC1001 PHY drivers"); |
| 34 | MODULE_AUTHOR("Michael Barkowski"); | 34 | MODULE_AUTHOR("Michael Barkowski"); |
| 35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
| 36 | 36 | ||
| @@ -89,6 +89,33 @@ static int ip175c_config_init(struct phy_device *phydev) | |||
| 89 | return 0; | 89 | return 0; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | static int ip1001_config_init(struct phy_device *phydev) | ||
| 93 | { | ||
| 94 | int err, value; | ||
| 95 | |||
| 96 | /* Software Reset PHY */ | ||
| 97 | value = phy_read(phydev, MII_BMCR); | ||
| 98 | value |= BMCR_RESET; | ||
| 99 | err = phy_write(phydev, MII_BMCR, value); | ||
| 100 | if (err < 0) | ||
| 101 | return err; | ||
| 102 | |||
| 103 | do { | ||
| 104 | value = phy_read(phydev, MII_BMCR); | ||
| 105 | } while (value & BMCR_RESET); | ||
| 106 | |||
| 107 | /* Additional delay (2ns) used to adjust RX clock phase | ||
| 108 | * at GMII/ RGMII interface */ | ||
| 109 | value = phy_read(phydev, 16); | ||
| 110 | value |= 0x3; | ||
| 111 | |||
| 112 | err = phy_write(phydev, 16, value); | ||
| 113 | if (err < 0) | ||
| 114 | return err; | ||
| 115 | |||
| 116 | return err; | ||
| 117 | } | ||
| 118 | |||
| 92 | static int ip175c_read_status(struct phy_device *phydev) | 119 | static int ip175c_read_status(struct phy_device *phydev) |
| 93 | { | 120 | { |
| 94 | if (phydev->addr == 4) /* WAN port */ | 121 | if (phydev->addr == 4) /* WAN port */ |
| @@ -121,21 +148,43 @@ static struct phy_driver ip175c_driver = { | |||
| 121 | .driver = { .owner = THIS_MODULE,}, | 148 | .driver = { .owner = THIS_MODULE,}, |
| 122 | }; | 149 | }; |
| 123 | 150 | ||
| 124 | static int __init ip175c_init(void) | 151 | static struct phy_driver ip1001_driver = { |
| 152 | .phy_id = 0x02430d90, | ||
| 153 | .name = "ICPlus IP1001", | ||
| 154 | .phy_id_mask = 0x0ffffff0, | ||
| 155 | .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | | ||
| 156 | SUPPORTED_Asym_Pause, | ||
| 157 | .config_init = &ip1001_config_init, | ||
| 158 | .config_aneg = &genphy_config_aneg, | ||
| 159 | .read_status = &genphy_read_status, | ||
| 160 | .suspend = genphy_suspend, | ||
| 161 | .resume = genphy_resume, | ||
| 162 | .driver = { .owner = THIS_MODULE,}, | ||
| 163 | }; | ||
| 164 | |||
| 165 | static int __init icplus_init(void) | ||
| 125 | { | 166 | { |
| 167 | int ret = 0; | ||
| 168 | |||
| 169 | ret = phy_driver_register(&ip1001_driver); | ||
| 170 | if (ret < 0) | ||
| 171 | return -ENODEV; | ||
| 172 | |||
| 126 | return phy_driver_register(&ip175c_driver); | 173 | return phy_driver_register(&ip175c_driver); |
| 127 | } | 174 | } |
| 128 | 175 | ||
| 129 | static void __exit ip175c_exit(void) | 176 | static void __exit icplus_exit(void) |
| 130 | { | 177 | { |
| 178 | phy_driver_unregister(&ip1001_driver); | ||
| 131 | phy_driver_unregister(&ip175c_driver); | 179 | phy_driver_unregister(&ip175c_driver); |
| 132 | } | 180 | } |
| 133 | 181 | ||
| 134 | module_init(ip175c_init); | 182 | module_init(icplus_init); |
| 135 | module_exit(ip175c_exit); | 183 | module_exit(icplus_exit); |
| 136 | 184 | ||
| 137 | static struct mdio_device_id __maybe_unused icplus_tbl[] = { | 185 | static struct mdio_device_id __maybe_unused icplus_tbl[] = { |
| 138 | { 0x02430d80, 0x0ffffff0 }, | 186 | { 0x02430d80, 0x0ffffff0 }, |
| 187 | { 0x02430d90, 0x0ffffff0 }, | ||
| 139 | { } | 188 | { } |
| 140 | }; | 189 | }; |
| 141 | 190 | ||
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index d72fb0519a2..78c0e3c9b2b 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c | |||
| @@ -948,7 +948,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb) | |||
| 948 | 948 | ||
| 949 | abort: | 949 | abort: |
| 950 | kfree_skb(skb); | 950 | kfree_skb(skb); |
| 951 | return 0; | 951 | return 1; |
| 952 | } | 952 | } |
| 953 | 953 | ||
| 954 | /************************************************************************ | 954 | /************************************************************************ |
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 22821398fc6..9787dff90d3 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h | |||
| @@ -2083,6 +2083,7 @@ struct ql_adapter { | |||
| 2083 | u32 mailbox_in; | 2083 | u32 mailbox_in; |
| 2084 | u32 mailbox_out; | 2084 | u32 mailbox_out; |
| 2085 | struct mbox_params idc_mbc; | 2085 | struct mbox_params idc_mbc; |
| 2086 | struct mutex mpi_mutex; | ||
| 2086 | 2087 | ||
| 2087 | int tx_ring_size; | 2088 | int tx_ring_size; |
| 2088 | int rx_ring_size; | 2089 | int rx_ring_size; |
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 528eaef5308..2555b1d34f3 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
| @@ -4629,6 +4629,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev, | |||
| 4629 | INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work); | 4629 | INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work); |
| 4630 | INIT_DELAYED_WORK(&qdev->mpi_core_to_log, ql_mpi_core_to_log); | 4630 | INIT_DELAYED_WORK(&qdev->mpi_core_to_log, ql_mpi_core_to_log); |
| 4631 | init_completion(&qdev->ide_completion); | 4631 | init_completion(&qdev->ide_completion); |
| 4632 | mutex_init(&qdev->mpi_mutex); | ||
| 4632 | 4633 | ||
| 4633 | if (!cards_found) { | 4634 | if (!cards_found) { |
| 4634 | dev_info(&pdev->dev, "%s\n", DRV_STRING); | 4635 | dev_info(&pdev->dev, "%s\n", DRV_STRING); |
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c index 0e7c7c7ee16..a2e919bcb3c 100644 --- a/drivers/net/qlge/qlge_mpi.c +++ b/drivers/net/qlge/qlge_mpi.c | |||
| @@ -534,6 +534,7 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) | |||
| 534 | int status; | 534 | int status; |
| 535 | unsigned long count; | 535 | unsigned long count; |
| 536 | 536 | ||
| 537 | mutex_lock(&qdev->mpi_mutex); | ||
| 537 | 538 | ||
| 538 | /* Begin polled mode for MPI */ | 539 | /* Begin polled mode for MPI */ |
| 539 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); | 540 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); |
| @@ -603,6 +604,7 @@ done: | |||
| 603 | end: | 604 | end: |
| 604 | /* End polled mode for MPI */ | 605 | /* End polled mode for MPI */ |
| 605 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); | 606 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); |
| 607 | mutex_unlock(&qdev->mpi_mutex); | ||
| 606 | return status; | 608 | return status; |
| 607 | } | 609 | } |
| 608 | 610 | ||
| @@ -1099,9 +1101,7 @@ int ql_wait_fifo_empty(struct ql_adapter *qdev) | |||
| 1099 | static int ql_set_port_cfg(struct ql_adapter *qdev) | 1101 | static int ql_set_port_cfg(struct ql_adapter *qdev) |
| 1100 | { | 1102 | { |
| 1101 | int status; | 1103 | int status; |
| 1102 | rtnl_lock(); | ||
| 1103 | status = ql_mb_set_port_cfg(qdev); | 1104 | status = ql_mb_set_port_cfg(qdev); |
| 1104 | rtnl_unlock(); | ||
| 1105 | if (status) | 1105 | if (status) |
| 1106 | return status; | 1106 | return status; |
| 1107 | status = ql_idc_wait(qdev); | 1107 | status = ql_idc_wait(qdev); |
| @@ -1122,9 +1122,7 @@ void ql_mpi_port_cfg_work(struct work_struct *work) | |||
| 1122 | container_of(work, struct ql_adapter, mpi_port_cfg_work.work); | 1122 | container_of(work, struct ql_adapter, mpi_port_cfg_work.work); |
| 1123 | int status; | 1123 | int status; |
| 1124 | 1124 | ||
| 1125 | rtnl_lock(); | ||
| 1126 | status = ql_mb_get_port_cfg(qdev); | 1125 | status = ql_mb_get_port_cfg(qdev); |
| 1127 | rtnl_unlock(); | ||
| 1128 | if (status) { | 1126 | if (status) { |
| 1129 | netif_err(qdev, drv, qdev->ndev, | 1127 | netif_err(qdev, drv, qdev->ndev, |
| 1130 | "Bug: Failed to get port config data.\n"); | 1128 | "Bug: Failed to get port config data.\n"); |
| @@ -1167,7 +1165,6 @@ void ql_mpi_idc_work(struct work_struct *work) | |||
| 1167 | u32 aen; | 1165 | u32 aen; |
| 1168 | int timeout; | 1166 | int timeout; |
| 1169 | 1167 | ||
| 1170 | rtnl_lock(); | ||
| 1171 | aen = mbcp->mbox_out[1] >> 16; | 1168 | aen = mbcp->mbox_out[1] >> 16; |
| 1172 | timeout = (mbcp->mbox_out[1] >> 8) & 0xf; | 1169 | timeout = (mbcp->mbox_out[1] >> 8) & 0xf; |
| 1173 | 1170 | ||
| @@ -1231,7 +1228,6 @@ void ql_mpi_idc_work(struct work_struct *work) | |||
| 1231 | } | 1228 | } |
| 1232 | break; | 1229 | break; |
| 1233 | } | 1230 | } |
| 1234 | rtnl_unlock(); | ||
| 1235 | } | 1231 | } |
| 1236 | 1232 | ||
| 1237 | void ql_mpi_work(struct work_struct *work) | 1233 | void ql_mpi_work(struct work_struct *work) |
| @@ -1242,7 +1238,7 @@ void ql_mpi_work(struct work_struct *work) | |||
| 1242 | struct mbox_params *mbcp = &mbc; | 1238 | struct mbox_params *mbcp = &mbc; |
| 1243 | int err = 0; | 1239 | int err = 0; |
| 1244 | 1240 | ||
| 1245 | rtnl_lock(); | 1241 | mutex_lock(&qdev->mpi_mutex); |
| 1246 | /* Begin polled mode for MPI */ | 1242 | /* Begin polled mode for MPI */ |
| 1247 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); | 1243 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); |
| 1248 | 1244 | ||
| @@ -1259,7 +1255,7 @@ void ql_mpi_work(struct work_struct *work) | |||
| 1259 | 1255 | ||
| 1260 | /* End polled mode for MPI */ | 1256 | /* End polled mode for MPI */ |
| 1261 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); | 1257 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); |
| 1262 | rtnl_unlock(); | 1258 | mutex_unlock(&qdev->mpi_mutex); |
| 1263 | ql_enable_completion_interrupt(qdev, 0); | 1259 | ql_enable_completion_interrupt(qdev, 0); |
| 1264 | } | 1260 | } |
| 1265 | 1261 | ||
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 7d33ef4bcb4..53b13deade9 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
| @@ -744,26 +744,36 @@ static void rtl8169_xmii_reset_enable(void __iomem *ioaddr) | |||
| 744 | mdio_write(ioaddr, MII_BMCR, val & 0xffff); | 744 | mdio_write(ioaddr, MII_BMCR, val & 0xffff); |
| 745 | } | 745 | } |
| 746 | 746 | ||
| 747 | static void rtl8169_check_link_status(struct net_device *dev, | 747 | static void __rtl8169_check_link_status(struct net_device *dev, |
| 748 | struct rtl8169_private *tp, | 748 | struct rtl8169_private *tp, |
| 749 | void __iomem *ioaddr) | 749 | void __iomem *ioaddr, |
| 750 | bool pm) | ||
| 750 | { | 751 | { |
| 751 | unsigned long flags; | 752 | unsigned long flags; |
| 752 | 753 | ||
| 753 | spin_lock_irqsave(&tp->lock, flags); | 754 | spin_lock_irqsave(&tp->lock, flags); |
| 754 | if (tp->link_ok(ioaddr)) { | 755 | if (tp->link_ok(ioaddr)) { |
| 755 | /* This is to cancel a scheduled suspend if there's one. */ | 756 | /* This is to cancel a scheduled suspend if there's one. */ |
| 756 | pm_request_resume(&tp->pci_dev->dev); | 757 | if (pm) |
| 758 | pm_request_resume(&tp->pci_dev->dev); | ||
| 757 | netif_carrier_on(dev); | 759 | netif_carrier_on(dev); |
| 758 | netif_info(tp, ifup, dev, "link up\n"); | 760 | netif_info(tp, ifup, dev, "link up\n"); |
| 759 | } else { | 761 | } else { |
| 760 | netif_carrier_off(dev); | 762 | netif_carrier_off(dev); |
| 761 | netif_info(tp, ifdown, dev, "link down\n"); | 763 | netif_info(tp, ifdown, dev, "link down\n"); |
| 762 | pm_schedule_suspend(&tp->pci_dev->dev, 100); | 764 | if (pm) |
| 765 | pm_schedule_suspend(&tp->pci_dev->dev, 100); | ||
| 763 | } | 766 | } |
| 764 | spin_unlock_irqrestore(&tp->lock, flags); | 767 | spin_unlock_irqrestore(&tp->lock, flags); |
| 765 | } | 768 | } |
| 766 | 769 | ||
| 770 | static void rtl8169_check_link_status(struct net_device *dev, | ||
| 771 | struct rtl8169_private *tp, | ||
| 772 | void __iomem *ioaddr) | ||
| 773 | { | ||
| 774 | __rtl8169_check_link_status(dev, tp, ioaddr, false); | ||
| 775 | } | ||
| 776 | |||
| 767 | #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) | 777 | #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) |
| 768 | 778 | ||
| 769 | static u32 __rtl8169_get_wol(struct rtl8169_private *tp) | 779 | static u32 __rtl8169_get_wol(struct rtl8169_private *tp) |
| @@ -4600,7 +4610,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
| 4600 | } | 4610 | } |
| 4601 | 4611 | ||
| 4602 | if (status & LinkChg) | 4612 | if (status & LinkChg) |
| 4603 | rtl8169_check_link_status(dev, tp, ioaddr); | 4613 | __rtl8169_check_link_status(dev, tp, ioaddr, true); |
| 4604 | 4614 | ||
| 4605 | /* We need to see the lastest version of tp->intr_mask to | 4615 | /* We need to see the lastest version of tp->intr_mask to |
| 4606 | * avoid ignoring an MSI interrupt and having to wait for | 4616 | * avoid ignoring an MSI interrupt and having to wait for |
| @@ -4890,11 +4900,7 @@ static int rtl8169_runtime_idle(struct device *device) | |||
| 4890 | struct net_device *dev = pci_get_drvdata(pdev); | 4900 | struct net_device *dev = pci_get_drvdata(pdev); |
| 4891 | struct rtl8169_private *tp = netdev_priv(dev); | 4901 | struct rtl8169_private *tp = netdev_priv(dev); |
| 4892 | 4902 | ||
| 4893 | if (!tp->TxDescArray) | 4903 | return tp->TxDescArray ? -EBUSY : 0; |
| 4894 | return 0; | ||
| 4895 | |||
| 4896 | rtl8169_check_link_status(dev, tp, tp->mmio_addr); | ||
| 4897 | return -EBUSY; | ||
| 4898 | } | 4904 | } |
| 4899 | 4905 | ||
| 4900 | static const struct dev_pm_ops rtl8169_pm_ops = { | 4906 | static const struct dev_pm_ops rtl8169_pm_ops = { |
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 05df20e4797..fb83cdd9464 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
| @@ -197,7 +197,9 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value"); | |||
| 197 | 197 | ||
| 198 | static void efx_remove_channels(struct efx_nic *efx); | 198 | static void efx_remove_channels(struct efx_nic *efx); |
| 199 | static void efx_remove_port(struct efx_nic *efx); | 199 | static void efx_remove_port(struct efx_nic *efx); |
| 200 | static void efx_init_napi(struct efx_nic *efx); | ||
| 200 | static void efx_fini_napi(struct efx_nic *efx); | 201 | static void efx_fini_napi(struct efx_nic *efx); |
| 202 | static void efx_fini_napi_channel(struct efx_channel *channel); | ||
| 201 | static void efx_fini_struct(struct efx_nic *efx); | 203 | static void efx_fini_struct(struct efx_nic *efx); |
| 202 | static void efx_start_all(struct efx_nic *efx); | 204 | static void efx_start_all(struct efx_nic *efx); |
| 203 | static void efx_stop_all(struct efx_nic *efx); | 205 | static void efx_stop_all(struct efx_nic *efx); |
| @@ -335,8 +337,10 @@ void efx_process_channel_now(struct efx_channel *channel) | |||
| 335 | 337 | ||
| 336 | /* Disable interrupts and wait for ISRs to complete */ | 338 | /* Disable interrupts and wait for ISRs to complete */ |
| 337 | efx_nic_disable_interrupts(efx); | 339 | efx_nic_disable_interrupts(efx); |
| 338 | if (efx->legacy_irq) | 340 | if (efx->legacy_irq) { |
| 339 | synchronize_irq(efx->legacy_irq); | 341 | synchronize_irq(efx->legacy_irq); |
| 342 | efx->legacy_irq_enabled = false; | ||
| 343 | } | ||
| 340 | if (channel->irq) | 344 | if (channel->irq) |
| 341 | synchronize_irq(channel->irq); | 345 | synchronize_irq(channel->irq); |
| 342 | 346 | ||
| @@ -351,6 +355,8 @@ void efx_process_channel_now(struct efx_channel *channel) | |||
| 351 | efx_channel_processed(channel); | 355 | efx_channel_processed(channel); |
| 352 | 356 | ||
| 353 | napi_enable(&channel->napi_str); | 357 | napi_enable(&channel->napi_str); |
| 358 | if (efx->legacy_irq) | ||
| 359 | efx->legacy_irq_enabled = true; | ||
| 354 | efx_nic_enable_interrupts(efx); | 360 | efx_nic_enable_interrupts(efx); |
| 355 | } | 361 | } |
| 356 | 362 | ||
| @@ -426,6 +432,7 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel) | |||
| 426 | 432 | ||
| 427 | *channel = *old_channel; | 433 | *channel = *old_channel; |
| 428 | 434 | ||
| 435 | channel->napi_dev = NULL; | ||
| 429 | memset(&channel->eventq, 0, sizeof(channel->eventq)); | 436 | memset(&channel->eventq, 0, sizeof(channel->eventq)); |
| 430 | 437 | ||
| 431 | rx_queue = &channel->rx_queue; | 438 | rx_queue = &channel->rx_queue; |
| @@ -736,9 +743,13 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries) | |||
| 736 | if (rc) | 743 | if (rc) |
| 737 | goto rollback; | 744 | goto rollback; |
| 738 | 745 | ||
| 746 | efx_init_napi(efx); | ||
| 747 | |||
| 739 | /* Destroy old channels */ | 748 | /* Destroy old channels */ |
| 740 | for (i = 0; i < efx->n_channels; i++) | 749 | for (i = 0; i < efx->n_channels; i++) { |
| 750 | efx_fini_napi_channel(other_channel[i]); | ||
| 741 | efx_remove_channel(other_channel[i]); | 751 | efx_remove_channel(other_channel[i]); |
| 752 | } | ||
| 742 | out: | 753 | out: |
| 743 | /* Free unused channel structures */ | 754 | /* Free unused channel structures */ |
| 744 | for (i = 0; i < efx->n_channels; i++) | 755 | for (i = 0; i < efx->n_channels; i++) |
| @@ -1400,6 +1411,8 @@ static void efx_start_all(struct efx_nic *efx) | |||
| 1400 | efx_start_channel(channel); | 1411 | efx_start_channel(channel); |
| 1401 | } | 1412 | } |
| 1402 | 1413 | ||
| 1414 | if (efx->legacy_irq) | ||
| 1415 | efx->legacy_irq_enabled = true; | ||
| 1403 | efx_nic_enable_interrupts(efx); | 1416 | efx_nic_enable_interrupts(efx); |
| 1404 | 1417 | ||
| 1405 | /* Switch to event based MCDI completions after enabling interrupts. | 1418 | /* Switch to event based MCDI completions after enabling interrupts. |
| @@ -1460,8 +1473,10 @@ static void efx_stop_all(struct efx_nic *efx) | |||
| 1460 | 1473 | ||
| 1461 | /* Disable interrupts and wait for ISR to complete */ | 1474 | /* Disable interrupts and wait for ISR to complete */ |
| 1462 | efx_nic_disable_interrupts(efx); | 1475 | efx_nic_disable_interrupts(efx); |
| 1463 | if (efx->legacy_irq) | 1476 | if (efx->legacy_irq) { |
| 1464 | synchronize_irq(efx->legacy_irq); | 1477 | synchronize_irq(efx->legacy_irq); |
| 1478 | efx->legacy_irq_enabled = false; | ||
| 1479 | } | ||
| 1465 | efx_for_each_channel(channel, efx) { | 1480 | efx_for_each_channel(channel, efx) { |
| 1466 | if (channel->irq) | 1481 | if (channel->irq) |
| 1467 | synchronize_irq(channel->irq); | 1482 | synchronize_irq(channel->irq); |
| @@ -1593,7 +1608,7 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) | |||
| 1593 | * | 1608 | * |
| 1594 | **************************************************************************/ | 1609 | **************************************************************************/ |
| 1595 | 1610 | ||
| 1596 | static int efx_init_napi(struct efx_nic *efx) | 1611 | static void efx_init_napi(struct efx_nic *efx) |
| 1597 | { | 1612 | { |
| 1598 | struct efx_channel *channel; | 1613 | struct efx_channel *channel; |
| 1599 | 1614 | ||
| @@ -1602,18 +1617,21 @@ static int efx_init_napi(struct efx_nic *efx) | |||
| 1602 | netif_napi_add(channel->napi_dev, &channel->napi_str, | 1617 | netif_napi_add(channel->napi_dev, &channel->napi_str, |
| 1603 | efx_poll, napi_weight); | 1618 | efx_poll, napi_weight); |
| 1604 | } | 1619 | } |
| 1605 | return 0; | 1620 | } |
| 1621 | |||
| 1622 | static void efx_fini_napi_channel(struct efx_channel *channel) | ||
| 1623 | { | ||
| 1624 | if (channel->napi_dev) | ||
| 1625 | netif_napi_del(&channel->napi_str); | ||
| 1626 | channel->napi_dev = NULL; | ||
| 1606 | } | 1627 | } |
| 1607 | 1628 | ||
| 1608 | static void efx_fini_napi(struct efx_nic *efx) | 1629 | static void efx_fini_napi(struct efx_nic *efx) |
| 1609 | { | 1630 | { |
| 1610 | struct efx_channel *channel; | 1631 | struct efx_channel *channel; |
| 1611 | 1632 | ||
| 1612 | efx_for_each_channel(channel, efx) { | 1633 | efx_for_each_channel(channel, efx) |
| 1613 | if (channel->napi_dev) | 1634 | efx_fini_napi_channel(channel); |
| 1614 | netif_napi_del(&channel->napi_str); | ||
| 1615 | channel->napi_dev = NULL; | ||
| 1616 | } | ||
| 1617 | } | 1635 | } |
| 1618 | 1636 | ||
| 1619 | /************************************************************************** | 1637 | /************************************************************************** |
| @@ -2335,9 +2353,7 @@ static int efx_pci_probe_main(struct efx_nic *efx) | |||
| 2335 | if (rc) | 2353 | if (rc) |
| 2336 | goto fail1; | 2354 | goto fail1; |
| 2337 | 2355 | ||
| 2338 | rc = efx_init_napi(efx); | 2356 | efx_init_napi(efx); |
| 2339 | if (rc) | ||
| 2340 | goto fail2; | ||
| 2341 | 2357 | ||
| 2342 | rc = efx->type->init(efx); | 2358 | rc = efx->type->init(efx); |
| 2343 | if (rc) { | 2359 | if (rc) { |
| @@ -2368,7 +2384,6 @@ static int efx_pci_probe_main(struct efx_nic *efx) | |||
| 2368 | efx->type->fini(efx); | 2384 | efx->type->fini(efx); |
| 2369 | fail3: | 2385 | fail3: |
| 2370 | efx_fini_napi(efx); | 2386 | efx_fini_napi(efx); |
| 2371 | fail2: | ||
| 2372 | efx_remove_all(efx); | 2387 | efx_remove_all(efx); |
| 2373 | fail1: | 2388 | fail1: |
| 2374 | return rc; | 2389 | return rc; |
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 0a7e26d73b5..b137c889152 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
| @@ -621,6 +621,7 @@ struct efx_filter_state; | |||
| 621 | * @pci_dev: The PCI device | 621 | * @pci_dev: The PCI device |
| 622 | * @type: Controller type attributes | 622 | * @type: Controller type attributes |
| 623 | * @legacy_irq: IRQ number | 623 | * @legacy_irq: IRQ number |
| 624 | * @legacy_irq_enabled: Are IRQs enabled on NIC (INT_EN_KER register)? | ||
| 624 | * @workqueue: Workqueue for port reconfigures and the HW monitor. | 625 | * @workqueue: Workqueue for port reconfigures and the HW monitor. |
| 625 | * Work items do not hold and must not acquire RTNL. | 626 | * Work items do not hold and must not acquire RTNL. |
| 626 | * @workqueue_name: Name of workqueue | 627 | * @workqueue_name: Name of workqueue |
| @@ -709,6 +710,7 @@ struct efx_nic { | |||
| 709 | struct pci_dev *pci_dev; | 710 | struct pci_dev *pci_dev; |
| 710 | const struct efx_nic_type *type; | 711 | const struct efx_nic_type *type; |
| 711 | int legacy_irq; | 712 | int legacy_irq; |
| 713 | bool legacy_irq_enabled; | ||
| 712 | struct workqueue_struct *workqueue; | 714 | struct workqueue_struct *workqueue; |
| 713 | char workqueue_name[16]; | 715 | char workqueue_name[16]; |
| 714 | struct work_struct reset_work; | 716 | struct work_struct reset_work; |
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 41c36b9a424..67cb0c96838 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c | |||
| @@ -1418,6 +1418,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) | |||
| 1418 | u32 queues; | 1418 | u32 queues; |
| 1419 | int syserr; | 1419 | int syserr; |
| 1420 | 1420 | ||
| 1421 | /* Could this be ours? If interrupts are disabled then the | ||
| 1422 | * channel state may not be valid. | ||
| 1423 | */ | ||
| 1424 | if (!efx->legacy_irq_enabled) | ||
| 1425 | return result; | ||
| 1426 | |||
| 1421 | /* Read the ISR which also ACKs the interrupts */ | 1427 | /* Read the ISR which also ACKs the interrupts */ |
| 1422 | efx_readd(efx, ®, FR_BZ_INT_ISR0); | 1428 | efx_readd(efx, ®, FR_BZ_INT_ISR0); |
| 1423 | queues = EFX_EXTRACT_DWORD(reg, 0, 31); | 1429 | queues = EFX_EXTRACT_DWORD(reg, 0, 31); |
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 06bc6034ce8..2114837809e 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c | |||
| @@ -1509,6 +1509,8 @@ static int stmmac_probe(struct net_device *dev) | |||
| 1509 | pr_warning("\tno valid MAC address;" | 1509 | pr_warning("\tno valid MAC address;" |
| 1510 | "please, use ifconfig or nwhwconfig!\n"); | 1510 | "please, use ifconfig or nwhwconfig!\n"); |
| 1511 | 1511 | ||
| 1512 | spin_lock_init(&priv->lock); | ||
| 1513 | |||
| 1512 | ret = register_netdev(dev); | 1514 | ret = register_netdev(dev); |
| 1513 | if (ret) { | 1515 | if (ret) { |
| 1514 | pr_err("%s: ERROR %i registering the device\n", | 1516 | pr_err("%s: ERROR %i registering the device\n", |
| @@ -1520,8 +1522,6 @@ static int stmmac_probe(struct net_device *dev) | |||
| 1520 | dev->name, (dev->features & NETIF_F_SG) ? "on" : "off", | 1522 | dev->name, (dev->features & NETIF_F_SG) ? "on" : "off", |
| 1521 | (dev->features & NETIF_F_HW_CSUM) ? "on" : "off"); | 1523 | (dev->features & NETIF_F_HW_CSUM) ? "on" : "off"); |
| 1522 | 1524 | ||
| 1523 | spin_lock_init(&priv->lock); | ||
| 1524 | |||
| 1525 | return ret; | 1525 | return ret; |
| 1526 | } | 1526 | } |
| 1527 | 1527 | ||
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index a9f7d5d1a26..7064e035757 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c | |||
| @@ -688,9 +688,6 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb, | |||
| 688 | 688 | ||
| 689 | DMFE_DBUG(0, "dmfe_start_xmit", 0); | 689 | DMFE_DBUG(0, "dmfe_start_xmit", 0); |
| 690 | 690 | ||
| 691 | /* Resource flag check */ | ||
| 692 | netif_stop_queue(dev); | ||
| 693 | |||
| 694 | /* Too large packet check */ | 691 | /* Too large packet check */ |
| 695 | if (skb->len > MAX_PACKET_SIZE) { | 692 | if (skb->len > MAX_PACKET_SIZE) { |
| 696 | pr_err("big packet = %d\n", (u16)skb->len); | 693 | pr_err("big packet = %d\n", (u16)skb->len); |
| @@ -698,6 +695,9 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb, | |||
| 698 | return NETDEV_TX_OK; | 695 | return NETDEV_TX_OK; |
| 699 | } | 696 | } |
| 700 | 697 | ||
| 698 | /* Resource flag check */ | ||
| 699 | netif_stop_queue(dev); | ||
| 700 | |||
| 701 | spin_lock_irqsave(&db->lock, flags); | 701 | spin_lock_irqsave(&db->lock, flags); |
| 702 | 702 | ||
| 703 | /* No Tx resource check, it never happen nromally */ | 703 | /* No Tx resource check, it never happen nromally */ |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 62e9e8dc819..812edf85d6d 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
| @@ -958,10 +958,6 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, | |||
| 958 | /* Packet is complete. Inject into stack. */ | 958 | /* Packet is complete. Inject into stack. */ |
| 959 | /* We have IP packet here */ | 959 | /* We have IP packet here */ |
| 960 | odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP); | 960 | odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP); |
| 961 | /* don't check it */ | ||
| 962 | odev->skb_rx_buf->ip_summed = | ||
| 963 | CHECKSUM_UNNECESSARY; | ||
| 964 | |||
| 965 | skb_reset_mac_header(odev->skb_rx_buf); | 961 | skb_reset_mac_header(odev->skb_rx_buf); |
| 966 | 962 | ||
| 967 | /* Ship it off to the kernel */ | 963 | /* Ship it off to the kernel */ |
diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c index ea476cbd38b..e305274f83f 100644 --- a/drivers/net/wan/hd64572.c +++ b/drivers/net/wan/hd64572.c | |||
| @@ -293,6 +293,7 @@ static inline void sca_tx_done(port_t *port) | |||
| 293 | struct net_device *dev = port->netdev; | 293 | struct net_device *dev = port->netdev; |
| 294 | card_t* card = port->card; | 294 | card_t* card = port->card; |
| 295 | u8 stat; | 295 | u8 stat; |
| 296 | unsigned count = 0; | ||
| 296 | 297 | ||
| 297 | spin_lock(&port->lock); | 298 | spin_lock(&port->lock); |
| 298 | 299 | ||
| @@ -316,10 +317,12 @@ static inline void sca_tx_done(port_t *port) | |||
| 316 | dev->stats.tx_bytes += readw(&desc->len); | 317 | dev->stats.tx_bytes += readw(&desc->len); |
| 317 | } | 318 | } |
| 318 | writeb(0, &desc->stat); /* Free descriptor */ | 319 | writeb(0, &desc->stat); /* Free descriptor */ |
| 320 | count++; | ||
| 319 | port->txlast = (port->txlast + 1) % card->tx_ring_buffers; | 321 | port->txlast = (port->txlast + 1) % card->tx_ring_buffers; |
| 320 | } | 322 | } |
| 321 | 323 | ||
| 322 | netif_wake_queue(dev); | 324 | if (count) |
| 325 | netif_wake_queue(dev); | ||
| 323 | spin_unlock(&port->lock); | 326 | spin_unlock(&port->lock); |
| 324 | } | 327 | } |
| 325 | 328 | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 8251946842e..42ed923cdb1 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
| @@ -1917,7 +1917,8 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
| 1917 | sc->bmisscount = 0; | 1917 | sc->bmisscount = 0; |
| 1918 | } | 1918 | } |
| 1919 | 1919 | ||
| 1920 | if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) { | 1920 | if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) || |
| 1921 | sc->opmode == NL80211_IFTYPE_MESH_POINT) { | ||
| 1921 | u64 tsf = ath5k_hw_get_tsf64(ah); | 1922 | u64 tsf = ath5k_hw_get_tsf64(ah); |
| 1922 | u32 tsftu = TSF_TO_TU(tsf); | 1923 | u32 tsftu = TSF_TO_TU(tsf); |
| 1923 | int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval; | 1924 | int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval; |
| @@ -1949,8 +1950,9 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
| 1949 | /* NB: hw still stops DMA, so proceed */ | 1950 | /* NB: hw still stops DMA, so proceed */ |
| 1950 | } | 1951 | } |
| 1951 | 1952 | ||
| 1952 | /* refresh the beacon for AP mode */ | 1953 | /* refresh the beacon for AP or MESH mode */ |
| 1953 | if (sc->opmode == NL80211_IFTYPE_AP) | 1954 | if (sc->opmode == NL80211_IFTYPE_AP || |
| 1955 | sc->opmode == NL80211_IFTYPE_MESH_POINT) | ||
| 1954 | ath5k_beacon_update(sc->hw, vif); | 1956 | ath5k_beacon_update(sc->hw, vif); |
| 1955 | 1957 | ||
| 1956 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); | 1958 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); |
| @@ -2851,7 +2853,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
| 2851 | 2853 | ||
| 2852 | /* Assign the vap/adhoc to a beacon xmit slot. */ | 2854 | /* Assign the vap/adhoc to a beacon xmit slot. */ |
| 2853 | if ((avf->opmode == NL80211_IFTYPE_AP) || | 2855 | if ((avf->opmode == NL80211_IFTYPE_AP) || |
| 2854 | (avf->opmode == NL80211_IFTYPE_ADHOC)) { | 2856 | (avf->opmode == NL80211_IFTYPE_ADHOC) || |
| 2857 | (avf->opmode == NL80211_IFTYPE_MESH_POINT)) { | ||
| 2855 | int slot; | 2858 | int slot; |
| 2856 | 2859 | ||
| 2857 | WARN_ON(list_empty(&sc->bcbuf)); | 2860 | WARN_ON(list_empty(&sc->bcbuf)); |
| @@ -2870,7 +2873,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
| 2870 | sc->bslot[avf->bslot] = vif; | 2873 | sc->bslot[avf->bslot] = vif; |
| 2871 | if (avf->opmode == NL80211_IFTYPE_AP) | 2874 | if (avf->opmode == NL80211_IFTYPE_AP) |
| 2872 | sc->num_ap_vifs++; | 2875 | sc->num_ap_vifs++; |
| 2873 | else | 2876 | else if (avf->opmode == NL80211_IFTYPE_ADHOC) |
| 2874 | sc->num_adhoc_vifs++; | 2877 | sc->num_adhoc_vifs++; |
| 2875 | } | 2878 | } |
| 2876 | 2879 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c4182359bee..a7b82f0085d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
| @@ -55,6 +55,8 @@ | |||
| 55 | #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ | 55 | #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ |
| 56 | #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ | 56 | #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ |
| 57 | 57 | ||
| 58 | #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6)) | ||
| 59 | |||
| 58 | static const struct ar9300_eeprom ar9300_default = { | 60 | static const struct ar9300_eeprom ar9300_default = { |
| 59 | .eepromVersion = 2, | 61 | .eepromVersion = 2, |
| 60 | .templateVersion = 2, | 62 | .templateVersion = 2, |
| @@ -290,20 +292,21 @@ static const struct ar9300_eeprom ar9300_default = { | |||
| 290 | } | 292 | } |
| 291 | }, | 293 | }, |
| 292 | .ctlPowerData_2G = { | 294 | .ctlPowerData_2G = { |
| 293 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 295 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
| 294 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 296 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
| 295 | { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } }, | 297 | { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, |
| 296 | 298 | ||
| 297 | { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } }, | 299 | { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, |
| 298 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 300 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
| 299 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 301 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
| 300 | 302 | ||
| 301 | { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } }, | 303 | { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } }, |
| 302 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 304 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
| 303 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 305 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
| 304 | 306 | ||
| 305 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 307 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
| 306 | { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, | 308 | { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } }, |
| 309 | { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } }, | ||
| 307 | }, | 310 | }, |
| 308 | .modalHeader5G = { | 311 | .modalHeader5G = { |
| 309 | /* 4 idle,t1,t2,b (4 bits per setting) */ | 312 | /* 4 idle,t1,t2,b (4 bits per setting) */ |
| @@ -568,56 +571,56 @@ static const struct ar9300_eeprom ar9300_default = { | |||
| 568 | .ctlPowerData_5G = { | 571 | .ctlPowerData_5G = { |
| 569 | { | 572 | { |
| 570 | { | 573 | { |
| 571 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 574 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
| 572 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | 575 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), |
| 573 | } | 576 | } |
| 574 | }, | 577 | }, |
| 575 | { | 578 | { |
| 576 | { | 579 | { |
| 577 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 580 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
| 578 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | 581 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), |
| 579 | } | 582 | } |
| 580 | }, | 583 | }, |
| 581 | { | 584 | { |
| 582 | { | 585 | { |
| 583 | {60, 0}, {60, 1}, {60, 0}, {60, 1}, | 586 | CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1), |
| 584 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 587 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
| 585 | } | 588 | } |
| 586 | }, | 589 | }, |
| 587 | { | 590 | { |
| 588 | { | 591 | { |
| 589 | {60, 0}, {60, 1}, {60, 1}, {60, 0}, | 592 | CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0), |
| 590 | {60, 1}, {60, 0}, {60, 0}, {60, 0}, | 593 | CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0), |
| 591 | } | 594 | } |
| 592 | }, | 595 | }, |
| 593 | { | 596 | { |
| 594 | { | 597 | { |
| 595 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | 598 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), |
| 596 | {60, 0}, {60, 0}, {60, 0}, {60, 0}, | 599 | CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0), |
| 597 | } | 600 | } |
| 598 | }, | 601 | }, |
| 599 | { | 602 | { |
| 600 | { | 603 | { |
| 601 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 604 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
| 602 | {60, 1}, {60, 0}, {60, 0}, {60, 0}, | 605 | CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0), |
| 603 | } | 606 | } |
| 604 | }, | 607 | }, |
| 605 | { | 608 | { |
| 606 | { | 609 | { |
| 607 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 610 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
| 608 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 611 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
| 609 | } | 612 | } |
| 610 | }, | 613 | }, |
| 611 | { | 614 | { |
| 612 | { | 615 | { |
| 613 | {60, 1}, {60, 1}, {60, 0}, {60, 1}, | 616 | CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1), |
| 614 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | 617 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), |
| 615 | } | 618 | } |
| 616 | }, | 619 | }, |
| 617 | { | 620 | { |
| 618 | { | 621 | { |
| 619 | {60, 1}, {60, 0}, {60, 1}, {60, 1}, | 622 | CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1), |
| 620 | {60, 1}, {60, 1}, {60, 0}, {60, 1}, | 623 | CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1), |
| 621 | } | 624 | } |
| 622 | }, | 625 | }, |
| 623 | } | 626 | } |
| @@ -1827,9 +1830,9 @@ static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep, | |||
| 1827 | struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G; | 1830 | struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G; |
| 1828 | 1831 | ||
| 1829 | if (is2GHz) | 1832 | if (is2GHz) |
| 1830 | return ctl_2g[idx].ctlEdges[edge].tPower; | 1833 | return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]); |
| 1831 | else | 1834 | else |
| 1832 | return ctl_5g[idx].ctlEdges[edge].tPower; | 1835 | return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]); |
| 1833 | } | 1836 | } |
| 1834 | 1837 | ||
| 1835 | static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, | 1838 | static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, |
| @@ -1847,12 +1850,12 @@ static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, | |||
| 1847 | 1850 | ||
| 1848 | if (is2GHz) { | 1851 | if (is2GHz) { |
| 1849 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq && | 1852 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq && |
| 1850 | ctl_2g[idx].ctlEdges[edge - 1].flag) | 1853 | CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1])) |
| 1851 | return ctl_2g[idx].ctlEdges[edge - 1].tPower; | 1854 | return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]); |
| 1852 | } else { | 1855 | } else { |
| 1853 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq && | 1856 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq && |
| 1854 | ctl_5g[idx].ctlEdges[edge - 1].flag) | 1857 | CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1])) |
| 1855 | return ctl_5g[idx].ctlEdges[edge - 1].tPower; | 1858 | return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]); |
| 1856 | } | 1859 | } |
| 1857 | 1860 | ||
| 1858 | return AR9300_MAX_RATE_POWER; | 1861 | return AR9300_MAX_RATE_POWER; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 3c533bb983c..655b3033396 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | |||
| @@ -261,17 +261,12 @@ struct cal_tgt_pow_ht { | |||
| 261 | u8 tPow2x[14]; | 261 | u8 tPow2x[14]; |
| 262 | } __packed; | 262 | } __packed; |
| 263 | 263 | ||
| 264 | struct cal_ctl_edge_pwr { | ||
| 265 | u8 tPower:6, | ||
| 266 | flag:2; | ||
| 267 | } __packed; | ||
| 268 | |||
| 269 | struct cal_ctl_data_2g { | 264 | struct cal_ctl_data_2g { |
| 270 | struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_2G]; | 265 | u8 ctlEdges[AR9300_NUM_BAND_EDGES_2G]; |
| 271 | } __packed; | 266 | } __packed; |
| 272 | 267 | ||
| 273 | struct cal_ctl_data_5g { | 268 | struct cal_ctl_data_5g { |
| 274 | struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G]; | 269 | u8 ctlEdges[AR9300_NUM_BAND_EDGES_5G]; |
| 275 | } __packed; | 270 | } __packed; |
| 276 | 271 | ||
| 277 | struct ar9300_eeprom { | 272 | struct ar9300_eeprom { |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 170d44a35cc..0963071e8f9 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
| 22 | #include <linux/leds.h> | 22 | #include <linux/leds.h> |
| 23 | #include <linux/completion.h> | 23 | #include <linux/completion.h> |
| 24 | #include <linux/pm_qos_params.h> | ||
| 24 | 25 | ||
| 25 | #include "debug.h" | 26 | #include "debug.h" |
| 26 | #include "common.h" | 27 | #include "common.h" |
| @@ -328,7 +329,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp); | |||
| 328 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); | 329 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); |
| 329 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); | 330 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); |
| 330 | int ath_tx_setup(struct ath_softc *sc, int haltype); | 331 | int ath_tx_setup(struct ath_softc *sc, int haltype); |
| 331 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); | 332 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); |
| 332 | void ath_draintxq(struct ath_softc *sc, | 333 | void ath_draintxq(struct ath_softc *sc, |
| 333 | struct ath_txq *txq, bool retry_tx); | 334 | struct ath_txq *txq, bool retry_tx); |
| 334 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); | 335 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); |
| @@ -646,6 +647,8 @@ struct ath_softc { | |||
| 646 | struct ath_descdma txsdma; | 647 | struct ath_descdma txsdma; |
| 647 | 648 | ||
| 648 | struct ath_ant_comb ant_comb; | 649 | struct ath_ant_comb ant_comb; |
| 650 | |||
| 651 | struct pm_qos_request_list pm_qos_req; | ||
| 649 | }; | 652 | }; |
| 650 | 653 | ||
| 651 | struct ath_wiphy { | 654 | struct ath_wiphy { |
| @@ -675,7 +678,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) | |||
| 675 | } | 678 | } |
| 676 | 679 | ||
| 677 | extern struct ieee80211_ops ath9k_ops; | 680 | extern struct ieee80211_ops ath9k_ops; |
| 678 | extern struct pm_qos_request_list ath9k_pm_qos_req; | ||
| 679 | extern int modparam_nohwcrypt; | 681 | extern int modparam_nohwcrypt; |
| 680 | extern int led_blink; | 682 | extern int led_blink; |
| 681 | 683 | ||
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index 1266333f586..2bbf94d0191 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c | |||
| @@ -240,16 +240,16 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, | |||
| 240 | for (i = 0; (i < num_band_edges) && | 240 | for (i = 0; (i < num_band_edges) && |
| 241 | (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) { | 241 | (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) { |
| 242 | if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { | 242 | if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { |
| 243 | twiceMaxEdgePower = pRdEdgesPower[i].tPower; | 243 | twiceMaxEdgePower = CTL_EDGE_TPOWER(pRdEdgesPower[i].ctl); |
| 244 | break; | 244 | break; |
| 245 | } else if ((i > 0) && | 245 | } else if ((i > 0) && |
| 246 | (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, | 246 | (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, |
| 247 | is2GHz))) { | 247 | is2GHz))) { |
| 248 | if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel, | 248 | if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel, |
| 249 | is2GHz) < freq && | 249 | is2GHz) < freq && |
| 250 | pRdEdgesPower[i - 1].flag) { | 250 | CTL_EDGE_FLAGS(pRdEdgesPower[i - 1].ctl)) { |
| 251 | twiceMaxEdgePower = | 251 | twiceMaxEdgePower = |
| 252 | pRdEdgesPower[i - 1].tPower; | 252 | CTL_EDGE_TPOWER(pRdEdgesPower[i - 1].ctl); |
| 253 | } | 253 | } |
| 254 | break; | 254 | break; |
| 255 | } | 255 | } |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index dacb45e1b90..dd59f09441a 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
| @@ -233,6 +233,18 @@ | |||
| 233 | 233 | ||
| 234 | #define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1) | 234 | #define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1) |
| 235 | 235 | ||
| 236 | #define CTL_EDGE_TPOWER(_ctl) ((_ctl) & 0x3f) | ||
| 237 | #define CTL_EDGE_FLAGS(_ctl) (((_ctl) >> 6) & 0x03) | ||
| 238 | |||
| 239 | #define LNA_CTL_BUF_MODE BIT(0) | ||
| 240 | #define LNA_CTL_ISEL_LO BIT(1) | ||
| 241 | #define LNA_CTL_ISEL_HI BIT(2) | ||
| 242 | #define LNA_CTL_BUF_IN BIT(3) | ||
| 243 | #define LNA_CTL_FEM_BAND BIT(4) | ||
| 244 | #define LNA_CTL_LOCAL_BIAS BIT(5) | ||
| 245 | #define LNA_CTL_FORCE_XPA BIT(6) | ||
| 246 | #define LNA_CTL_USE_ANT1 BIT(7) | ||
| 247 | |||
| 236 | enum eeprom_param { | 248 | enum eeprom_param { |
| 237 | EEP_NFTHRESH_5, | 249 | EEP_NFTHRESH_5, |
| 238 | EEP_NFTHRESH_2, | 250 | EEP_NFTHRESH_2, |
| @@ -378,10 +390,7 @@ struct modal_eep_header { | |||
| 378 | u8 xatten2Margin[AR5416_MAX_CHAINS]; | 390 | u8 xatten2Margin[AR5416_MAX_CHAINS]; |
| 379 | u8 ob_ch1; | 391 | u8 ob_ch1; |
| 380 | u8 db_ch1; | 392 | u8 db_ch1; |
| 381 | u8 useAnt1:1, | 393 | u8 lna_ctl; |
| 382 | force_xpaon:1, | ||
| 383 | local_bias:1, | ||
| 384 | femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1; | ||
| 385 | u8 miscBits; | 394 | u8 miscBits; |
| 386 | u16 xpaBiasLvlFreq[3]; | 395 | u16 xpaBiasLvlFreq[3]; |
| 387 | u8 futureModal[6]; | 396 | u8 futureModal[6]; |
| @@ -535,18 +544,10 @@ struct cal_target_power_ht { | |||
| 535 | u8 tPow2x[8]; | 544 | u8 tPow2x[8]; |
| 536 | } __packed; | 545 | } __packed; |
| 537 | 546 | ||
| 538 | |||
| 539 | #ifdef __BIG_ENDIAN_BITFIELD | ||
| 540 | struct cal_ctl_edges { | ||
| 541 | u8 bChannel; | ||
| 542 | u8 flag:2, tPower:6; | ||
| 543 | } __packed; | ||
| 544 | #else | ||
| 545 | struct cal_ctl_edges { | 547 | struct cal_ctl_edges { |
| 546 | u8 bChannel; | 548 | u8 bChannel; |
| 547 | u8 tPower:6, flag:2; | 549 | u8 ctl; |
| 548 | } __packed; | 550 | } __packed; |
| 549 | #endif | ||
| 550 | 551 | ||
| 551 | struct cal_data_op_loop_ar9287 { | 552 | struct cal_data_op_loop_ar9287 { |
| 552 | u8 pwrPdg[2][5]; | 553 | u8 pwrPdg[2][5]; |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 76b4d65472d..a3ccb1b9638 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c | |||
| @@ -451,9 +451,10 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah, | |||
| 451 | ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2, | 451 | ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2, |
| 452 | AR_AN_TOP2_LOCALBIAS, | 452 | AR_AN_TOP2_LOCALBIAS, |
| 453 | AR_AN_TOP2_LOCALBIAS_S, | 453 | AR_AN_TOP2_LOCALBIAS_S, |
| 454 | pModal->local_bias); | 454 | !!(pModal->lna_ctl & |
| 455 | LNA_CTL_LOCAL_BIAS)); | ||
| 455 | REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, | 456 | REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, |
| 456 | pModal->force_xpaon); | 457 | !!(pModal->lna_ctl & LNA_CTL_FORCE_XPA)); |
| 457 | } | 458 | } |
| 458 | 459 | ||
| 459 | REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, | 460 | REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, |
| @@ -1062,15 +1063,19 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, | |||
| 1062 | case 1: | 1063 | case 1: |
| 1063 | break; | 1064 | break; |
| 1064 | case 2: | 1065 | case 2: |
| 1065 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | 1066 | if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN) |
| 1067 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | ||
| 1068 | else | ||
| 1069 | scaledPower = 0; | ||
| 1066 | break; | 1070 | break; |
| 1067 | case 3: | 1071 | case 3: |
| 1068 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | 1072 | if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN) |
| 1073 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | ||
| 1074 | else | ||
| 1075 | scaledPower = 0; | ||
| 1069 | break; | 1076 | break; |
| 1070 | } | 1077 | } |
| 1071 | 1078 | ||
| 1072 | scaledPower = max((u16)0, scaledPower); | ||
| 1073 | |||
| 1074 | if (IS_CHAN_2GHZ(chan)) { | 1079 | if (IS_CHAN_2GHZ(chan)) { |
| 1075 | numCtlModes = ARRAY_SIZE(ctlModesFor11g) - | 1080 | numCtlModes = ARRAY_SIZE(ctlModesFor11g) - |
| 1076 | SUB_NUM_CTL_MODES_AT_2G_40; | 1081 | SUB_NUM_CTL_MODES_AT_2G_40; |
| @@ -1428,9 +1433,9 @@ static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah, | |||
| 1428 | 1433 | ||
| 1429 | num_ant_config = 1; | 1434 | num_ant_config = 1; |
| 1430 | 1435 | ||
| 1431 | if (pBase->version >= 0x0E0D) | 1436 | if (pBase->version >= 0x0E0D && |
| 1432 | if (pModal->useAnt1) | 1437 | (pModal->lna_ctl & LNA_CTL_USE_ANT1)) |
| 1433 | num_ant_config += 1; | 1438 | num_ant_config += 1; |
| 1434 | 1439 | ||
| 1435 | return num_ant_config; | 1440 | return num_ant_config; |
| 1436 | } | 1441 | } |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index dfb6560dab9..0de3c3d3c24 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
| @@ -1024,6 +1024,13 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface, | |||
| 1024 | struct hif_device_usb *hif_dev = | 1024 | struct hif_device_usb *hif_dev = |
| 1025 | (struct hif_device_usb *) usb_get_intfdata(interface); | 1025 | (struct hif_device_usb *) usb_get_intfdata(interface); |
| 1026 | 1026 | ||
| 1027 | /* | ||
| 1028 | * The device has to be set to FULLSLEEP mode in case no | ||
| 1029 | * interface is up. | ||
| 1030 | */ | ||
| 1031 | if (!(hif_dev->flags & HIF_USB_START)) | ||
| 1032 | ath9k_htc_suspend(hif_dev->htc_handle); | ||
| 1033 | |||
| 1027 | ath9k_hif_usb_dealloc_urbs(hif_dev); | 1034 | ath9k_hif_usb_dealloc_urbs(hif_dev); |
| 1028 | 1035 | ||
| 1029 | return 0; | 1036 | return 0; |
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 75ecf6a30d2..c3b561daa6c 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
| @@ -455,6 +455,8 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv); | |||
| 455 | void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv); | 455 | void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv); |
| 456 | void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv); | 456 | void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv); |
| 457 | void ath9k_ps_work(struct work_struct *work); | 457 | void ath9k_ps_work(struct work_struct *work); |
| 458 | bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, | ||
| 459 | enum ath9k_power_mode mode); | ||
| 458 | 460 | ||
| 459 | void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); | 461 | void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); |
| 460 | void ath9k_init_leds(struct ath9k_htc_priv *priv); | 462 | void ath9k_init_leds(struct ath9k_htc_priv *priv); |
| @@ -464,6 +466,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, | |||
| 464 | u16 devid, char *product); | 466 | u16 devid, char *product); |
| 465 | void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug); | 467 | void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug); |
| 466 | #ifdef CONFIG_PM | 468 | #ifdef CONFIG_PM |
| 469 | void ath9k_htc_suspend(struct htc_target *htc_handle); | ||
| 467 | int ath9k_htc_resume(struct htc_target *htc_handle); | 470 | int ath9k_htc_resume(struct htc_target *htc_handle); |
| 468 | #endif | 471 | #endif |
| 469 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | 472 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 7c8a38d0456..8776f49ffd4 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
| @@ -891,6 +891,12 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug) | |||
| 891 | } | 891 | } |
| 892 | 892 | ||
| 893 | #ifdef CONFIG_PM | 893 | #ifdef CONFIG_PM |
| 894 | |||
| 895 | void ath9k_htc_suspend(struct htc_target *htc_handle) | ||
| 896 | { | ||
| 897 | ath9k_htc_setpower(htc_handle->drv_priv, ATH9K_PM_FULL_SLEEP); | ||
| 898 | } | ||
| 899 | |||
| 894 | int ath9k_htc_resume(struct htc_target *htc_handle) | 900 | int ath9k_htc_resume(struct htc_target *htc_handle) |
| 895 | { | 901 | { |
| 896 | int ret; | 902 | int ret; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 9a3be8da755..51977caca47 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
| @@ -63,8 +63,8 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv, | |||
| 63 | return mode; | 63 | return mode; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, | 66 | bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, |
| 67 | enum ath9k_power_mode mode) | 67 | enum ath9k_power_mode mode) |
| 68 | { | 68 | { |
| 69 | bool ret; | 69 | bool ret; |
| 70 | 70 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 6ebc68bca91..c7fbe25cc12 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
| @@ -2044,7 +2044,8 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) | |||
| 2044 | val = REG_READ(ah, AR7010_GPIO_IN); | 2044 | val = REG_READ(ah, AR7010_GPIO_IN); |
| 2045 | return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0; | 2045 | return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0; |
| 2046 | } else if (AR_SREV_9300_20_OR_LATER(ah)) | 2046 | } else if (AR_SREV_9300_20_OR_LATER(ah)) |
| 2047 | return MS_REG_READ(AR9300, gpio) != 0; | 2047 | return (MS(REG_READ(ah, AR_GPIO_IN), AR9300_GPIO_IN_VAL) & |
| 2048 | AR_GPIO_BIT(gpio)) != 0; | ||
| 2048 | else if (AR_SREV_9271(ah)) | 2049 | else if (AR_SREV_9271(ah)) |
| 2049 | return MS_REG_READ(AR9271, gpio) != 0; | 2050 | return MS_REG_READ(AR9271, gpio) != 0; |
| 2050 | else if (AR_SREV_9287_11_OR_LATER(ah)) | 2051 | else if (AR_SREV_9287_11_OR_LATER(ah)) |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 92bc5c5f487..14b8ab386da 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 18 | #include <linux/pm_qos_params.h> | ||
| 19 | 18 | ||
| 20 | #include "ath9k.h" | 19 | #include "ath9k.h" |
| 21 | 20 | ||
| @@ -180,8 +179,6 @@ static const struct ath_ops ath9k_common_ops = { | |||
| 180 | .write = ath9k_iowrite32, | 179 | .write = ath9k_iowrite32, |
| 181 | }; | 180 | }; |
| 182 | 181 | ||
| 183 | struct pm_qos_request_list ath9k_pm_qos_req; | ||
| 184 | |||
| 185 | /**************************/ | 182 | /**************************/ |
| 186 | /* Initialization */ | 183 | /* Initialization */ |
| 187 | /**************************/ | 184 | /**************************/ |
| @@ -664,6 +661,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
| 664 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | 661 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; |
| 665 | 662 | ||
| 666 | hw->wiphy->interface_modes = | 663 | hw->wiphy->interface_modes = |
| 664 | BIT(NL80211_IFTYPE_P2P_GO) | | ||
| 665 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | ||
| 667 | BIT(NL80211_IFTYPE_AP) | | 666 | BIT(NL80211_IFTYPE_AP) | |
| 668 | BIT(NL80211_IFTYPE_WDS) | | 667 | BIT(NL80211_IFTYPE_WDS) | |
| 669 | BIT(NL80211_IFTYPE_STATION) | | 668 | BIT(NL80211_IFTYPE_STATION) | |
| @@ -759,7 +758,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
| 759 | ath_init_leds(sc); | 758 | ath_init_leds(sc); |
| 760 | ath_start_rfkill_poll(sc); | 759 | ath_start_rfkill_poll(sc); |
| 761 | 760 | ||
| 762 | pm_qos_add_request(&ath9k_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, | 761 | pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, |
| 763 | PM_QOS_DEFAULT_VALUE); | 762 | PM_QOS_DEFAULT_VALUE); |
| 764 | 763 | ||
| 765 | return 0; | 764 | return 0; |
| @@ -830,7 +829,7 @@ void ath9k_deinit_device(struct ath_softc *sc) | |||
| 830 | } | 829 | } |
| 831 | 830 | ||
| 832 | ieee80211_unregister_hw(hw); | 831 | ieee80211_unregister_hw(hw); |
| 833 | pm_qos_remove_request(&ath9k_pm_qos_req); | 832 | pm_qos_remove_request(&sc->pm_qos_req); |
| 834 | ath_rx_cleanup(sc); | 833 | ath_rx_cleanup(sc); |
| 835 | ath_tx_cleanup(sc); | 834 | ath_tx_cleanup(sc); |
| 836 | ath9k_deinit_softc(sc); | 835 | ath9k_deinit_softc(sc); |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 8c13479b17c..c996963ab33 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
| @@ -703,8 +703,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, | |||
| 703 | rs->rs_phyerr = phyerr; | 703 | rs->rs_phyerr = phyerr; |
| 704 | } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) | 704 | } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) |
| 705 | rs->rs_status |= ATH9K_RXERR_DECRYPT; | 705 | rs->rs_status |= ATH9K_RXERR_DECRYPT; |
| 706 | else if ((ads.ds_rxstatus8 & AR_MichaelErr) && | 706 | else if (ads.ds_rxstatus8 & AR_MichaelErr) |
| 707 | rs->rs_keyix != ATH9K_RXKEYIX_INVALID) | ||
| 708 | rs->rs_status |= ATH9K_RXERR_MIC; | 707 | rs->rs_status |= ATH9K_RXERR_MIC; |
| 709 | else if (ads.ds_rxstatus8 & AR_KeyMiss) | 708 | else if (ads.ds_rxstatus8 & AR_KeyMiss) |
| 710 | rs->rs_status |= ATH9K_RXERR_DECRYPT; | 709 | rs->rs_status |= ATH9K_RXERR_DECRYPT; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 25d3ef4c338..c0c3464d3a8 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #include <linux/nl80211.h> | 17 | #include <linux/nl80211.h> |
| 18 | #include <linux/pm_qos_params.h> | ||
| 19 | #include "ath9k.h" | 18 | #include "ath9k.h" |
| 20 | #include "btcoex.h" | 19 | #include "btcoex.h" |
| 21 | 20 | ||
| @@ -245,11 +244,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
| 245 | * the relevant bits of the h/w. | 244 | * the relevant bits of the h/w. |
| 246 | */ | 245 | */ |
| 247 | ath9k_hw_set_interrupts(ah, 0); | 246 | ath9k_hw_set_interrupts(ah, 0); |
| 248 | ath_drain_all_txq(sc, false); | 247 | stopped = ath_drain_all_txq(sc, false); |
| 249 | 248 | ||
| 250 | spin_lock_bh(&sc->rx.pcu_lock); | 249 | spin_lock_bh(&sc->rx.pcu_lock); |
| 251 | 250 | ||
| 252 | stopped = ath_stoprecv(sc); | 251 | if (!ath_stoprecv(sc)) |
| 252 | stopped = false; | ||
| 253 | 253 | ||
| 254 | /* XXX: do not flush receive queue here. We don't want | 254 | /* XXX: do not flush receive queue here. We don't want |
| 255 | * to flush data frames already in queue because of | 255 | * to flush data frames already in queue because of |
| @@ -1244,7 +1244,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
| 1244 | ath9k_btcoex_timer_resume(sc); | 1244 | ath9k_btcoex_timer_resume(sc); |
| 1245 | } | 1245 | } |
| 1246 | 1246 | ||
| 1247 | pm_qos_update_request(&ath9k_pm_qos_req, 55); | 1247 | pm_qos_update_request(&sc->pm_qos_req, 55); |
| 1248 | 1248 | ||
| 1249 | mutex_unlock: | 1249 | mutex_unlock: |
| 1250 | mutex_unlock(&sc->mutex); | 1250 | mutex_unlock(&sc->mutex); |
| @@ -1423,7 +1423,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
| 1423 | 1423 | ||
| 1424 | sc->sc_flags |= SC_OP_INVALID; | 1424 | sc->sc_flags |= SC_OP_INVALID; |
| 1425 | 1425 | ||
| 1426 | pm_qos_update_request(&ath9k_pm_qos_req, PM_QOS_DEFAULT_VALUE); | 1426 | pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE); |
| 1427 | 1427 | ||
| 1428 | mutex_unlock(&sc->mutex); | 1428 | mutex_unlock(&sc->mutex); |
| 1429 | 1429 | ||
| @@ -1520,7 +1520,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
| 1520 | struct ath_softc *sc = aphy->sc; | 1520 | struct ath_softc *sc = aphy->sc; |
| 1521 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1521 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
| 1522 | struct ath_vif *avp = (void *)vif->drv_priv; | 1522 | struct ath_vif *avp = (void *)vif->drv_priv; |
| 1523 | int i; | ||
| 1524 | 1523 | ||
| 1525 | ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); | 1524 | ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); |
| 1526 | 1525 | ||
| @@ -1534,21 +1533,24 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
| 1534 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || | 1533 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
| 1535 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || | 1534 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || |
| 1536 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { | 1535 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { |
| 1536 | /* Disable SWBA interrupt */ | ||
| 1537 | sc->sc_ah->imask &= ~ATH9K_INT_SWBA; | ||
| 1537 | ath9k_ps_wakeup(sc); | 1538 | ath9k_ps_wakeup(sc); |
| 1539 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); | ||
| 1538 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1540 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
| 1539 | ath9k_ps_restore(sc); | 1541 | ath9k_ps_restore(sc); |
| 1542 | tasklet_kill(&sc->bcon_tasklet); | ||
| 1540 | } | 1543 | } |
| 1541 | 1544 | ||
| 1542 | ath_beacon_return(sc, avp); | 1545 | ath_beacon_return(sc, avp); |
| 1543 | sc->sc_flags &= ~SC_OP_BEACONS; | 1546 | sc->sc_flags &= ~SC_OP_BEACONS; |
| 1544 | 1547 | ||
| 1545 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | 1548 | if (sc->nbcnvifs) { |
| 1546 | if (sc->beacon.bslot[i] == vif) { | 1549 | /* Re-enable SWBA interrupt */ |
| 1547 | printk(KERN_DEBUG "%s: vif had allocated beacon " | 1550 | sc->sc_ah->imask |= ATH9K_INT_SWBA; |
| 1548 | "slot\n", __func__); | 1551 | ath9k_ps_wakeup(sc); |
| 1549 | sc->beacon.bslot[i] = NULL; | 1552 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); |
| 1550 | sc->beacon.bslot_aphy[i] = NULL; | 1553 | ath9k_ps_restore(sc); |
| 1551 | } | ||
| 1552 | } | 1554 | } |
| 1553 | 1555 | ||
| 1554 | sc->nvifs--; | 1556 | sc->nvifs--; |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 1a62e351ec7..fdc2ec52b42 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
| @@ -838,6 +838,10 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
| 838 | struct ath_rx_status *rx_stats, | 838 | struct ath_rx_status *rx_stats, |
| 839 | bool *decrypt_error) | 839 | bool *decrypt_error) |
| 840 | { | 840 | { |
| 841 | #define is_mc_or_valid_tkip_keyix ((is_mc || \ | ||
| 842 | (rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && \ | ||
| 843 | test_bit(rx_stats->rs_keyix, common->tkip_keymap)))) | ||
| 844 | |||
| 841 | struct ath_hw *ah = common->ah; | 845 | struct ath_hw *ah = common->ah; |
| 842 | __le16 fc; | 846 | __le16 fc; |
| 843 | u8 rx_status_len = ah->caps.rx_status_len; | 847 | u8 rx_status_len = ah->caps.rx_status_len; |
| @@ -879,15 +883,18 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
| 879 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { | 883 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { |
| 880 | *decrypt_error = true; | 884 | *decrypt_error = true; |
| 881 | } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { | 885 | } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { |
| 886 | bool is_mc; | ||
| 882 | /* | 887 | /* |
| 883 | * The MIC error bit is only valid if the frame | 888 | * The MIC error bit is only valid if the frame |
| 884 | * is not a control frame or fragment, and it was | 889 | * is not a control frame or fragment, and it was |
| 885 | * decrypted using a valid TKIP key. | 890 | * decrypted using a valid TKIP key. |
| 886 | */ | 891 | */ |
| 892 | is_mc = !!is_multicast_ether_addr(hdr->addr1); | ||
| 893 | |||
| 887 | if (!ieee80211_is_ctl(fc) && | 894 | if (!ieee80211_is_ctl(fc) && |
| 888 | !ieee80211_has_morefrags(fc) && | 895 | !ieee80211_has_morefrags(fc) && |
| 889 | !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && | 896 | !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && |
| 890 | test_bit(rx_stats->rs_keyix, common->tkip_keymap)) | 897 | is_mc_or_valid_tkip_keyix) |
| 891 | rxs->flag |= RX_FLAG_MMIC_ERROR; | 898 | rxs->flag |= RX_FLAG_MMIC_ERROR; |
| 892 | else | 899 | else |
| 893 | rx_stats->rs_status &= ~ATH9K_RXERR_MIC; | 900 | rx_stats->rs_status &= ~ATH9K_RXERR_MIC; |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index dddf579aacf..2c6a22fbb0f 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
| @@ -984,11 +984,13 @@ enum { | |||
| 984 | #define AR9287_GPIO_IN_VAL_S 11 | 984 | #define AR9287_GPIO_IN_VAL_S 11 |
| 985 | #define AR9271_GPIO_IN_VAL 0xFFFF0000 | 985 | #define AR9271_GPIO_IN_VAL 0xFFFF0000 |
| 986 | #define AR9271_GPIO_IN_VAL_S 16 | 986 | #define AR9271_GPIO_IN_VAL_S 16 |
| 987 | #define AR9300_GPIO_IN_VAL 0x0001FFFF | ||
| 988 | #define AR9300_GPIO_IN_VAL_S 0 | ||
| 989 | #define AR7010_GPIO_IN_VAL 0x0000FFFF | 987 | #define AR7010_GPIO_IN_VAL 0x0000FFFF |
| 990 | #define AR7010_GPIO_IN_VAL_S 0 | 988 | #define AR7010_GPIO_IN_VAL_S 0 |
| 991 | 989 | ||
| 990 | #define AR_GPIO_IN 0x404c | ||
| 991 | #define AR9300_GPIO_IN_VAL 0x0001FFFF | ||
| 992 | #define AR9300_GPIO_IN_VAL_S 0 | ||
| 993 | |||
| 992 | #define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c) | 994 | #define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c) |
| 993 | #define AR_GPIO_OE_OUT_DRV 0x3 | 995 | #define AR_GPIO_OE_OUT_DRV 0x3 |
| 994 | #define AR_GPIO_OE_OUT_DRV_NO 0x0 | 996 | #define AR_GPIO_OE_OUT_DRV_NO 0x0 |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index f2ade2402ce..aff04789f79 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -1120,7 +1120,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
| 1120 | } | 1120 | } |
| 1121 | } | 1121 | } |
| 1122 | 1122 | ||
| 1123 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | 1123 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) |
| 1124 | { | 1124 | { |
| 1125 | struct ath_hw *ah = sc->sc_ah; | 1125 | struct ath_hw *ah = sc->sc_ah; |
| 1126 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1126 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
| @@ -1128,7 +1128,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
| 1128 | int i, npend = 0; | 1128 | int i, npend = 0; |
| 1129 | 1129 | ||
| 1130 | if (sc->sc_flags & SC_OP_INVALID) | 1130 | if (sc->sc_flags & SC_OP_INVALID) |
| 1131 | return; | 1131 | return true; |
| 1132 | 1132 | ||
| 1133 | /* Stop beacon queue */ | 1133 | /* Stop beacon queue */ |
| 1134 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1134 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
| @@ -1142,25 +1142,15 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
| 1142 | } | 1142 | } |
| 1143 | } | 1143 | } |
| 1144 | 1144 | ||
| 1145 | if (npend) { | 1145 | if (npend) |
| 1146 | int r; | 1146 | ath_print(common, ATH_DBG_FATAL, "Failed to stop TX DMA!\n"); |
| 1147 | |||
| 1148 | ath_print(common, ATH_DBG_FATAL, | ||
| 1149 | "Failed to stop TX DMA. Resetting hardware!\n"); | ||
| 1150 | |||
| 1151 | spin_lock_bh(&sc->sc_resetlock); | ||
| 1152 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); | ||
| 1153 | if (r) | ||
| 1154 | ath_print(common, ATH_DBG_FATAL, | ||
| 1155 | "Unable to reset hardware; reset status %d\n", | ||
| 1156 | r); | ||
| 1157 | spin_unlock_bh(&sc->sc_resetlock); | ||
| 1158 | } | ||
| 1159 | 1147 | ||
| 1160 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | 1148 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { |
| 1161 | if (ATH_TXQ_SETUP(sc, i)) | 1149 | if (ATH_TXQ_SETUP(sc, i)) |
| 1162 | ath_draintxq(sc, &sc->tx.txq[i], retry_tx); | 1150 | ath_draintxq(sc, &sc->tx.txq[i], retry_tx); |
| 1163 | } | 1151 | } |
| 1152 | |||
| 1153 | return !npend; | ||
| 1164 | } | 1154 | } |
| 1165 | 1155 | ||
| 1166 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) | 1156 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) |
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index ae6c006bbc5..546b4e4ec5e 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c | |||
| @@ -291,7 +291,8 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) | |||
| 291 | 291 | ||
| 292 | if (SUPP(CARL9170FW_WLANTX_CAB)) { | 292 | if (SUPP(CARL9170FW_WLANTX_CAB)) { |
| 293 | ar->hw->wiphy->interface_modes |= | 293 | ar->hw->wiphy->interface_modes |= |
| 294 | BIT(NL80211_IFTYPE_AP); | 294 | BIT(NL80211_IFTYPE_AP) | |
| 295 | BIT(NL80211_IFTYPE_P2P_GO); | ||
| 295 | } | 296 | } |
| 296 | } | 297 | } |
| 297 | 298 | ||
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index a314c2c2bfb..dc7b30b170d 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
| @@ -1631,7 +1631,8 @@ void *carl9170_alloc(size_t priv_size) | |||
| 1631 | * supports these modes. The code which will add the | 1631 | * supports these modes. The code which will add the |
| 1632 | * additional interface_modes is in fw.c. | 1632 | * additional interface_modes is in fw.c. |
| 1633 | */ | 1633 | */ |
| 1634 | hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); | 1634 | hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
| 1635 | BIT(NL80211_IFTYPE_P2P_CLIENT); | ||
| 1635 | 1636 | ||
| 1636 | hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | | 1637 | hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | |
| 1637 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 1638 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index b575c865142..7e6506a77bb 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c | |||
| @@ -810,7 +810,7 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) | |||
| 810 | 810 | ||
| 811 | mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION | | 811 | mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION | |
| 812 | AR9170_TX_MAC_BACKOFF); | 812 | AR9170_TX_MAC_BACKOFF); |
| 813 | mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) && | 813 | mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) & |
| 814 | AR9170_TX_MAC_QOS); | 814 | AR9170_TX_MAC_QOS); |
| 815 | 815 | ||
| 816 | no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK); | 816 | no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK); |
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index e5685dc317a..b4de0ca10fe 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
| @@ -1170,7 +1170,6 @@ static void if_sdio_remove(struct sdio_func *func) | |||
| 1170 | lbs_deb_sdio("call remove card\n"); | 1170 | lbs_deb_sdio("call remove card\n"); |
| 1171 | lbs_stop_card(card->priv); | 1171 | lbs_stop_card(card->priv); |
| 1172 | lbs_remove_card(card->priv); | 1172 | lbs_remove_card(card->priv); |
| 1173 | card->priv->surpriseremoved = 1; | ||
| 1174 | 1173 | ||
| 1175 | flush_workqueue(card->workqueue); | 1174 | flush_workqueue(card->workqueue); |
| 1176 | destroy_workqueue(card->workqueue); | 1175 | destroy_workqueue(card->workqueue); |
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 79bcb4e5d2c..ecd4d04b2c3 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c | |||
| @@ -1055,7 +1055,6 @@ static int __devexit libertas_spi_remove(struct spi_device *spi) | |||
| 1055 | lbs_stop_card(priv); | 1055 | lbs_stop_card(priv); |
| 1056 | lbs_remove_card(priv); /* will call free_netdev */ | 1056 | lbs_remove_card(priv); /* will call free_netdev */ |
| 1057 | 1057 | ||
| 1058 | priv->surpriseremoved = 1; | ||
| 1059 | free_irq(spi->irq, card); | 1058 | free_irq(spi->irq, card); |
| 1060 | if_spi_terminate_spi_thread(card); | 1059 | if_spi_terminate_spi_thread(card); |
| 1061 | if (card->pdata->teardown) | 1060 | if (card->pdata->teardown) |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 46b88b118c9..fcd1bbfc632 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
| @@ -915,8 +915,6 @@ void lbs_remove_card(struct lbs_private *priv) | |||
| 915 | 915 | ||
| 916 | lbs_free_adapter(priv); | 916 | lbs_free_adapter(priv); |
| 917 | lbs_cfg_free(priv); | 917 | lbs_cfg_free(priv); |
| 918 | |||
| 919 | priv->dev = NULL; | ||
| 920 | free_netdev(dev); | 918 | free_netdev(dev); |
| 921 | 919 | ||
| 922 | lbs_deb_leave(LBS_DEB_MAIN); | 920 | lbs_deb_leave(LBS_DEB_MAIN); |
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index e8e2d0f4763..f3d396e7544 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c | |||
| @@ -1392,10 +1392,9 @@ static void orinoco_process_scan_results(struct work_struct *work) | |||
| 1392 | orinoco_add_hostscan_results(priv, buf, len); | 1392 | orinoco_add_hostscan_results(priv, buf, len); |
| 1393 | 1393 | ||
| 1394 | kfree(buf); | 1394 | kfree(buf); |
| 1395 | } else if (priv->scan_request) { | 1395 | } else { |
| 1396 | /* Either abort or complete the scan */ | 1396 | /* Either abort or complete the scan */ |
| 1397 | cfg80211_scan_done(priv->scan_request, (len < 0)); | 1397 | orinoco_scan_done(priv, (len < 0)); |
| 1398 | priv->scan_request = NULL; | ||
| 1399 | } | 1398 | } |
| 1400 | 1399 | ||
| 1401 | spin_lock_irqsave(&priv->scan_lock, flags); | 1400 | spin_lock_irqsave(&priv->scan_lock, flags); |
| @@ -1684,6 +1683,8 @@ static int __orinoco_down(struct orinoco_private *priv) | |||
| 1684 | hermes_write_regn(hw, EVACK, 0xffff); | 1683 | hermes_write_regn(hw, EVACK, 0xffff); |
| 1685 | } | 1684 | } |
| 1686 | 1685 | ||
| 1686 | orinoco_scan_done(priv, true); | ||
| 1687 | |||
| 1687 | /* firmware will have to reassociate */ | 1688 | /* firmware will have to reassociate */ |
| 1688 | netif_carrier_off(dev); | 1689 | netif_carrier_off(dev); |
| 1689 | priv->last_linkstatus = 0xffff; | 1690 | priv->last_linkstatus = 0xffff; |
| @@ -1762,10 +1763,7 @@ void orinoco_reset(struct work_struct *work) | |||
| 1762 | orinoco_unlock(priv, &flags); | 1763 | orinoco_unlock(priv, &flags); |
| 1763 | 1764 | ||
| 1764 | /* Scanning support: Notify scan cancellation */ | 1765 | /* Scanning support: Notify scan cancellation */ |
| 1765 | if (priv->scan_request) { | 1766 | orinoco_scan_done(priv, true); |
| 1766 | cfg80211_scan_done(priv->scan_request, 1); | ||
| 1767 | priv->scan_request = NULL; | ||
| 1768 | } | ||
| 1769 | 1767 | ||
| 1770 | if (priv->hard_reset) { | 1768 | if (priv->hard_reset) { |
| 1771 | err = (*priv->hard_reset)(priv); | 1769 | err = (*priv->hard_reset)(priv); |
| @@ -1813,6 +1811,12 @@ static int __orinoco_commit(struct orinoco_private *priv) | |||
| 1813 | struct net_device *dev = priv->ndev; | 1811 | struct net_device *dev = priv->ndev; |
| 1814 | int err = 0; | 1812 | int err = 0; |
| 1815 | 1813 | ||
| 1814 | /* If we've called commit, we are reconfiguring or bringing the | ||
| 1815 | * interface up. Maintaining countermeasures across this would | ||
| 1816 | * be confusing, so note that we've disabled them. The port will | ||
| 1817 | * be enabled later in orinoco_commit or __orinoco_up. */ | ||
| 1818 | priv->tkip_cm_active = 0; | ||
| 1819 | |||
| 1816 | err = orinoco_hw_program_rids(priv); | 1820 | err = orinoco_hw_program_rids(priv); |
| 1817 | 1821 | ||
| 1818 | /* FIXME: what about netif_tx_lock */ | 1822 | /* FIXME: what about netif_tx_lock */ |
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index 71b3d68b940..32954c4b243 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c | |||
| @@ -151,20 +151,20 @@ orinoco_cs_config(struct pcmcia_device *link) | |||
| 151 | goto failed; | 151 | goto failed; |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
| 155 | if (ret) | ||
| 156 | goto failed; | ||
| 157 | |||
| 158 | /* We initialize the hermes structure before completing PCMCIA | ||
| 159 | * configuration just in case the interrupt handler gets | ||
| 160 | * called. */ | ||
| 161 | mem = ioport_map(link->resource[0]->start, | 154 | mem = ioport_map(link->resource[0]->start, |
| 162 | resource_size(link->resource[0])); | 155 | resource_size(link->resource[0])); |
| 163 | if (!mem) | 156 | if (!mem) |
| 164 | goto failed; | 157 | goto failed; |
| 165 | 158 | ||
| 159 | /* We initialize the hermes structure before completing PCMCIA | ||
| 160 | * configuration just in case the interrupt handler gets | ||
| 161 | * called. */ | ||
| 166 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); | 162 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); |
| 167 | 163 | ||
| 164 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
| 165 | if (ret) | ||
| 166 | goto failed; | ||
| 167 | |||
| 168 | ret = pcmcia_enable_device(link); | 168 | ret = pcmcia_enable_device(link); |
| 169 | if (ret) | 169 | if (ret) |
| 170 | goto failed; | 170 | goto failed; |
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c index 4300d9db7d8..86cb54c842e 100644 --- a/drivers/net/wireless/orinoco/scan.c +++ b/drivers/net/wireless/orinoco/scan.c | |||
| @@ -229,3 +229,11 @@ void orinoco_add_hostscan_results(struct orinoco_private *priv, | |||
| 229 | priv->scan_request = NULL; | 229 | priv->scan_request = NULL; |
| 230 | } | 230 | } |
| 231 | } | 231 | } |
| 232 | |||
| 233 | void orinoco_scan_done(struct orinoco_private *priv, bool abort) | ||
| 234 | { | ||
| 235 | if (priv->scan_request) { | ||
| 236 | cfg80211_scan_done(priv->scan_request, abort); | ||
| 237 | priv->scan_request = NULL; | ||
| 238 | } | ||
| 239 | } | ||
diff --git a/drivers/net/wireless/orinoco/scan.h b/drivers/net/wireless/orinoco/scan.h index 2dc4e046dbd..27281fb0a6d 100644 --- a/drivers/net/wireless/orinoco/scan.h +++ b/drivers/net/wireless/orinoco/scan.h | |||
| @@ -16,5 +16,6 @@ void orinoco_add_extscan_result(struct orinoco_private *priv, | |||
| 16 | void orinoco_add_hostscan_results(struct orinoco_private *dev, | 16 | void orinoco_add_hostscan_results(struct orinoco_private *dev, |
| 17 | unsigned char *buf, | 17 | unsigned char *buf, |
| 18 | size_t len); | 18 | size_t len); |
| 19 | void orinoco_scan_done(struct orinoco_private *priv, bool abort); | ||
| 19 | 20 | ||
| 20 | #endif /* _ORINOCO_SCAN_H_ */ | 21 | #endif /* _ORINOCO_SCAN_H_ */ |
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index fb859a5ad2e..db34c282e59 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c | |||
| @@ -214,21 +214,21 @@ spectrum_cs_config(struct pcmcia_device *link) | |||
| 214 | goto failed; | 214 | goto failed; |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
| 218 | if (ret) | ||
| 219 | goto failed; | ||
| 220 | |||
| 221 | /* We initialize the hermes structure before completing PCMCIA | ||
| 222 | * configuration just in case the interrupt handler gets | ||
| 223 | * called. */ | ||
| 224 | mem = ioport_map(link->resource[0]->start, | 217 | mem = ioport_map(link->resource[0]->start, |
| 225 | resource_size(link->resource[0])); | 218 | resource_size(link->resource[0])); |
| 226 | if (!mem) | 219 | if (!mem) |
| 227 | goto failed; | 220 | goto failed; |
| 228 | 221 | ||
| 222 | /* We initialize the hermes structure before completing PCMCIA | ||
| 223 | * configuration just in case the interrupt handler gets | ||
| 224 | * called. */ | ||
| 229 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); | 225 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); |
| 230 | hw->eeprom_pda = true; | 226 | hw->eeprom_pda = true; |
| 231 | 227 | ||
| 228 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
| 229 | if (ret) | ||
| 230 | goto failed; | ||
| 231 | |||
| 232 | ret = pcmcia_enable_device(link); | 232 | ret = pcmcia_enable_device(link); |
| 233 | if (ret) | 233 | if (ret) |
| 234 | goto failed; | 234 | goto failed; |
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index 93505f93bf9..e5afabee60d 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c | |||
| @@ -911,10 +911,10 @@ static int orinoco_ioctl_set_auth(struct net_device *dev, | |||
| 911 | */ | 911 | */ |
| 912 | if (param->value) { | 912 | if (param->value) { |
| 913 | priv->tkip_cm_active = 1; | 913 | priv->tkip_cm_active = 1; |
| 914 | ret = hermes_enable_port(hw, 0); | 914 | ret = hermes_disable_port(hw, 0); |
| 915 | } else { | 915 | } else { |
| 916 | priv->tkip_cm_active = 0; | 916 | priv->tkip_cm_active = 0; |
| 917 | ret = hermes_disable_port(hw, 0); | 917 | ret = hermes_enable_port(hw, 0); |
| 918 | } | 918 | } |
| 919 | break; | 919 | break; |
| 920 | 920 | ||
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 458bb57914a..cdbeec9f83e 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
| @@ -66,8 +66,8 @@ struct netfront_cb { | |||
| 66 | 66 | ||
| 67 | #define GRANT_INVALID_REF 0 | 67 | #define GRANT_INVALID_REF 0 |
| 68 | 68 | ||
| 69 | #define NET_TX_RING_SIZE __RING_SIZE((struct xen_netif_tx_sring *)0, PAGE_SIZE) | 69 | #define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE) |
| 70 | #define NET_RX_RING_SIZE __RING_SIZE((struct xen_netif_rx_sring *)0, PAGE_SIZE) | 70 | #define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE) |
| 71 | #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) | 71 | #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) |
| 72 | 72 | ||
| 73 | struct netfront_info { | 73 | struct netfront_info { |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 003170ea2e3..69546e9213d 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
| @@ -64,77 +64,6 @@ void pci_bus_remove_resources(struct pci_bus *bus) | |||
| 64 | } | 64 | } |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | static bool pci_bus_resource_better(struct resource *res1, bool pos1, | ||
| 68 | struct resource *res2, bool pos2) | ||
| 69 | { | ||
| 70 | /* If exactly one is positive decode, always prefer that one */ | ||
| 71 | if (pos1 != pos2) | ||
| 72 | return pos1 ? true : false; | ||
| 73 | |||
| 74 | /* Prefer the one that contains the highest address */ | ||
| 75 | if (res1->end != res2->end) | ||
| 76 | return (res1->end > res2->end) ? true : false; | ||
| 77 | |||
| 78 | /* Otherwise, prefer the one with highest "center of gravity" */ | ||
| 79 | if (res1->start != res2->start) | ||
| 80 | return (res1->start > res2->start) ? true : false; | ||
| 81 | |||
| 82 | /* Otherwise, choose one arbitrarily (but consistently) */ | ||
| 83 | return (res1 > res2) ? true : false; | ||
| 84 | } | ||
| 85 | |||
| 86 | static bool pci_bus_resource_positive(struct pci_bus *bus, struct resource *res) | ||
| 87 | { | ||
| 88 | struct pci_bus_resource *bus_res; | ||
| 89 | |||
| 90 | /* | ||
| 91 | * This relies on the fact that pci_bus.resource[] refers to P2P or | ||
| 92 | * CardBus bridge base/limit registers, which are always positively | ||
| 93 | * decoded. The pci_bus.resources list contains host bridge or | ||
| 94 | * subtractively decoded resources. | ||
| 95 | */ | ||
| 96 | list_for_each_entry(bus_res, &bus->resources, list) { | ||
| 97 | if (bus_res->res == res) | ||
| 98 | return (bus_res->flags & PCI_SUBTRACTIVE_DECODE) ? | ||
| 99 | false : true; | ||
| 100 | } | ||
| 101 | return true; | ||
| 102 | } | ||
| 103 | |||
| 104 | /* | ||
| 105 | * Find the next-best bus resource after the cursor "res". If the cursor is | ||
| 106 | * NULL, return the best resource. "Best" means that we prefer positive | ||
| 107 | * decode regions over subtractive decode, then those at higher addresses. | ||
| 108 | */ | ||
| 109 | static struct resource *pci_bus_find_resource_prev(struct pci_bus *bus, | ||
| 110 | unsigned int type, | ||
| 111 | struct resource *res) | ||
| 112 | { | ||
| 113 | bool res_pos, r_pos, prev_pos = false; | ||
| 114 | struct resource *r, *prev = NULL; | ||
| 115 | int i; | ||
| 116 | |||
| 117 | res_pos = pci_bus_resource_positive(bus, res); | ||
| 118 | pci_bus_for_each_resource(bus, r, i) { | ||
| 119 | if (!r) | ||
| 120 | continue; | ||
| 121 | |||
| 122 | if ((r->flags & IORESOURCE_TYPE_BITS) != type) | ||
| 123 | continue; | ||
| 124 | |||
| 125 | r_pos = pci_bus_resource_positive(bus, r); | ||
| 126 | if (!res || pci_bus_resource_better(res, res_pos, r, r_pos)) { | ||
| 127 | if (!prev || pci_bus_resource_better(r, r_pos, | ||
| 128 | prev, prev_pos)) { | ||
| 129 | prev = r; | ||
| 130 | prev_pos = r_pos; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | return prev; | ||
| 136 | } | ||
| 137 | |||
| 138 | /** | 67 | /** |
| 139 | * pci_bus_alloc_resource - allocate a resource from a parent bus | 68 | * pci_bus_alloc_resource - allocate a resource from a parent bus |
| 140 | * @bus: PCI bus | 69 | * @bus: PCI bus |
| @@ -160,10 +89,9 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
| 160 | resource_size_t), | 89 | resource_size_t), |
| 161 | void *alignf_data) | 90 | void *alignf_data) |
| 162 | { | 91 | { |
| 163 | int ret = -ENOMEM; | 92 | int i, ret = -ENOMEM; |
| 164 | struct resource *r; | 93 | struct resource *r; |
| 165 | resource_size_t max = -1; | 94 | resource_size_t max = -1; |
| 166 | unsigned int type = res->flags & IORESOURCE_TYPE_BITS; | ||
| 167 | 95 | ||
| 168 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; | 96 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; |
| 169 | 97 | ||
| @@ -171,9 +99,10 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
| 171 | if (!(res->flags & IORESOURCE_MEM_64)) | 99 | if (!(res->flags & IORESOURCE_MEM_64)) |
| 172 | max = PCIBIOS_MAX_MEM_32; | 100 | max = PCIBIOS_MAX_MEM_32; |
| 173 | 101 | ||
| 174 | /* Look for space at highest addresses first */ | 102 | pci_bus_for_each_resource(bus, r, i) { |
| 175 | r = pci_bus_find_resource_prev(bus, type, NULL); | 103 | if (!r) |
| 176 | for ( ; r; r = pci_bus_find_resource_prev(bus, type, r)) { | 104 | continue; |
| 105 | |||
| 177 | /* type_mask must match */ | 106 | /* type_mask must match */ |
| 178 | if ((res->flags ^ r->flags) & type_mask) | 107 | if ((res->flags ^ r->flags) & type_mask) |
| 179 | continue; | 108 | continue; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 6f9350cabbd..313c0bda0a8 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -2329,6 +2329,9 @@ static void __devinit nvbridge_check_legacy_irq_routing(struct pci_dev *dev) | |||
| 2329 | { | 2329 | { |
| 2330 | u32 cfg; | 2330 | u32 cfg; |
| 2331 | 2331 | ||
| 2332 | if (!pci_find_capability(dev, PCI_CAP_ID_HT)) | ||
| 2333 | return; | ||
| 2334 | |||
| 2332 | pci_read_config_dword(dev, 0x74, &cfg); | 2335 | pci_read_config_dword(dev, 0x74, &cfg); |
| 2333 | 2336 | ||
| 2334 | if (cfg & ((1 << 2) | (1 << 15))) { | 2337 | if (cfg & ((1 << 2) | (1 << 15))) { |
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 2d73dfcecdb..57313f4658b 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
| @@ -180,7 +180,7 @@ struct pnp_protocol pnpacpi_protocol = { | |||
| 180 | }; | 180 | }; |
| 181 | EXPORT_SYMBOL(pnpacpi_protocol); | 181 | EXPORT_SYMBOL(pnpacpi_protocol); |
| 182 | 182 | ||
| 183 | static char *pnpacpi_get_id(struct acpi_device *device) | 183 | static char *__init pnpacpi_get_id(struct acpi_device *device) |
| 184 | { | 184 | { |
| 185 | struct acpi_hardware_id *id; | 185 | struct acpi_hardware_id *id; |
| 186 | 186 | ||
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 51237fbb1bb..6d20b0454a1 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c | |||
| @@ -231,8 +231,7 @@ static int tps6586x_dvm_voltages[] = { | |||
| 231 | }; | 231 | }; |
| 232 | 232 | ||
| 233 | #define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits, \ | 233 | #define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits, \ |
| 234 | ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ | 234 | ereg0, ebit0, ereg1, ebit1) \ |
| 235 | { \ | ||
| 236 | .desc = { \ | 235 | .desc = { \ |
| 237 | .name = "REG-" #_id, \ | 236 | .name = "REG-" #_id, \ |
| 238 | .ops = &tps6586x_regulator_##_ops, \ | 237 | .ops = &tps6586x_regulator_##_ops, \ |
| @@ -248,18 +247,26 @@ static int tps6586x_dvm_voltages[] = { | |||
| 248 | .enable_bit[0] = (ebit0), \ | 247 | .enable_bit[0] = (ebit0), \ |
| 249 | .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ | 248 | .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ |
| 250 | .enable_bit[1] = (ebit1), \ | 249 | .enable_bit[1] = (ebit1), \ |
| 251 | .voltages = tps6586x_##vdata##_voltages, \ | 250 | .voltages = tps6586x_##vdata##_voltages, |
| 252 | } | 251 | |
| 252 | #define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ | ||
| 253 | .go_reg = TPS6586X_##goreg, \ | ||
| 254 | .go_bit = (gobit), | ||
| 253 | 255 | ||
| 254 | #define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \ | 256 | #define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \ |
| 255 | ereg0, ebit0, ereg1, ebit1) \ | 257 | ereg0, ebit0, ereg1, ebit1) \ |
| 258 | { \ | ||
| 256 | TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits, \ | 259 | TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits, \ |
| 257 | ereg0, ebit0, ereg1, ebit1, 0, 0) | 260 | ereg0, ebit0, ereg1, ebit1) \ |
| 261 | } | ||
| 258 | 262 | ||
| 259 | #define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \ | 263 | #define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \ |
| 260 | ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ | 264 | ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ |
| 265 | { \ | ||
| 261 | TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits, \ | 266 | TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits, \ |
| 262 | ereg0, ebit0, ereg1, ebit1, goreg, gobit) | 267 | ereg0, ebit0, ereg1, ebit1) \ |
| 268 | TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ | ||
| 269 | } | ||
| 263 | 270 | ||
| 264 | static struct tps6586x_regulator tps6586x_regulator[] = { | 271 | static struct tps6586x_regulator tps6586x_regulator[] = { |
| 265 | TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0), | 272 | TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0), |
| @@ -267,11 +274,11 @@ static struct tps6586x_regulator tps6586x_regulator[] = { | |||
| 267 | TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), | 274 | TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), |
| 268 | TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), | 275 | TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), |
| 269 | TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5), | 276 | TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5), |
| 270 | TPS6586X_LDO(LDO_8, ldo, SUPPLYV1, 5, 3, ENC, 6, END, 6), | 277 | TPS6586X_LDO(LDO_8, ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6), |
| 271 | TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), | 278 | TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), |
| 272 | TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, ENE, 7, ENE, 7), | 279 | TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), |
| 273 | TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), | 280 | TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), |
| 274 | TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 1, END, 1), | 281 | TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), |
| 275 | 282 | ||
| 276 | TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6), | 283 | TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6), |
| 277 | TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6), | 284 | TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6), |
| @@ -290,6 +297,10 @@ static inline int tps6586x_regulator_preinit(struct device *parent, | |||
| 290 | uint8_t val1, val2; | 297 | uint8_t val1, val2; |
| 291 | int ret; | 298 | int ret; |
| 292 | 299 | ||
| 300 | if (ri->enable_reg[0] == ri->enable_reg[1] && | ||
| 301 | ri->enable_bit[0] == ri->enable_bit[1]) | ||
| 302 | return 0; | ||
| 303 | |||
| 293 | ret = tps6586x_read(parent, ri->enable_reg[0], &val1); | 304 | ret = tps6586x_read(parent, ri->enable_reg[0], &val1); |
| 294 | if (ret) | 305 | if (ret) |
| 295 | return ret; | 306 | return ret; |
| @@ -298,14 +309,14 @@ static inline int tps6586x_regulator_preinit(struct device *parent, | |||
| 298 | if (ret) | 309 | if (ret) |
| 299 | return ret; | 310 | return ret; |
| 300 | 311 | ||
| 301 | if (!(val2 & ri->enable_bit[1])) | 312 | if (!(val2 & (1 << ri->enable_bit[1]))) |
| 302 | return 0; | 313 | return 0; |
| 303 | 314 | ||
| 304 | /* | 315 | /* |
| 305 | * The regulator is on, but it's enabled with the bit we don't | 316 | * The regulator is on, but it's enabled with the bit we don't |
| 306 | * want to use, so we switch the enable bits | 317 | * want to use, so we switch the enable bits |
| 307 | */ | 318 | */ |
| 308 | if (!(val1 & ri->enable_bit[0])) { | 319 | if (!(val1 & (1 << ri->enable_bit[0]))) { |
| 309 | ret = tps6586x_set_bits(parent, ri->enable_reg[0], | 320 | ret = tps6586x_set_bits(parent, ri->enable_reg[0], |
| 310 | 1 << ri->enable_bit[0]); | 321 | 1 << ri->enable_bit[0]); |
| 311 | if (ret) | 322 | if (ret) |
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index d37c7331f24..0bcd5806bd9 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
| @@ -156,6 +156,8 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, | |||
| 156 | if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) || | 156 | if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) || |
| 157 | a_status & ZFCP_STATUS_COMMON_ERP_FAILED) | 157 | a_status & ZFCP_STATUS_COMMON_ERP_FAILED) |
| 158 | return 0; | 158 | return 0; |
| 159 | if (p_status & ZFCP_STATUS_COMMON_NOESC) | ||
| 160 | return need; | ||
| 159 | if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED)) | 161 | if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED)) |
| 160 | need = ZFCP_ERP_ACTION_REOPEN_ADAPTER; | 162 | need = ZFCP_ERP_ACTION_REOPEN_ADAPTER; |
| 161 | /* fall through */ | 163 | /* fall through */ |
| @@ -188,6 +190,9 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, | |||
| 188 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, | 190 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, |
| 189 | &zfcp_sdev->status); | 191 | &zfcp_sdev->status); |
| 190 | erp_action = &zfcp_sdev->erp_action; | 192 | erp_action = &zfcp_sdev->erp_action; |
| 193 | memset(erp_action, 0, sizeof(struct zfcp_erp_action)); | ||
| 194 | erp_action->port = port; | ||
| 195 | erp_action->sdev = sdev; | ||
| 191 | if (!(atomic_read(&zfcp_sdev->status) & | 196 | if (!(atomic_read(&zfcp_sdev->status) & |
| 192 | ZFCP_STATUS_COMMON_RUNNING)) | 197 | ZFCP_STATUS_COMMON_RUNNING)) |
| 193 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; | 198 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; |
| @@ -200,6 +205,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, | |||
| 200 | zfcp_erp_action_dismiss_port(port); | 205 | zfcp_erp_action_dismiss_port(port); |
| 201 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); | 206 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); |
| 202 | erp_action = &port->erp_action; | 207 | erp_action = &port->erp_action; |
| 208 | memset(erp_action, 0, sizeof(struct zfcp_erp_action)); | ||
| 209 | erp_action->port = port; | ||
| 203 | if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING)) | 210 | if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING)) |
| 204 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; | 211 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; |
| 205 | break; | 212 | break; |
| @@ -209,6 +216,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, | |||
| 209 | zfcp_erp_action_dismiss_adapter(adapter); | 216 | zfcp_erp_action_dismiss_adapter(adapter); |
| 210 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); | 217 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); |
| 211 | erp_action = &adapter->erp_action; | 218 | erp_action = &adapter->erp_action; |
| 219 | memset(erp_action, 0, sizeof(struct zfcp_erp_action)); | ||
| 212 | if (!(atomic_read(&adapter->status) & | 220 | if (!(atomic_read(&adapter->status) & |
| 213 | ZFCP_STATUS_COMMON_RUNNING)) | 221 | ZFCP_STATUS_COMMON_RUNNING)) |
| 214 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; | 222 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; |
| @@ -218,10 +226,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, | |||
| 218 | return NULL; | 226 | return NULL; |
| 219 | } | 227 | } |
| 220 | 228 | ||
| 221 | memset(erp_action, 0, sizeof(struct zfcp_erp_action)); | ||
| 222 | erp_action->adapter = adapter; | 229 | erp_action->adapter = adapter; |
| 223 | erp_action->port = port; | ||
| 224 | erp_action->sdev = sdev; | ||
| 225 | erp_action->action = need; | 230 | erp_action->action = need; |
| 226 | erp_action->status = act_status; | 231 | erp_action->status = act_status; |
| 227 | 232 | ||
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index be031745714..2eb7dd56ab8 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
| @@ -851,7 +851,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *scmnd) | |||
| 851 | 851 | ||
| 852 | zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); | 852 | zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); |
| 853 | 853 | ||
| 854 | req->data = zfcp_sdev; | 854 | req->data = sdev; |
| 855 | req->handler = zfcp_fsf_abort_fcp_command_handler; | 855 | req->handler = zfcp_fsf_abort_fcp_command_handler; |
| 856 | req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; | 856 | req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; |
| 857 | req->qtcb->header.port_handle = zfcp_sdev->port->handle; | 857 | req->qtcb->header.port_handle = zfcp_sdev->port->handle; |
| @@ -2069,8 +2069,6 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req) | |||
| 2069 | struct fcp_resp_with_ext *fcp_rsp; | 2069 | struct fcp_resp_with_ext *fcp_rsp; |
| 2070 | unsigned long flags; | 2070 | unsigned long flags; |
| 2071 | 2071 | ||
| 2072 | zfcp_fsf_fcp_handler_common(req); | ||
| 2073 | |||
| 2074 | read_lock_irqsave(&req->adapter->abort_lock, flags); | 2072 | read_lock_irqsave(&req->adapter->abort_lock, flags); |
| 2075 | 2073 | ||
| 2076 | scpnt = req->data; | 2074 | scpnt = req->data; |
| @@ -2079,6 +2077,8 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req) | |||
| 2079 | return; | 2077 | return; |
| 2080 | } | 2078 | } |
| 2081 | 2079 | ||
| 2080 | zfcp_fsf_fcp_handler_common(req); | ||
| 2081 | |||
| 2082 | if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) { | 2082 | if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) { |
| 2083 | set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED); | 2083 | set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED); |
| 2084 | goto skip_fsfstatus; | 2084 | goto skip_fsfstatus; |
| @@ -2170,12 +2170,13 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd) | |||
| 2170 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; | 2170 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; |
| 2171 | struct zfcp_qdio *qdio = adapter->qdio; | 2171 | struct zfcp_qdio *qdio = adapter->qdio; |
| 2172 | struct fsf_qtcb_bottom_io *io; | 2172 | struct fsf_qtcb_bottom_io *io; |
| 2173 | unsigned long flags; | ||
| 2173 | 2174 | ||
| 2174 | if (unlikely(!(atomic_read(&zfcp_sdev->status) & | 2175 | if (unlikely(!(atomic_read(&zfcp_sdev->status) & |
| 2175 | ZFCP_STATUS_COMMON_UNBLOCKED))) | 2176 | ZFCP_STATUS_COMMON_UNBLOCKED))) |
| 2176 | return -EBUSY; | 2177 | return -EBUSY; |
| 2177 | 2178 | ||
| 2178 | spin_lock(&qdio->req_q_lock); | 2179 | spin_lock_irqsave(&qdio->req_q_lock, flags); |
| 2179 | if (atomic_read(&qdio->req_q_free) <= 0) { | 2180 | if (atomic_read(&qdio->req_q_free) <= 0) { |
| 2180 | atomic_inc(&qdio->req_q_full); | 2181 | atomic_inc(&qdio->req_q_full); |
| 2181 | goto out; | 2182 | goto out; |
| @@ -2239,7 +2240,7 @@ failed_scsi_cmnd: | |||
| 2239 | zfcp_fsf_req_free(req); | 2240 | zfcp_fsf_req_free(req); |
| 2240 | scsi_cmnd->host_scribble = NULL; | 2241 | scsi_cmnd->host_scribble = NULL; |
| 2241 | out: | 2242 | out: |
| 2242 | spin_unlock(&qdio->req_q_lock); | 2243 | spin_unlock_irqrestore(&qdio->req_q_lock, flags); |
| 2243 | return retval; | 2244 | return retval; |
| 2244 | } | 2245 | } |
| 2245 | 2246 | ||
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 6bd2dbc4c31..63529ed801e 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
| @@ -76,8 +76,8 @@ static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) | |||
| 76 | scpnt->scsi_done(scpnt); | 76 | scpnt->scsi_done(scpnt); |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt, | 79 | static |
| 80 | void (*done) (struct scsi_cmnd *)) | 80 | int zfcp_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scpnt) |
| 81 | { | 81 | { |
| 82 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); | 82 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); |
| 83 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; | 83 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; |
| @@ -87,7 +87,6 @@ static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt, | |||
| 87 | /* reset the status for this request */ | 87 | /* reset the status for this request */ |
| 88 | scpnt->result = 0; | 88 | scpnt->result = 0; |
| 89 | scpnt->host_scribble = NULL; | 89 | scpnt->host_scribble = NULL; |
| 90 | scpnt->scsi_done = done; | ||
| 91 | 90 | ||
| 92 | scsi_result = fc_remote_port_chkready(rport); | 91 | scsi_result = fc_remote_port_chkready(rport); |
| 93 | if (unlikely(scsi_result)) { | 92 | if (unlikely(scsi_result)) { |
| @@ -127,8 +126,6 @@ static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt, | |||
| 127 | return ret; | 126 | return ret; |
| 128 | } | 127 | } |
| 129 | 128 | ||
| 130 | static DEF_SCSI_QCMD(zfcp_scsi_queuecommand) | ||
| 131 | |||
| 132 | static int zfcp_scsi_slave_alloc(struct scsi_device *sdev) | 129 | static int zfcp_scsi_slave_alloc(struct scsi_device *sdev) |
| 133 | { | 130 | { |
| 134 | struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); | 131 | struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); |
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index b2fb2b2a6e7..a6dea08664f 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
| @@ -90,11 +90,7 @@ static const struct pci_device_id hpsa_pci_device_id[] = { | |||
| 90 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3252}, | 90 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3252}, |
| 91 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3253}, | 91 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3253}, |
| 92 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3254}, | 92 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3254}, |
| 93 | #define PCI_DEVICE_ID_HP_CISSF 0x333f | 93 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
| 94 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x333F}, | ||
| 95 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
| 96 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, | ||
| 97 | {PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
| 98 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, | 94 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, |
| 99 | {0,} | 95 | {0,} |
| 100 | }; | 96 | }; |
| @@ -113,8 +109,6 @@ static struct board_type products[] = { | |||
| 113 | {0x3249103C, "Smart Array P812", &SA5_access}, | 109 | {0x3249103C, "Smart Array P812", &SA5_access}, |
| 114 | {0x324a103C, "Smart Array P712m", &SA5_access}, | 110 | {0x324a103C, "Smart Array P712m", &SA5_access}, |
| 115 | {0x324b103C, "Smart Array P711m", &SA5_access}, | 111 | {0x324b103C, "Smart Array P711m", &SA5_access}, |
| 116 | {0x3233103C, "StorageWorks P1210m", &SA5_access}, | ||
| 117 | {0x333F103C, "StorageWorks P1210m", &SA5_access}, | ||
| 118 | {0x3250103C, "Smart Array", &SA5_access}, | 112 | {0x3250103C, "Smart Array", &SA5_access}, |
| 119 | {0x3250113C, "Smart Array", &SA5_access}, | 113 | {0x3250113C, "Smart Array", &SA5_access}, |
| 120 | {0x3250123C, "Smart Array", &SA5_access}, | 114 | {0x3250123C, "Smart Array", &SA5_access}, |
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 0433ea6f27c..b37c8a3c1bb 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c | |||
| @@ -951,8 +951,8 @@ static int _osd_req_finalize_cdb_cont(struct osd_request *or, const u8 *cap_key) | |||
| 951 | /* create a bio for continuation segment */ | 951 | /* create a bio for continuation segment */ |
| 952 | bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes, | 952 | bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes, |
| 953 | GFP_KERNEL); | 953 | GFP_KERNEL); |
| 954 | if (unlikely(!bio)) | 954 | if (IS_ERR(bio)) |
| 955 | return -ENOMEM; | 955 | return PTR_ERR(bio); |
| 956 | 956 | ||
| 957 | bio->bi_rw |= REQ_WRITE; | 957 | bio->bi_rw |= REQ_WRITE; |
| 958 | 958 | ||
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 5e76a624cb0..300d59f389d 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c | |||
| @@ -62,6 +62,7 @@ | |||
| 62 | static unsigned int pmcraid_debug_log; | 62 | static unsigned int pmcraid_debug_log; |
| 63 | static unsigned int pmcraid_disable_aen; | 63 | static unsigned int pmcraid_disable_aen; |
| 64 | static unsigned int pmcraid_log_level = IOASC_LOG_LEVEL_MUST; | 64 | static unsigned int pmcraid_log_level = IOASC_LOG_LEVEL_MUST; |
| 65 | static unsigned int pmcraid_enable_msix; | ||
| 65 | 66 | ||
| 66 | /* | 67 | /* |
| 67 | * Data structures to support multiple adapters by the LLD. | 68 | * Data structures to support multiple adapters by the LLD. |
| @@ -4691,7 +4692,8 @@ pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance) | |||
| 4691 | int rc; | 4692 | int rc; |
| 4692 | struct pci_dev *pdev = pinstance->pdev; | 4693 | struct pci_dev *pdev = pinstance->pdev; |
| 4693 | 4694 | ||
| 4694 | if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { | 4695 | if ((pmcraid_enable_msix) && |
| 4696 | (pci_find_capability(pdev, PCI_CAP_ID_MSIX))) { | ||
| 4695 | int num_hrrq = PMCRAID_NUM_MSIX_VECTORS; | 4697 | int num_hrrq = PMCRAID_NUM_MSIX_VECTORS; |
| 4696 | struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS]; | 4698 | struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS]; |
| 4697 | int i; | 4699 | int i; |
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h index 1134279604e..4db210d9394 100644 --- a/drivers/scsi/pmcraid.h +++ b/drivers/scsi/pmcraid.h | |||
| @@ -42,7 +42,7 @@ | |||
| 42 | */ | 42 | */ |
| 43 | #define PMCRAID_DRIVER_NAME "PMC MaxRAID" | 43 | #define PMCRAID_DRIVER_NAME "PMC MaxRAID" |
| 44 | #define PMCRAID_DEVFILE "pmcsas" | 44 | #define PMCRAID_DEVFILE "pmcsas" |
| 45 | #define PMCRAID_DRIVER_VERSION "2.0.3" | 45 | #define PMCRAID_DRIVER_VERSION "1.0.3" |
| 46 | #define PMCRAID_DRIVER_DATE __DATE__ | 46 | #define PMCRAID_DRIVER_DATE __DATE__ |
| 47 | 47 | ||
| 48 | #define PMCRAID_FW_VERSION_1 0x002 | 48 | #define PMCRAID_FW_VERSION_1 0x002 |
| @@ -333,11 +333,9 @@ struct pmcraid_config_table_entry { | |||
| 333 | __u8 lun[PMCRAID_LUN_LEN]; | 333 | __u8 lun[PMCRAID_LUN_LEN]; |
| 334 | } __attribute__((packed, aligned(4))); | 334 | } __attribute__((packed, aligned(4))); |
| 335 | 335 | ||
| 336 | /* extended configuration table sizes are of 64 bytes in size */ | 336 | /* extended configuration table sizes are also of 32 bytes in size */ |
| 337 | #define PMCRAID_CFGTE_EXT_SIZE 32 | ||
| 338 | struct pmcraid_config_table_entry_ext { | 337 | struct pmcraid_config_table_entry_ext { |
| 339 | struct pmcraid_config_table_entry cfgte; | 338 | struct pmcraid_config_table_entry cfgte; |
| 340 | __u8 cfgte_ext[PMCRAID_CFGTE_EXT_SIZE]; | ||
| 341 | }; | 339 | }; |
| 342 | 340 | ||
| 343 | /* resource types (config_table_entry.resource_type values) */ | 341 | /* resource types (config_table_entry.resource_type values) */ |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 3a22effced5..9ce539d4557 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
| @@ -2409,7 +2409,6 @@ struct qla_hw_data { | |||
| 2409 | uint32_t enable_target_reset :1; | 2409 | uint32_t enable_target_reset :1; |
| 2410 | uint32_t enable_lip_full_login :1; | 2410 | uint32_t enable_lip_full_login :1; |
| 2411 | uint32_t enable_led_scheme :1; | 2411 | uint32_t enable_led_scheme :1; |
| 2412 | uint32_t inta_enabled :1; | ||
| 2413 | uint32_t msi_enabled :1; | 2412 | uint32_t msi_enabled :1; |
| 2414 | uint32_t msix_enabled :1; | 2413 | uint32_t msix_enabled :1; |
| 2415 | uint32_t disable_serdes :1; | 2414 | uint32_t disable_serdes :1; |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 5f94430b42f..4c1ba6263eb 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
| @@ -1061,6 +1061,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
| 1061 | fcp_cmnd->additional_cdb_len |= 2; | 1061 | fcp_cmnd->additional_cdb_len |= 2; |
| 1062 | 1062 | ||
| 1063 | int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun); | 1063 | int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun); |
| 1064 | host_to_fcp_swap((uint8_t *)&fcp_cmnd->lun, sizeof(fcp_cmnd->lun)); | ||
| 1064 | memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); | 1065 | memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); |
| 1065 | cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len); | 1066 | cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len); |
| 1066 | cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32( | 1067 | cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32( |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 1f06ddd9bdd..7f77898486a 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
| @@ -2491,14 +2491,15 @@ skip_msix: | |||
| 2491 | skip_msi: | 2491 | skip_msi: |
| 2492 | 2492 | ||
| 2493 | ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler, | 2493 | ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler, |
| 2494 | IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp); | 2494 | ha->flags.msi_enabled ? 0 : IRQF_SHARED, |
| 2495 | QLA2XXX_DRIVER_NAME, rsp); | ||
| 2495 | if (ret) { | 2496 | if (ret) { |
| 2496 | qla_printk(KERN_WARNING, ha, | 2497 | qla_printk(KERN_WARNING, ha, |
| 2497 | "Failed to reserve interrupt %d already in use.\n", | 2498 | "Failed to reserve interrupt %d already in use.\n", |
| 2498 | ha->pdev->irq); | 2499 | ha->pdev->irq); |
| 2499 | goto fail; | 2500 | goto fail; |
| 2500 | } | 2501 | } |
| 2501 | ha->flags.inta_enabled = 1; | 2502 | |
| 2502 | clear_risc_ints: | 2503 | clear_risc_ints: |
| 2503 | 2504 | ||
| 2504 | /* | 2505 | /* |
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 8d9edfb3980..ae2acacc000 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c | |||
| @@ -2749,6 +2749,7 @@ sufficient_dsds: | |||
| 2749 | goto queuing_error_fcp_cmnd; | 2749 | goto queuing_error_fcp_cmnd; |
| 2750 | 2750 | ||
| 2751 | int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); | 2751 | int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); |
| 2752 | host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); | ||
| 2752 | 2753 | ||
| 2753 | /* build FCP_CMND IU */ | 2754 | /* build FCP_CMND IU */ |
| 2754 | memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); | 2755 | memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 1644eabaafe..2c0876c81a3 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
| @@ -829,7 +829,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
| 829 | { | 829 | { |
| 830 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); | 830 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
| 831 | srb_t *sp; | 831 | srb_t *sp; |
| 832 | int ret; | 832 | int ret = SUCCESS; |
| 833 | unsigned int id, lun; | 833 | unsigned int id, lun; |
| 834 | unsigned long flags; | 834 | unsigned long flags; |
| 835 | int wait = 0; | 835 | int wait = 0; |
| @@ -2064,6 +2064,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 2064 | ha->init_cb_size = sizeof(struct mid_init_cb_81xx); | 2064 | ha->init_cb_size = sizeof(struct mid_init_cb_81xx); |
| 2065 | ha->gid_list_info_size = 8; | 2065 | ha->gid_list_info_size = 8; |
| 2066 | ha->optrom_size = OPTROM_SIZE_82XX; | 2066 | ha->optrom_size = OPTROM_SIZE_82XX; |
| 2067 | ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX; | ||
| 2067 | ha->isp_ops = &qla82xx_isp_ops; | 2068 | ha->isp_ops = &qla82xx_isp_ops; |
| 2068 | ha->flash_conf_off = FARX_ACCESS_FLASH_CONF; | 2069 | ha->flash_conf_off = FARX_ACCESS_FLASH_CONF; |
| 2069 | ha->flash_data_off = FARX_ACCESS_FLASH_DATA; | 2070 | ha->flash_data_off = FARX_ACCESS_FLASH_DATA; |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 8edbccb3232..cf0075a2d0c 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
| @@ -7,9 +7,9 @@ | |||
| 7 | /* | 7 | /* |
| 8 | * Driver version | 8 | * Driver version |
| 9 | */ | 9 | */ |
| 10 | #define QLA2XXX_VERSION "8.03.04-k0" | 10 | #define QLA2XXX_VERSION "8.03.05-k0" |
| 11 | 11 | ||
| 12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
| 13 | #define QLA_DRIVER_MINOR_VER 3 | 13 | #define QLA_DRIVER_MINOR_VER 3 |
| 14 | #define QLA_DRIVER_PATCH_VER 4 | 14 | #define QLA_DRIVER_PATCH_VER 5 |
| 15 | #define QLA_DRIVER_BETA_VER 0 | 15 | #define QLA_DRIVER_BETA_VER 0 |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 824b8fc03ce..30ac116186f 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
| @@ -615,7 +615,7 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd) | |||
| 615 | return rtn; | 615 | return rtn; |
| 616 | } | 616 | } |
| 617 | 617 | ||
| 618 | static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) | 618 | static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) |
| 619 | { | 619 | { |
| 620 | if (!scmd->device->host->hostt->eh_abort_handler) | 620 | if (!scmd->device->host->hostt->eh_abort_handler) |
| 621 | return FAILED; | 621 | return FAILED; |
| @@ -623,31 +623,9 @@ static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) | |||
| 623 | return scmd->device->host->hostt->eh_abort_handler(scmd); | 623 | return scmd->device->host->hostt->eh_abort_handler(scmd); |
| 624 | } | 624 | } |
| 625 | 625 | ||
| 626 | /** | ||
| 627 | * scsi_try_to_abort_cmd - Ask host to abort a running command. | ||
| 628 | * @scmd: SCSI cmd to abort from Lower Level. | ||
| 629 | * | ||
| 630 | * Notes: | ||
| 631 | * This function will not return until the user's completion function | ||
| 632 | * has been called. there is no timeout on this operation. if the | ||
| 633 | * author of the low-level driver wishes this operation to be timed, | ||
| 634 | * they can provide this facility themselves. helper functions in | ||
| 635 | * scsi_error.c can be supplied to make this easier to do. | ||
| 636 | */ | ||
| 637 | static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) | ||
| 638 | { | ||
| 639 | /* | ||
| 640 | * scsi_done was called just after the command timed out and before | ||
| 641 | * we had a chance to process it. (db) | ||
| 642 | */ | ||
| 643 | if (scmd->serial_number == 0) | ||
| 644 | return SUCCESS; | ||
| 645 | return __scsi_try_to_abort_cmd(scmd); | ||
| 646 | } | ||
| 647 | |||
| 648 | static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) | 626 | static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) |
| 649 | { | 627 | { |
| 650 | if (__scsi_try_to_abort_cmd(scmd) != SUCCESS) | 628 | if (scsi_try_to_abort_cmd(scmd) != SUCCESS) |
| 651 | if (scsi_try_bus_device_reset(scmd) != SUCCESS) | 629 | if (scsi_try_bus_device_reset(scmd) != SUCCESS) |
| 652 | if (scsi_try_target_reset(scmd) != SUCCESS) | 630 | if (scsi_try_target_reset(scmd) != SUCCESS) |
| 653 | if (scsi_try_bus_reset(scmd) != SUCCESS) | 631 | if (scsi_try_bus_reset(scmd) != SUCCESS) |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index eafeeda6e19..5b6bbaea59f 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
| @@ -1403,11 +1403,6 @@ static void scsi_softirq_done(struct request *rq) | |||
| 1403 | 1403 | ||
| 1404 | INIT_LIST_HEAD(&cmd->eh_entry); | 1404 | INIT_LIST_HEAD(&cmd->eh_entry); |
| 1405 | 1405 | ||
| 1406 | /* | ||
| 1407 | * Set the serial numbers back to zero | ||
| 1408 | */ | ||
| 1409 | cmd->serial_number = 0; | ||
| 1410 | |||
| 1411 | atomic_inc(&cmd->device->iodone_cnt); | 1406 | atomic_inc(&cmd->device->iodone_cnt); |
| 1412 | if (cmd->result) | 1407 | if (cmd->result) |
| 1413 | atomic_inc(&cmd->device->ioerr_cnt); | 1408 | atomic_inc(&cmd->device->ioerr_cnt); |
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c index 3374618300a..25a8bc565f4 100644 --- a/drivers/serial/kgdboc.c +++ b/drivers/serial/kgdboc.c | |||
| @@ -90,7 +90,8 @@ static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper); | |||
| 90 | 90 | ||
| 91 | static void kgdboc_restore_input(void) | 91 | static void kgdboc_restore_input(void) |
| 92 | { | 92 | { |
| 93 | schedule_work(&kgdboc_restore_input_work); | 93 | if (likely(system_state == SYSTEM_RUNNING)) |
| 94 | schedule_work(&kgdboc_restore_input_work); | ||
| 94 | } | 95 | } |
| 95 | 96 | ||
| 96 | static int kgdboc_register_kbd(char **cptr) | 97 | static int kgdboc_register_kbd(char **cptr) |
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c index 90439314cf6..0838c79861e 100644 --- a/drivers/spi/dw_spi.c +++ b/drivers/spi/dw_spi.c | |||
| @@ -413,6 +413,11 @@ static void poll_transfer(struct dw_spi *dws) | |||
| 413 | { | 413 | { |
| 414 | while (dws->write(dws)) | 414 | while (dws->write(dws)) |
| 415 | dws->read(dws); | 415 | dws->read(dws); |
| 416 | /* | ||
| 417 | * There is a possibility that the last word of a transaction | ||
| 418 | * will be lost if data is not ready. Re-read to solve this issue. | ||
| 419 | */ | ||
| 420 | dws->read(dws); | ||
| 416 | 421 | ||
| 417 | transfer_complete(dws); | 422 | transfer_complete(dws); |
| 418 | } | 423 | } |
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 05bf5a27b5b..989e16e4ab5 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c | |||
| @@ -951,7 +951,9 @@ static int usbatm_atm_init(struct usbatm_data *instance) | |||
| 951 | * condition: callbacks we register can be executed at once, before we have | 951 | * condition: callbacks we register can be executed at once, before we have |
| 952 | * initialized the struct atm_dev. To protect against this, all callbacks | 952 | * initialized the struct atm_dev. To protect against this, all callbacks |
| 953 | * abort if atm_dev->dev_data is NULL. */ | 953 | * abort if atm_dev->dev_data is NULL. */ |
| 954 | atm_dev = atm_dev_register(instance->driver_name, &usbatm_atm_devops, -1, NULL); | 954 | atm_dev = atm_dev_register(instance->driver_name, |
| 955 | &instance->usb_intf->dev, &usbatm_atm_devops, | ||
| 956 | -1, NULL); | ||
| 955 | if (!atm_dev) { | 957 | if (!atm_dev) { |
| 956 | usb_err(instance, "%s: failed to register ATM device!\n", __func__); | 958 | usb_err(instance, "%s: failed to register ATM device!\n", __func__); |
| 957 | return -1; | 959 | return -1; |
| @@ -966,14 +968,6 @@ static int usbatm_atm_init(struct usbatm_data *instance) | |||
| 966 | /* temp init ATM device, set to 128kbit */ | 968 | /* temp init ATM device, set to 128kbit */ |
| 967 | atm_dev->link_rate = 128 * 1000 / 424; | 969 | atm_dev->link_rate = 128 * 1000 / 424; |
| 968 | 970 | ||
| 969 | ret = sysfs_create_link(&atm_dev->class_dev.kobj, | ||
| 970 | &instance->usb_intf->dev.kobj, "device"); | ||
| 971 | if (ret) { | ||
| 972 | atm_err(instance, "%s: sysfs_create_link failed: %d\n", | ||
| 973 | __func__, ret); | ||
| 974 | goto fail_sysfs; | ||
| 975 | } | ||
| 976 | |||
| 977 | if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) { | 971 | if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) { |
| 978 | atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret); | 972 | atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret); |
| 979 | goto fail; | 973 | goto fail; |
| @@ -992,8 +986,6 @@ static int usbatm_atm_init(struct usbatm_data *instance) | |||
| 992 | return 0; | 986 | return 0; |
| 993 | 987 | ||
| 994 | fail: | 988 | fail: |
| 995 | sysfs_remove_link(&atm_dev->class_dev.kobj, "device"); | ||
| 996 | fail_sysfs: | ||
| 997 | instance->atm_dev = NULL; | 989 | instance->atm_dev = NULL; |
| 998 | atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */ | 990 | atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */ |
| 999 | return ret; | 991 | return ret; |
| @@ -1329,7 +1321,6 @@ void usbatm_usb_disconnect(struct usb_interface *intf) | |||
| 1329 | 1321 | ||
| 1330 | /* ATM finalize */ | 1322 | /* ATM finalize */ |
| 1331 | if (instance->atm_dev) { | 1323 | if (instance->atm_dev) { |
| 1332 | sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device"); | ||
| 1333 | atm_dev_deregister(instance->atm_dev); | 1324 | atm_dev_deregister(instance->atm_dev); |
| 1334 | instance->atm_dev = NULL; | 1325 | instance->atm_dev = NULL; |
| 1335 | } | 1326 | } |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 94701ff3a23..159c77a5746 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
| @@ -884,6 +884,7 @@ static int log_write(void __user *log_base, | |||
| 884 | int r; | 884 | int r; |
| 885 | if (!write_length) | 885 | if (!write_length) |
| 886 | return 0; | 886 | return 0; |
| 887 | write_length += write_address % VHOST_PAGE_SIZE; | ||
| 887 | write_address /= VHOST_PAGE_SIZE; | 888 | write_address /= VHOST_PAGE_SIZE; |
| 888 | for (;;) { | 889 | for (;;) { |
| 889 | u64 base = (u64)(unsigned long)log_base; | 890 | u64 base = (u64)(unsigned long)log_base; |
| @@ -897,7 +898,7 @@ static int log_write(void __user *log_base, | |||
| 897 | if (write_length <= VHOST_PAGE_SIZE) | 898 | if (write_length <= VHOST_PAGE_SIZE) |
| 898 | break; | 899 | break; |
| 899 | write_length -= VHOST_PAGE_SIZE; | 900 | write_length -= VHOST_PAGE_SIZE; |
| 900 | write_address += VHOST_PAGE_SIZE; | 901 | write_address += 1; |
| 901 | } | 902 | } |
| 902 | return r; | 903 | return r; |
| 903 | } | 904 | } |
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 0a4dbdc1693..de450c1fb86 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c | |||
| @@ -855,6 +855,7 @@ const struct fb_videomode *fb_find_nearest_mode(const struct fb_videomode *mode, | |||
| 855 | abs(cmode->yres - mode->yres); | 855 | abs(cmode->yres - mode->yres); |
| 856 | if (diff > d) { | 856 | if (diff > d) { |
| 857 | diff = d; | 857 | diff = d; |
| 858 | diff_refresh = abs(cmode->refresh - mode->refresh); | ||
| 858 | best = cmode; | 859 | best = cmode; |
| 859 | } else if (diff == d) { | 860 | } else if (diff == d) { |
| 860 | d = abs(cmode->refresh - mode->refresh); | 861 | d = abs(cmode->refresh - mode->refresh); |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index c547cca26a2..51d2e4de34e 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -696,6 +696,7 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
| 696 | __btree_submit_bio_done); | 696 | __btree_submit_bio_done); |
| 697 | } | 697 | } |
| 698 | 698 | ||
| 699 | #ifdef CONFIG_MIGRATION | ||
| 699 | static int btree_migratepage(struct address_space *mapping, | 700 | static int btree_migratepage(struct address_space *mapping, |
| 700 | struct page *newpage, struct page *page) | 701 | struct page *newpage, struct page *page) |
| 701 | { | 702 | { |
| @@ -712,12 +713,9 @@ static int btree_migratepage(struct address_space *mapping, | |||
| 712 | if (page_has_private(page) && | 713 | if (page_has_private(page) && |
| 713 | !try_to_release_page(page, GFP_KERNEL)) | 714 | !try_to_release_page(page, GFP_KERNEL)) |
| 714 | return -EAGAIN; | 715 | return -EAGAIN; |
| 715 | #ifdef CONFIG_MIGRATION | ||
| 716 | return migrate_page(mapping, newpage, page); | 716 | return migrate_page(mapping, newpage, page); |
| 717 | #else | ||
| 718 | return -ENOSYS; | ||
| 719 | #endif | ||
| 720 | } | 717 | } |
| 718 | #endif | ||
| 721 | 719 | ||
| 722 | static int btree_writepage(struct page *page, struct writeback_control *wbc) | 720 | static int btree_writepage(struct page *page, struct writeback_control *wbc) |
| 723 | { | 721 | { |
| @@ -1009,7 +1007,10 @@ static int find_and_setup_root(struct btrfs_root *tree_root, | |||
| 1009 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); | 1007 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); |
| 1010 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), | 1008 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), |
| 1011 | blocksize, generation); | 1009 | blocksize, generation); |
| 1012 | BUG_ON(!root->node); | 1010 | if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) { |
| 1011 | free_extent_buffer(root->node); | ||
| 1012 | return -EIO; | ||
| 1013 | } | ||
| 1013 | root->commit_root = btrfs_root_node(root); | 1014 | root->commit_root = btrfs_root_node(root); |
| 1014 | return 0; | 1015 | return 0; |
| 1015 | } | 1016 | } |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index bcd59c7dfb5..227e5815d83 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -429,6 +429,7 @@ err: | |||
| 429 | 429 | ||
| 430 | static int cache_block_group(struct btrfs_block_group_cache *cache, | 430 | static int cache_block_group(struct btrfs_block_group_cache *cache, |
| 431 | struct btrfs_trans_handle *trans, | 431 | struct btrfs_trans_handle *trans, |
| 432 | struct btrfs_root *root, | ||
| 432 | int load_cache_only) | 433 | int load_cache_only) |
| 433 | { | 434 | { |
| 434 | struct btrfs_fs_info *fs_info = cache->fs_info; | 435 | struct btrfs_fs_info *fs_info = cache->fs_info; |
| @@ -442,9 +443,12 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, | |||
| 442 | 443 | ||
| 443 | /* | 444 | /* |
| 444 | * We can't do the read from on-disk cache during a commit since we need | 445 | * We can't do the read from on-disk cache during a commit since we need |
| 445 | * to have the normal tree locking. | 446 | * to have the normal tree locking. Also if we are currently trying to |
| 447 | * allocate blocks for the tree root we can't do the fast caching since | ||
| 448 | * we likely hold important locks. | ||
| 446 | */ | 449 | */ |
| 447 | if (!trans->transaction->in_commit) { | 450 | if (!trans->transaction->in_commit && |
| 451 | (root && root != root->fs_info->tree_root)) { | ||
| 448 | spin_lock(&cache->lock); | 452 | spin_lock(&cache->lock); |
| 449 | if (cache->cached != BTRFS_CACHE_NO) { | 453 | if (cache->cached != BTRFS_CACHE_NO) { |
| 450 | spin_unlock(&cache->lock); | 454 | spin_unlock(&cache->lock); |
| @@ -2741,6 +2745,7 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group, | |||
| 2741 | struct btrfs_root *root = block_group->fs_info->tree_root; | 2745 | struct btrfs_root *root = block_group->fs_info->tree_root; |
| 2742 | struct inode *inode = NULL; | 2746 | struct inode *inode = NULL; |
| 2743 | u64 alloc_hint = 0; | 2747 | u64 alloc_hint = 0; |
| 2748 | int dcs = BTRFS_DC_ERROR; | ||
| 2744 | int num_pages = 0; | 2749 | int num_pages = 0; |
| 2745 | int retries = 0; | 2750 | int retries = 0; |
| 2746 | int ret = 0; | 2751 | int ret = 0; |
| @@ -2795,6 +2800,8 @@ again: | |||
| 2795 | 2800 | ||
| 2796 | spin_lock(&block_group->lock); | 2801 | spin_lock(&block_group->lock); |
| 2797 | if (block_group->cached != BTRFS_CACHE_FINISHED) { | 2802 | if (block_group->cached != BTRFS_CACHE_FINISHED) { |
| 2803 | /* We're not cached, don't bother trying to write stuff out */ | ||
| 2804 | dcs = BTRFS_DC_WRITTEN; | ||
| 2798 | spin_unlock(&block_group->lock); | 2805 | spin_unlock(&block_group->lock); |
| 2799 | goto out_put; | 2806 | goto out_put; |
| 2800 | } | 2807 | } |
| @@ -2821,6 +2828,8 @@ again: | |||
| 2821 | ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages, | 2828 | ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages, |
| 2822 | num_pages, num_pages, | 2829 | num_pages, num_pages, |
| 2823 | &alloc_hint); | 2830 | &alloc_hint); |
| 2831 | if (!ret) | ||
| 2832 | dcs = BTRFS_DC_SETUP; | ||
| 2824 | btrfs_free_reserved_data_space(inode, num_pages); | 2833 | btrfs_free_reserved_data_space(inode, num_pages); |
| 2825 | out_put: | 2834 | out_put: |
| 2826 | iput(inode); | 2835 | iput(inode); |
| @@ -2828,10 +2837,7 @@ out_free: | |||
| 2828 | btrfs_release_path(root, path); | 2837 | btrfs_release_path(root, path); |
| 2829 | out: | 2838 | out: |
| 2830 | spin_lock(&block_group->lock); | 2839 | spin_lock(&block_group->lock); |
| 2831 | if (ret) | 2840 | block_group->disk_cache_state = dcs; |
| 2832 | block_group->disk_cache_state = BTRFS_DC_ERROR; | ||
| 2833 | else | ||
| 2834 | block_group->disk_cache_state = BTRFS_DC_SETUP; | ||
| 2835 | spin_unlock(&block_group->lock); | 2841 | spin_unlock(&block_group->lock); |
| 2836 | 2842 | ||
| 2837 | return ret; | 2843 | return ret; |
| @@ -3037,7 +3043,13 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags) | |||
| 3037 | 3043 | ||
| 3038 | u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) | 3044 | u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) |
| 3039 | { | 3045 | { |
| 3040 | u64 num_devices = root->fs_info->fs_devices->rw_devices; | 3046 | /* |
| 3047 | * we add in the count of missing devices because we want | ||
| 3048 | * to make sure that any RAID levels on a degraded FS | ||
| 3049 | * continue to be honored. | ||
| 3050 | */ | ||
| 3051 | u64 num_devices = root->fs_info->fs_devices->rw_devices + | ||
| 3052 | root->fs_info->fs_devices->missing_devices; | ||
| 3041 | 3053 | ||
| 3042 | if (num_devices == 1) | 3054 | if (num_devices == 1) |
| 3043 | flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0); | 3055 | flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0); |
| @@ -4080,7 +4092,7 @@ static int update_block_group(struct btrfs_trans_handle *trans, | |||
| 4080 | * space back to the block group, otherwise we will leak space. | 4092 | * space back to the block group, otherwise we will leak space. |
| 4081 | */ | 4093 | */ |
| 4082 | if (!alloc && cache->cached == BTRFS_CACHE_NO) | 4094 | if (!alloc && cache->cached == BTRFS_CACHE_NO) |
| 4083 | cache_block_group(cache, trans, 1); | 4095 | cache_block_group(cache, trans, NULL, 1); |
| 4084 | 4096 | ||
| 4085 | byte_in_group = bytenr - cache->key.objectid; | 4097 | byte_in_group = bytenr - cache->key.objectid; |
| 4086 | WARN_ON(byte_in_group > cache->key.offset); | 4098 | WARN_ON(byte_in_group > cache->key.offset); |
| @@ -4930,11 +4942,31 @@ search: | |||
| 4930 | btrfs_get_block_group(block_group); | 4942 | btrfs_get_block_group(block_group); |
| 4931 | search_start = block_group->key.objectid; | 4943 | search_start = block_group->key.objectid; |
| 4932 | 4944 | ||
| 4945 | /* | ||
| 4946 | * this can happen if we end up cycling through all the | ||
| 4947 | * raid types, but we want to make sure we only allocate | ||
| 4948 | * for the proper type. | ||
| 4949 | */ | ||
| 4950 | if (!block_group_bits(block_group, data)) { | ||
| 4951 | u64 extra = BTRFS_BLOCK_GROUP_DUP | | ||
| 4952 | BTRFS_BLOCK_GROUP_RAID1 | | ||
| 4953 | BTRFS_BLOCK_GROUP_RAID10; | ||
| 4954 | |||
| 4955 | /* | ||
| 4956 | * if they asked for extra copies and this block group | ||
| 4957 | * doesn't provide them, bail. This does allow us to | ||
| 4958 | * fill raid0 from raid1. | ||
| 4959 | */ | ||
| 4960 | if ((data & extra) && !(block_group->flags & extra)) | ||
| 4961 | goto loop; | ||
| 4962 | } | ||
| 4963 | |||
| 4933 | have_block_group: | 4964 | have_block_group: |
| 4934 | if (unlikely(block_group->cached == BTRFS_CACHE_NO)) { | 4965 | if (unlikely(block_group->cached == BTRFS_CACHE_NO)) { |
| 4935 | u64 free_percent; | 4966 | u64 free_percent; |
| 4936 | 4967 | ||
| 4937 | ret = cache_block_group(block_group, trans, 1); | 4968 | ret = cache_block_group(block_group, trans, |
| 4969 | orig_root, 1); | ||
| 4938 | if (block_group->cached == BTRFS_CACHE_FINISHED) | 4970 | if (block_group->cached == BTRFS_CACHE_FINISHED) |
| 4939 | goto have_block_group; | 4971 | goto have_block_group; |
| 4940 | 4972 | ||
| @@ -4958,7 +4990,8 @@ have_block_group: | |||
| 4958 | if (loop > LOOP_CACHING_NOWAIT || | 4990 | if (loop > LOOP_CACHING_NOWAIT || |
| 4959 | (loop > LOOP_FIND_IDEAL && | 4991 | (loop > LOOP_FIND_IDEAL && |
| 4960 | atomic_read(&space_info->caching_threads) < 2)) { | 4992 | atomic_read(&space_info->caching_threads) < 2)) { |
| 4961 | ret = cache_block_group(block_group, trans, 0); | 4993 | ret = cache_block_group(block_group, trans, |
| 4994 | orig_root, 0); | ||
| 4962 | BUG_ON(ret); | 4995 | BUG_ON(ret); |
| 4963 | } | 4996 | } |
| 4964 | found_uncached_bg = true; | 4997 | found_uncached_bg = true; |
| @@ -5515,7 +5548,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, | |||
| 5515 | u64 num_bytes = ins->offset; | 5548 | u64 num_bytes = ins->offset; |
| 5516 | 5549 | ||
| 5517 | block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid); | 5550 | block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid); |
| 5518 | cache_block_group(block_group, trans, 0); | 5551 | cache_block_group(block_group, trans, NULL, 0); |
| 5519 | caching_ctl = get_caching_control(block_group); | 5552 | caching_ctl = get_caching_control(block_group); |
| 5520 | 5553 | ||
| 5521 | if (!caching_ctl) { | 5554 | if (!caching_ctl) { |
| @@ -6300,9 +6333,13 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
| 6300 | NULL, NULL); | 6333 | NULL, NULL); |
| 6301 | BUG_ON(ret < 0); | 6334 | BUG_ON(ret < 0); |
| 6302 | if (ret > 0) { | 6335 | if (ret > 0) { |
| 6303 | ret = btrfs_del_orphan_item(trans, tree_root, | 6336 | /* if we fail to delete the orphan item this time |
| 6304 | root->root_key.objectid); | 6337 | * around, it'll get picked up the next time. |
| 6305 | BUG_ON(ret); | 6338 | * |
| 6339 | * The most common failure here is just -ENOENT. | ||
| 6340 | */ | ||
| 6341 | btrfs_del_orphan_item(trans, tree_root, | ||
| 6342 | root->root_key.objectid); | ||
| 6306 | } | 6343 | } |
| 6307 | } | 6344 | } |
| 6308 | 6345 | ||
| @@ -7878,7 +7915,14 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags) | |||
| 7878 | u64 stripped = BTRFS_BLOCK_GROUP_RAID0 | | 7915 | u64 stripped = BTRFS_BLOCK_GROUP_RAID0 | |
| 7879 | BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10; | 7916 | BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10; |
| 7880 | 7917 | ||
| 7881 | num_devices = root->fs_info->fs_devices->rw_devices; | 7918 | /* |
| 7919 | * we add in the count of missing devices because we want | ||
| 7920 | * to make sure that any RAID levels on a degraded FS | ||
| 7921 | * continue to be honored. | ||
| 7922 | */ | ||
| 7923 | num_devices = root->fs_info->fs_devices->rw_devices + | ||
| 7924 | root->fs_info->fs_devices->missing_devices; | ||
| 7925 | |||
| 7882 | if (num_devices == 1) { | 7926 | if (num_devices == 1) { |
| 7883 | stripped |= BTRFS_BLOCK_GROUP_DUP; | 7927 | stripped |= BTRFS_BLOCK_GROUP_DUP; |
| 7884 | stripped = flags & ~stripped; | 7928 | stripped = flags & ~stripped; |
| @@ -8247,7 +8291,6 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
| 8247 | break; | 8291 | break; |
| 8248 | if (ret != 0) | 8292 | if (ret != 0) |
| 8249 | goto error; | 8293 | goto error; |
| 8250 | |||
| 8251 | leaf = path->nodes[0]; | 8294 | leaf = path->nodes[0]; |
| 8252 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); | 8295 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
| 8253 | cache = kzalloc(sizeof(*cache), GFP_NOFS); | 8296 | cache = kzalloc(sizeof(*cache), GFP_NOFS); |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index c1faded5fca..66836d85763 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -48,30 +48,34 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, | |||
| 48 | struct page **prepared_pages, | 48 | struct page **prepared_pages, |
| 49 | struct iov_iter *i) | 49 | struct iov_iter *i) |
| 50 | { | 50 | { |
| 51 | size_t copied; | 51 | size_t copied = 0; |
| 52 | int pg = 0; | 52 | int pg = 0; |
| 53 | int offset = pos & (PAGE_CACHE_SIZE - 1); | 53 | int offset = pos & (PAGE_CACHE_SIZE - 1); |
| 54 | int total_copied = 0; | ||
| 54 | 55 | ||
| 55 | while (write_bytes > 0) { | 56 | while (write_bytes > 0) { |
| 56 | size_t count = min_t(size_t, | 57 | size_t count = min_t(size_t, |
| 57 | PAGE_CACHE_SIZE - offset, write_bytes); | 58 | PAGE_CACHE_SIZE - offset, write_bytes); |
| 58 | struct page *page = prepared_pages[pg]; | 59 | struct page *page = prepared_pages[pg]; |
| 59 | again: | 60 | /* |
| 60 | if (unlikely(iov_iter_fault_in_readable(i, count))) | 61 | * Copy data from userspace to the current page |
| 61 | return -EFAULT; | 62 | * |
| 62 | 63 | * Disable pagefault to avoid recursive lock since | |
| 63 | /* Copy data from userspace to the current page */ | 64 | * the pages are already locked |
| 64 | copied = iov_iter_copy_from_user(page, i, offset, count); | 65 | */ |
| 66 | pagefault_disable(); | ||
| 67 | copied = iov_iter_copy_from_user_atomic(page, i, offset, count); | ||
| 68 | pagefault_enable(); | ||
| 65 | 69 | ||
| 66 | /* Flush processor's dcache for this page */ | 70 | /* Flush processor's dcache for this page */ |
| 67 | flush_dcache_page(page); | 71 | flush_dcache_page(page); |
| 68 | iov_iter_advance(i, copied); | 72 | iov_iter_advance(i, copied); |
| 69 | write_bytes -= copied; | 73 | write_bytes -= copied; |
| 74 | total_copied += copied; | ||
| 70 | 75 | ||
| 76 | /* Return to btrfs_file_aio_write to fault page */ | ||
| 71 | if (unlikely(copied == 0)) { | 77 | if (unlikely(copied == 0)) { |
| 72 | count = min_t(size_t, PAGE_CACHE_SIZE - offset, | 78 | break; |
| 73 | iov_iter_single_seg_count(i)); | ||
| 74 | goto again; | ||
| 75 | } | 79 | } |
| 76 | 80 | ||
| 77 | if (unlikely(copied < PAGE_CACHE_SIZE - offset)) { | 81 | if (unlikely(copied < PAGE_CACHE_SIZE - offset)) { |
| @@ -81,7 +85,7 @@ again: | |||
| 81 | offset = 0; | 85 | offset = 0; |
| 82 | } | 86 | } |
| 83 | } | 87 | } |
| 84 | return 0; | 88 | return total_copied; |
| 85 | } | 89 | } |
| 86 | 90 | ||
| 87 | /* | 91 | /* |
| @@ -854,6 +858,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
| 854 | unsigned long last_index; | 858 | unsigned long last_index; |
| 855 | int will_write; | 859 | int will_write; |
| 856 | int buffered = 0; | 860 | int buffered = 0; |
| 861 | int copied = 0; | ||
| 862 | int dirty_pages = 0; | ||
| 857 | 863 | ||
| 858 | will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) || | 864 | will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) || |
| 859 | (file->f_flags & O_DIRECT)); | 865 | (file->f_flags & O_DIRECT)); |
| @@ -970,7 +976,17 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
| 970 | WARN_ON(num_pages > nrptrs); | 976 | WARN_ON(num_pages > nrptrs); |
| 971 | memset(pages, 0, sizeof(struct page *) * nrptrs); | 977 | memset(pages, 0, sizeof(struct page *) * nrptrs); |
| 972 | 978 | ||
| 973 | ret = btrfs_delalloc_reserve_space(inode, write_bytes); | 979 | /* |
| 980 | * Fault pages before locking them in prepare_pages | ||
| 981 | * to avoid recursive lock | ||
| 982 | */ | ||
| 983 | if (unlikely(iov_iter_fault_in_readable(&i, write_bytes))) { | ||
| 984 | ret = -EFAULT; | ||
| 985 | goto out; | ||
| 986 | } | ||
| 987 | |||
| 988 | ret = btrfs_delalloc_reserve_space(inode, | ||
| 989 | num_pages << PAGE_CACHE_SHIFT); | ||
| 974 | if (ret) | 990 | if (ret) |
| 975 | goto out; | 991 | goto out; |
| 976 | 992 | ||
| @@ -978,37 +994,49 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
| 978 | pos, first_index, last_index, | 994 | pos, first_index, last_index, |
| 979 | write_bytes); | 995 | write_bytes); |
| 980 | if (ret) { | 996 | if (ret) { |
| 981 | btrfs_delalloc_release_space(inode, write_bytes); | 997 | btrfs_delalloc_release_space(inode, |
| 998 | num_pages << PAGE_CACHE_SHIFT); | ||
| 982 | goto out; | 999 | goto out; |
| 983 | } | 1000 | } |
| 984 | 1001 | ||
| 985 | ret = btrfs_copy_from_user(pos, num_pages, | 1002 | copied = btrfs_copy_from_user(pos, num_pages, |
| 986 | write_bytes, pages, &i); | 1003 | write_bytes, pages, &i); |
| 987 | if (ret == 0) { | 1004 | dirty_pages = (copied + PAGE_CACHE_SIZE - 1) >> |
| 1005 | PAGE_CACHE_SHIFT; | ||
| 1006 | |||
| 1007 | if (num_pages > dirty_pages) { | ||
| 1008 | if (copied > 0) | ||
| 1009 | atomic_inc( | ||
| 1010 | &BTRFS_I(inode)->outstanding_extents); | ||
| 1011 | btrfs_delalloc_release_space(inode, | ||
| 1012 | (num_pages - dirty_pages) << | ||
| 1013 | PAGE_CACHE_SHIFT); | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | if (copied > 0) { | ||
| 988 | dirty_and_release_pages(NULL, root, file, pages, | 1017 | dirty_and_release_pages(NULL, root, file, pages, |
| 989 | num_pages, pos, write_bytes); | 1018 | dirty_pages, pos, copied); |
| 990 | } | 1019 | } |
| 991 | 1020 | ||
| 992 | btrfs_drop_pages(pages, num_pages); | 1021 | btrfs_drop_pages(pages, num_pages); |
| 993 | if (ret) { | ||
| 994 | btrfs_delalloc_release_space(inode, write_bytes); | ||
| 995 | goto out; | ||
| 996 | } | ||
| 997 | 1022 | ||
| 998 | if (will_write) { | 1023 | if (copied > 0) { |
| 999 | filemap_fdatawrite_range(inode->i_mapping, pos, | 1024 | if (will_write) { |
| 1000 | pos + write_bytes - 1); | 1025 | filemap_fdatawrite_range(inode->i_mapping, pos, |
| 1001 | } else { | 1026 | pos + copied - 1); |
| 1002 | balance_dirty_pages_ratelimited_nr(inode->i_mapping, | 1027 | } else { |
| 1003 | num_pages); | 1028 | balance_dirty_pages_ratelimited_nr( |
| 1004 | if (num_pages < | 1029 | inode->i_mapping, |
| 1005 | (root->leafsize >> PAGE_CACHE_SHIFT) + 1) | 1030 | dirty_pages); |
| 1006 | btrfs_btree_balance_dirty(root, 1); | 1031 | if (dirty_pages < |
| 1007 | btrfs_throttle(root); | 1032 | (root->leafsize >> PAGE_CACHE_SHIFT) + 1) |
| 1033 | btrfs_btree_balance_dirty(root, 1); | ||
| 1034 | btrfs_throttle(root); | ||
| 1035 | } | ||
| 1008 | } | 1036 | } |
| 1009 | 1037 | ||
| 1010 | pos += write_bytes; | 1038 | pos += copied; |
| 1011 | num_written += write_bytes; | 1039 | num_written += copied; |
| 1012 | 1040 | ||
| 1013 | cond_resched(); | 1041 | cond_resched(); |
| 1014 | } | 1042 | } |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 22ee0dc2e6b..60d68426695 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
| @@ -290,7 +290,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, | |||
| 290 | (unsigned long long)BTRFS_I(inode)->generation, | 290 | (unsigned long long)BTRFS_I(inode)->generation, |
| 291 | (unsigned long long)generation, | 291 | (unsigned long long)generation, |
| 292 | (unsigned long long)block_group->key.objectid); | 292 | (unsigned long long)block_group->key.objectid); |
| 293 | goto out; | 293 | goto free_cache; |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | if (!num_entries) | 296 | if (!num_entries) |
| @@ -524,6 +524,12 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 524 | return 0; | 524 | return 0; |
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | node = rb_first(&block_group->free_space_offset); | ||
| 528 | if (!node) { | ||
| 529 | iput(inode); | ||
| 530 | return 0; | ||
| 531 | } | ||
| 532 | |||
| 527 | last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT; | 533 | last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT; |
| 528 | filemap_write_and_wait(inode->i_mapping); | 534 | filemap_write_and_wait(inode->i_mapping); |
| 529 | btrfs_wait_ordered_range(inode, inode->i_size & | 535 | btrfs_wait_ordered_range(inode, inode->i_size & |
| @@ -543,10 +549,6 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 543 | */ | 549 | */ |
| 544 | first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64); | 550 | first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64); |
| 545 | 551 | ||
| 546 | node = rb_first(&block_group->free_space_offset); | ||
| 547 | if (!node) | ||
| 548 | goto out_free; | ||
| 549 | |||
| 550 | /* | 552 | /* |
| 551 | * Lock all pages first so we can lock the extent safely. | 553 | * Lock all pages first so we can lock the extent safely. |
| 552 | * | 554 | * |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8039390bd6a..72f31ecb5c9 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -495,7 +495,7 @@ again: | |||
| 495 | add_async_extent(async_cow, start, num_bytes, | 495 | add_async_extent(async_cow, start, num_bytes, |
| 496 | total_compressed, pages, nr_pages_ret); | 496 | total_compressed, pages, nr_pages_ret); |
| 497 | 497 | ||
| 498 | if (start + num_bytes < end && start + num_bytes < actual_end) { | 498 | if (start + num_bytes < end) { |
| 499 | start += num_bytes; | 499 | start += num_bytes; |
| 500 | pages = NULL; | 500 | pages = NULL; |
| 501 | cond_resched(); | 501 | cond_resched(); |
| @@ -5712,9 +5712,9 @@ static void btrfs_end_dio_bio(struct bio *bio, int err) | |||
| 5712 | 5712 | ||
| 5713 | if (err) { | 5713 | if (err) { |
| 5714 | printk(KERN_ERR "btrfs direct IO failed ino %lu rw %lu " | 5714 | printk(KERN_ERR "btrfs direct IO failed ino %lu rw %lu " |
| 5715 | "disk_bytenr %lu len %u err no %d\n", | 5715 | "sector %#Lx len %u err no %d\n", |
| 5716 | dip->inode->i_ino, bio->bi_rw, bio->bi_sector, | 5716 | dip->inode->i_ino, bio->bi_rw, |
| 5717 | bio->bi_size, err); | 5717 | (unsigned long long)bio->bi_sector, bio->bi_size, err); |
| 5718 | dip->errors = 1; | 5718 | dip->errors = 1; |
| 5719 | 5719 | ||
| 5720 | /* | 5720 | /* |
| @@ -5934,8 +5934,7 @@ free_ordered: | |||
| 5934 | */ | 5934 | */ |
| 5935 | if (write) { | 5935 | if (write) { |
| 5936 | struct btrfs_ordered_extent *ordered; | 5936 | struct btrfs_ordered_extent *ordered; |
| 5937 | ordered = btrfs_lookup_ordered_extent(inode, | 5937 | ordered = btrfs_lookup_ordered_extent(inode, file_offset); |
| 5938 | dip->logical_offset); | ||
| 5939 | if (!test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags) && | 5938 | if (!test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags) && |
| 5940 | !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) | 5939 | !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) |
| 5941 | btrfs_free_reserved_extent(root, ordered->start, | 5940 | btrfs_free_reserved_extent(root, ordered->start, |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index f1c9bb4079e..f87552a1d7e 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -947,23 +947,42 @@ out: | |||
| 947 | 947 | ||
| 948 | static noinline int btrfs_ioctl_snap_create(struct file *file, | 948 | static noinline int btrfs_ioctl_snap_create(struct file *file, |
| 949 | void __user *arg, int subvol, | 949 | void __user *arg, int subvol, |
| 950 | int async) | 950 | int v2) |
| 951 | { | 951 | { |
| 952 | struct btrfs_ioctl_vol_args *vol_args = NULL; | 952 | struct btrfs_ioctl_vol_args *vol_args = NULL; |
| 953 | struct btrfs_ioctl_async_vol_args *async_vol_args = NULL; | 953 | struct btrfs_ioctl_vol_args_v2 *vol_args_v2 = NULL; |
| 954 | char *name; | 954 | char *name; |
| 955 | u64 fd; | 955 | u64 fd; |
| 956 | u64 transid = 0; | ||
| 957 | int ret; | 956 | int ret; |
| 958 | 957 | ||
| 959 | if (async) { | 958 | if (v2) { |
| 960 | async_vol_args = memdup_user(arg, sizeof(*async_vol_args)); | 959 | u64 transid = 0; |
| 961 | if (IS_ERR(async_vol_args)) | 960 | u64 *ptr = NULL; |
| 962 | return PTR_ERR(async_vol_args); | ||
| 963 | 961 | ||
| 964 | name = async_vol_args->name; | 962 | vol_args_v2 = memdup_user(arg, sizeof(*vol_args_v2)); |
| 965 | fd = async_vol_args->fd; | 963 | if (IS_ERR(vol_args_v2)) |
| 966 | async_vol_args->name[BTRFS_SNAPSHOT_NAME_MAX] = '\0'; | 964 | return PTR_ERR(vol_args_v2); |
| 965 | |||
| 966 | if (vol_args_v2->flags & ~BTRFS_SUBVOL_CREATE_ASYNC) { | ||
| 967 | ret = -EINVAL; | ||
| 968 | goto out; | ||
| 969 | } | ||
| 970 | |||
| 971 | name = vol_args_v2->name; | ||
| 972 | fd = vol_args_v2->fd; | ||
| 973 | vol_args_v2->name[BTRFS_SUBVOL_NAME_MAX] = '\0'; | ||
| 974 | |||
| 975 | if (vol_args_v2->flags & BTRFS_SUBVOL_CREATE_ASYNC) | ||
| 976 | ptr = &transid; | ||
| 977 | |||
| 978 | ret = btrfs_ioctl_snap_create_transid(file, name, fd, | ||
| 979 | subvol, ptr); | ||
| 980 | |||
| 981 | if (ret == 0 && ptr && | ||
| 982 | copy_to_user(arg + | ||
| 983 | offsetof(struct btrfs_ioctl_vol_args_v2, | ||
| 984 | transid), ptr, sizeof(*ptr))) | ||
| 985 | ret = -EFAULT; | ||
| 967 | } else { | 986 | } else { |
| 968 | vol_args = memdup_user(arg, sizeof(*vol_args)); | 987 | vol_args = memdup_user(arg, sizeof(*vol_args)); |
| 969 | if (IS_ERR(vol_args)) | 988 | if (IS_ERR(vol_args)) |
| @@ -971,20 +990,13 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, | |||
| 971 | name = vol_args->name; | 990 | name = vol_args->name; |
| 972 | fd = vol_args->fd; | 991 | fd = vol_args->fd; |
| 973 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; | 992 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; |
| 974 | } | ||
| 975 | |||
| 976 | ret = btrfs_ioctl_snap_create_transid(file, name, fd, | ||
| 977 | subvol, &transid); | ||
| 978 | 993 | ||
| 979 | if (!ret && async) { | 994 | ret = btrfs_ioctl_snap_create_transid(file, name, fd, |
| 980 | if (copy_to_user(arg + | 995 | subvol, NULL); |
| 981 | offsetof(struct btrfs_ioctl_async_vol_args, | ||
| 982 | transid), &transid, sizeof(transid))) | ||
| 983 | return -EFAULT; | ||
| 984 | } | 996 | } |
| 985 | 997 | out: | |
| 986 | kfree(vol_args); | 998 | kfree(vol_args); |
| 987 | kfree(async_vol_args); | 999 | kfree(vol_args_v2); |
| 988 | 1000 | ||
| 989 | return ret; | 1001 | return ret; |
| 990 | } | 1002 | } |
| @@ -2246,7 +2258,7 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
| 2246 | return btrfs_ioctl_getversion(file, argp); | 2258 | return btrfs_ioctl_getversion(file, argp); |
| 2247 | case BTRFS_IOC_SNAP_CREATE: | 2259 | case BTRFS_IOC_SNAP_CREATE: |
| 2248 | return btrfs_ioctl_snap_create(file, argp, 0, 0); | 2260 | return btrfs_ioctl_snap_create(file, argp, 0, 0); |
| 2249 | case BTRFS_IOC_SNAP_CREATE_ASYNC: | 2261 | case BTRFS_IOC_SNAP_CREATE_V2: |
| 2250 | return btrfs_ioctl_snap_create(file, argp, 0, 1); | 2262 | return btrfs_ioctl_snap_create(file, argp, 0, 1); |
| 2251 | case BTRFS_IOC_SUBVOL_CREATE: | 2263 | case BTRFS_IOC_SUBVOL_CREATE: |
| 2252 | return btrfs_ioctl_snap_create(file, argp, 1, 0); | 2264 | return btrfs_ioctl_snap_create(file, argp, 1, 0); |
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 17c99ebdf96..c344d12c646 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h | |||
| @@ -30,11 +30,15 @@ struct btrfs_ioctl_vol_args { | |||
| 30 | char name[BTRFS_PATH_NAME_MAX + 1]; | 30 | char name[BTRFS_PATH_NAME_MAX + 1]; |
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | #define BTRFS_SNAPSHOT_NAME_MAX 4079 | 33 | #define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0) |
| 34 | struct btrfs_ioctl_async_vol_args { | 34 | |
| 35 | #define BTRFS_SUBVOL_NAME_MAX 4039 | ||
| 36 | struct btrfs_ioctl_vol_args_v2 { | ||
| 35 | __s64 fd; | 37 | __s64 fd; |
| 36 | __u64 transid; | 38 | __u64 transid; |
| 37 | char name[BTRFS_SNAPSHOT_NAME_MAX + 1]; | 39 | __u64 flags; |
| 40 | __u64 unused[4]; | ||
| 41 | char name[BTRFS_SUBVOL_NAME_MAX + 1]; | ||
| 38 | }; | 42 | }; |
| 39 | 43 | ||
| 40 | #define BTRFS_INO_LOOKUP_PATH_MAX 4080 | 44 | #define BTRFS_INO_LOOKUP_PATH_MAX 4080 |
| @@ -187,6 +191,6 @@ struct btrfs_ioctl_space_args { | |||
| 187 | struct btrfs_ioctl_space_args) | 191 | struct btrfs_ioctl_space_args) |
| 188 | #define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64) | 192 | #define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64) |
| 189 | #define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64) | 193 | #define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64) |
| 190 | #define BTRFS_IOC_SNAP_CREATE_ASYNC _IOW(BTRFS_IOCTL_MAGIC, 23, \ | 194 | #define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \ |
| 191 | struct btrfs_ioctl_async_vol_args) | 195 | struct btrfs_ioctl_vol_args_v2) |
| 192 | #endif | 196 | #endif |
diff --git a/fs/btrfs/orphan.c b/fs/btrfs/orphan.c index 79cba5fbc28..f8be250963a 100644 --- a/fs/btrfs/orphan.c +++ b/fs/btrfs/orphan.c | |||
| @@ -56,8 +56,12 @@ int btrfs_del_orphan_item(struct btrfs_trans_handle *trans, | |||
| 56 | return -ENOMEM; | 56 | return -ENOMEM; |
| 57 | 57 | ||
| 58 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); | 58 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
| 59 | if (ret) | 59 | if (ret < 0) |
| 60 | goto out; | 60 | goto out; |
| 61 | if (ret) { | ||
| 62 | ret = -ENOENT; | ||
| 63 | goto out; | ||
| 64 | } | ||
| 61 | 65 | ||
| 62 | ret = btrfs_del_item(trans, root, path); | 66 | ret = btrfs_del_item(trans, root, path); |
| 63 | 67 | ||
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index dbb51ea7a13..883c6fa1367 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -685,9 +685,9 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 685 | mutex_unlock(&root->d_inode->i_mutex); | 685 | mutex_unlock(&root->d_inode->i_mutex); |
| 686 | 686 | ||
| 687 | if (IS_ERR(new_root)) { | 687 | if (IS_ERR(new_root)) { |
| 688 | dput(root); | ||
| 688 | deactivate_locked_super(s); | 689 | deactivate_locked_super(s); |
| 689 | error = PTR_ERR(new_root); | 690 | error = PTR_ERR(new_root); |
| 690 | dput(root); | ||
| 691 | goto error_free_subvol_name; | 691 | goto error_free_subvol_name; |
| 692 | } | 692 | } |
| 693 | if (!new_root->d_inode) { | 693 | if (!new_root->d_inode) { |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index cc04dc1445d..6b988450783 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -412,12 +412,16 @@ static noinline int device_list_add(const char *path, | |||
| 412 | 412 | ||
| 413 | device->fs_devices = fs_devices; | 413 | device->fs_devices = fs_devices; |
| 414 | fs_devices->num_devices++; | 414 | fs_devices->num_devices++; |
| 415 | } else if (strcmp(device->name, path)) { | 415 | } else if (!device->name || strcmp(device->name, path)) { |
| 416 | name = kstrdup(path, GFP_NOFS); | 416 | name = kstrdup(path, GFP_NOFS); |
| 417 | if (!name) | 417 | if (!name) |
| 418 | return -ENOMEM; | 418 | return -ENOMEM; |
| 419 | kfree(device->name); | 419 | kfree(device->name); |
| 420 | device->name = name; | 420 | device->name = name; |
| 421 | if (device->missing) { | ||
| 422 | fs_devices->missing_devices--; | ||
| 423 | device->missing = 0; | ||
| 424 | } | ||
| 421 | } | 425 | } |
| 422 | 426 | ||
| 423 | if (found_transid > fs_devices->latest_trans) { | 427 | if (found_transid > fs_devices->latest_trans) { |
| @@ -1236,6 +1240,9 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
| 1236 | 1240 | ||
| 1237 | device->fs_devices->num_devices--; | 1241 | device->fs_devices->num_devices--; |
| 1238 | 1242 | ||
| 1243 | if (device->missing) | ||
| 1244 | root->fs_info->fs_devices->missing_devices--; | ||
| 1245 | |||
| 1239 | next_device = list_entry(root->fs_info->fs_devices->devices.next, | 1246 | next_device = list_entry(root->fs_info->fs_devices->devices.next, |
| 1240 | struct btrfs_device, dev_list); | 1247 | struct btrfs_device, dev_list); |
| 1241 | if (device->bdev == root->fs_info->sb->s_bdev) | 1248 | if (device->bdev == root->fs_info->sb->s_bdev) |
| @@ -3080,7 +3087,9 @@ static struct btrfs_device *add_missing_dev(struct btrfs_root *root, | |||
| 3080 | device->devid = devid; | 3087 | device->devid = devid; |
| 3081 | device->work.func = pending_bios_fn; | 3088 | device->work.func = pending_bios_fn; |
| 3082 | device->fs_devices = fs_devices; | 3089 | device->fs_devices = fs_devices; |
| 3090 | device->missing = 1; | ||
| 3083 | fs_devices->num_devices++; | 3091 | fs_devices->num_devices++; |
| 3092 | fs_devices->missing_devices++; | ||
| 3084 | spin_lock_init(&device->io_lock); | 3093 | spin_lock_init(&device->io_lock); |
| 3085 | INIT_LIST_HEAD(&device->dev_alloc_list); | 3094 | INIT_LIST_HEAD(&device->dev_alloc_list); |
| 3086 | memcpy(device->uuid, dev_uuid, BTRFS_UUID_SIZE); | 3095 | memcpy(device->uuid, dev_uuid, BTRFS_UUID_SIZE); |
| @@ -3278,6 +3287,15 @@ static int read_one_dev(struct btrfs_root *root, | |||
| 3278 | device = add_missing_dev(root, devid, dev_uuid); | 3287 | device = add_missing_dev(root, devid, dev_uuid); |
| 3279 | if (!device) | 3288 | if (!device) |
| 3280 | return -ENOMEM; | 3289 | return -ENOMEM; |
| 3290 | } else if (!device->missing) { | ||
| 3291 | /* | ||
| 3292 | * this happens when a device that was properly setup | ||
| 3293 | * in the device info lists suddenly goes bad. | ||
| 3294 | * device->bdev is NULL, and so we have to set | ||
| 3295 | * device->missing to one here | ||
| 3296 | */ | ||
| 3297 | root->fs_info->fs_devices->missing_devices++; | ||
| 3298 | device->missing = 1; | ||
| 3281 | } | 3299 | } |
| 3282 | } | 3300 | } |
| 3283 | 3301 | ||
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 2b638b6e4ee..2740db49eb0 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
| @@ -44,6 +44,7 @@ struct btrfs_device { | |||
| 44 | 44 | ||
| 45 | int writeable; | 45 | int writeable; |
| 46 | int in_fs_metadata; | 46 | int in_fs_metadata; |
| 47 | int missing; | ||
| 47 | 48 | ||
| 48 | spinlock_t io_lock; | 49 | spinlock_t io_lock; |
| 49 | 50 | ||
| @@ -93,6 +94,7 @@ struct btrfs_fs_devices { | |||
| 93 | u64 num_devices; | 94 | u64 num_devices; |
| 94 | u64 open_devices; | 95 | u64 open_devices; |
| 95 | u64 rw_devices; | 96 | u64 rw_devices; |
| 97 | u64 missing_devices; | ||
| 96 | u64 total_rw_bytes; | 98 | u64 total_rw_bytes; |
| 97 | struct block_device *latest_bdev; | 99 | struct block_device *latest_bdev; |
| 98 | 100 | ||
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 7d447af84ec..158c700fdca 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
| @@ -114,8 +114,8 @@ static int __dcache_readdir(struct file *filp, | |||
| 114 | spin_lock(&dcache_lock); | 114 | spin_lock(&dcache_lock); |
| 115 | 115 | ||
| 116 | /* start at beginning? */ | 116 | /* start at beginning? */ |
| 117 | if (filp->f_pos == 2 || (last && | 117 | if (filp->f_pos == 2 || last == NULL || |
| 118 | filp->f_pos < ceph_dentry(last)->offset)) { | 118 | filp->f_pos < ceph_dentry(last)->offset) { |
| 119 | if (list_empty(&parent->d_subdirs)) | 119 | if (list_empty(&parent->d_subdirs)) |
| 120 | goto out_unlock; | 120 | goto out_unlock; |
| 121 | p = parent->d_subdirs.prev; | 121 | p = parent->d_subdirs.prev; |
diff --git a/fs/ceph/ioctl.h b/fs/ceph/ioctl.h index a6ce54e94eb..52e8fd74d45 100644 --- a/fs/ceph/ioctl.h +++ b/fs/ceph/ioctl.h | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | #include <linux/ioctl.h> | 4 | #include <linux/ioctl.h> |
| 5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
| 6 | 6 | ||
| 7 | #define CEPH_IOCTL_MAGIC 0x98 | 7 | #define CEPH_IOCTL_MAGIC 0x97 |
| 8 | 8 | ||
| 9 | /* just use u64 to align sanely on all archs */ | 9 | /* just use u64 to align sanely on all archs */ |
| 10 | struct ceph_ioctl_layout { | 10 | struct ceph_ioctl_layout { |
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index 40abde93c34..476b329867d 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
| @@ -11,40 +11,68 @@ | |||
| 11 | * Implement fcntl and flock locking functions. | 11 | * Implement fcntl and flock locking functions. |
| 12 | */ | 12 | */ |
| 13 | static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, | 13 | static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, |
| 14 | u64 pid, u64 pid_ns, | 14 | int cmd, u8 wait, struct file_lock *fl) |
| 15 | int cmd, u64 start, u64 length, u8 wait) | ||
| 16 | { | 15 | { |
| 17 | struct inode *inode = file->f_dentry->d_inode; | 16 | struct inode *inode = file->f_dentry->d_inode; |
| 18 | struct ceph_mds_client *mdsc = | 17 | struct ceph_mds_client *mdsc = |
| 19 | ceph_sb_to_client(inode->i_sb)->mdsc; | 18 | ceph_sb_to_client(inode->i_sb)->mdsc; |
| 20 | struct ceph_mds_request *req; | 19 | struct ceph_mds_request *req; |
| 21 | int err; | 20 | int err; |
| 21 | u64 length = 0; | ||
| 22 | 22 | ||
| 23 | req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS); | 23 | req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS); |
| 24 | if (IS_ERR(req)) | 24 | if (IS_ERR(req)) |
| 25 | return PTR_ERR(req); | 25 | return PTR_ERR(req); |
| 26 | req->r_inode = igrab(inode); | 26 | req->r_inode = igrab(inode); |
| 27 | 27 | ||
| 28 | /* mds requires start and length rather than start and end */ | ||
| 29 | if (LLONG_MAX == fl->fl_end) | ||
| 30 | length = 0; | ||
| 31 | else | ||
| 32 | length = fl->fl_end - fl->fl_start + 1; | ||
| 33 | |||
| 28 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " | 34 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " |
| 29 | "length: %llu, wait: %d, type`: %d", (int)lock_type, | 35 | "length: %llu, wait: %d, type`: %d", (int)lock_type, |
| 30 | (int)operation, pid, start, length, wait, cmd); | 36 | (int)operation, (u64)fl->fl_pid, fl->fl_start, |
| 37 | length, wait, fl->fl_type); | ||
| 38 | |||
| 31 | 39 | ||
| 32 | req->r_args.filelock_change.rule = lock_type; | 40 | req->r_args.filelock_change.rule = lock_type; |
| 33 | req->r_args.filelock_change.type = cmd; | 41 | req->r_args.filelock_change.type = cmd; |
| 34 | req->r_args.filelock_change.pid = cpu_to_le64(pid); | 42 | req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid); |
| 35 | /* This should be adjusted, but I'm not sure if | 43 | /* This should be adjusted, but I'm not sure if |
| 36 | namespaces actually get id numbers*/ | 44 | namespaces actually get id numbers*/ |
| 37 | req->r_args.filelock_change.pid_namespace = | 45 | req->r_args.filelock_change.pid_namespace = |
| 38 | cpu_to_le64((u64)pid_ns); | 46 | cpu_to_le64((u64)(unsigned long)fl->fl_nspid); |
| 39 | req->r_args.filelock_change.start = cpu_to_le64(start); | 47 | req->r_args.filelock_change.start = cpu_to_le64(fl->fl_start); |
| 40 | req->r_args.filelock_change.length = cpu_to_le64(length); | 48 | req->r_args.filelock_change.length = cpu_to_le64(length); |
| 41 | req->r_args.filelock_change.wait = wait; | 49 | req->r_args.filelock_change.wait = wait; |
| 42 | 50 | ||
| 43 | err = ceph_mdsc_do_request(mdsc, inode, req); | 51 | err = ceph_mdsc_do_request(mdsc, inode, req); |
| 52 | |||
| 53 | if ( operation == CEPH_MDS_OP_GETFILELOCK){ | ||
| 54 | fl->fl_pid = le64_to_cpu(req->r_reply_info.filelock_reply->pid); | ||
| 55 | if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type) | ||
| 56 | fl->fl_type = F_RDLCK; | ||
| 57 | else if (CEPH_LOCK_EXCL == req->r_reply_info.filelock_reply->type) | ||
| 58 | fl->fl_type = F_WRLCK; | ||
| 59 | else | ||
| 60 | fl->fl_type = F_UNLCK; | ||
| 61 | |||
| 62 | fl->fl_start = le64_to_cpu(req->r_reply_info.filelock_reply->start); | ||
| 63 | length = le64_to_cpu(req->r_reply_info.filelock_reply->start) + | ||
| 64 | le64_to_cpu(req->r_reply_info.filelock_reply->length); | ||
| 65 | if (length >= 1) | ||
| 66 | fl->fl_end = length -1; | ||
| 67 | else | ||
| 68 | fl->fl_end = 0; | ||
| 69 | |||
| 70 | } | ||
| 44 | ceph_mdsc_put_request(req); | 71 | ceph_mdsc_put_request(req); |
| 45 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " | 72 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " |
| 46 | "length: %llu, wait: %d, type`: %d err code %d", (int)lock_type, | 73 | "length: %llu, wait: %d, type`: %d, err code %d", (int)lock_type, |
| 47 | (int)operation, pid, start, length, wait, cmd, err); | 74 | (int)operation, (u64)fl->fl_pid, fl->fl_start, |
| 75 | length, wait, fl->fl_type, err); | ||
| 48 | return err; | 76 | return err; |
| 49 | } | 77 | } |
| 50 | 78 | ||
| @@ -54,7 +82,6 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, | |||
| 54 | */ | 82 | */ |
| 55 | int ceph_lock(struct file *file, int cmd, struct file_lock *fl) | 83 | int ceph_lock(struct file *file, int cmd, struct file_lock *fl) |
| 56 | { | 84 | { |
| 57 | u64 length; | ||
| 58 | u8 lock_cmd; | 85 | u8 lock_cmd; |
| 59 | int err; | 86 | int err; |
| 60 | u8 wait = 0; | 87 | u8 wait = 0; |
| @@ -76,29 +103,20 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) | |||
| 76 | else | 103 | else |
| 77 | lock_cmd = CEPH_LOCK_UNLOCK; | 104 | lock_cmd = CEPH_LOCK_UNLOCK; |
| 78 | 105 | ||
| 79 | if (LLONG_MAX == fl->fl_end) | 106 | err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, lock_cmd, wait, fl); |
| 80 | length = 0; | ||
| 81 | else | ||
| 82 | length = fl->fl_end - fl->fl_start + 1; | ||
| 83 | |||
| 84 | err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, | ||
| 85 | (u64)fl->fl_pid, | ||
| 86 | (u64)(unsigned long)fl->fl_nspid, | ||
| 87 | lock_cmd, fl->fl_start, | ||
| 88 | length, wait); | ||
| 89 | if (!err) { | 107 | if (!err) { |
| 90 | dout("mds locked, locking locally"); | 108 | if ( op != CEPH_MDS_OP_GETFILELOCK ){ |
| 91 | err = posix_lock_file(file, fl, NULL); | 109 | dout("mds locked, locking locally"); |
| 92 | if (err && (CEPH_MDS_OP_SETFILELOCK == op)) { | 110 | err = posix_lock_file(file, fl, NULL); |
| 93 | /* undo! This should only happen if the kernel detects | 111 | if (err && (CEPH_MDS_OP_SETFILELOCK == op)) { |
| 94 | * local deadlock. */ | 112 | /* undo! This should only happen if the kernel detects |
| 95 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, | 113 | * local deadlock. */ |
| 96 | (u64)fl->fl_pid, | 114 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, |
| 97 | (u64)(unsigned long)fl->fl_nspid, | 115 | CEPH_LOCK_UNLOCK, 0, fl); |
| 98 | CEPH_LOCK_UNLOCK, fl->fl_start, | 116 | dout("got %d on posix_lock_file, undid lock", err); |
| 99 | length, 0); | 117 | } |
| 100 | dout("got %d on posix_lock_file, undid lock", err); | ||
| 101 | } | 118 | } |
| 119 | |||
| 102 | } else { | 120 | } else { |
| 103 | dout("mds returned error code %d", err); | 121 | dout("mds returned error code %d", err); |
| 104 | } | 122 | } |
| @@ -107,7 +125,6 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) | |||
| 107 | 125 | ||
| 108 | int ceph_flock(struct file *file, int cmd, struct file_lock *fl) | 126 | int ceph_flock(struct file *file, int cmd, struct file_lock *fl) |
| 109 | { | 127 | { |
| 110 | u64 length; | ||
| 111 | u8 lock_cmd; | 128 | u8 lock_cmd; |
| 112 | int err; | 129 | int err; |
| 113 | u8 wait = 1; | 130 | u8 wait = 1; |
| @@ -127,26 +144,15 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) | |||
| 127 | lock_cmd = CEPH_LOCK_EXCL; | 144 | lock_cmd = CEPH_LOCK_EXCL; |
| 128 | else | 145 | else |
| 129 | lock_cmd = CEPH_LOCK_UNLOCK; | 146 | lock_cmd = CEPH_LOCK_UNLOCK; |
| 130 | /* mds requires start and length rather than start and end */ | ||
| 131 | if (LLONG_MAX == fl->fl_end) | ||
| 132 | length = 0; | ||
| 133 | else | ||
| 134 | length = fl->fl_end - fl->fl_start + 1; | ||
| 135 | 147 | ||
| 136 | err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK, | 148 | err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK, |
| 137 | file, (u64)fl->fl_pid, | 149 | file, lock_cmd, wait, fl); |
| 138 | (u64)(unsigned long)fl->fl_nspid, | ||
| 139 | lock_cmd, fl->fl_start, | ||
| 140 | length, wait); | ||
| 141 | if (!err) { | 150 | if (!err) { |
| 142 | err = flock_lock_file_wait(file, fl); | 151 | err = flock_lock_file_wait(file, fl); |
| 143 | if (err) { | 152 | if (err) { |
| 144 | ceph_lock_message(CEPH_LOCK_FLOCK, | 153 | ceph_lock_message(CEPH_LOCK_FLOCK, |
| 145 | CEPH_MDS_OP_SETFILELOCK, | 154 | CEPH_MDS_OP_SETFILELOCK, |
| 146 | file, (u64)fl->fl_pid, | 155 | file, CEPH_LOCK_UNLOCK, 0, fl); |
| 147 | (u64)(unsigned long)fl->fl_nspid, | ||
| 148 | CEPH_LOCK_UNLOCK, fl->fl_start, | ||
| 149 | length, 0); | ||
| 150 | dout("got %d on flock_lock_file_wait, undid lock", err); | 156 | dout("got %d on flock_lock_file_wait, undid lock", err); |
| 151 | } | 157 | } |
| 152 | } else { | 158 | } else { |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 098b1850847..38800eaa81d 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
| @@ -202,6 +202,38 @@ out_bad: | |||
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | /* | 204 | /* |
| 205 | * parse fcntl F_GETLK results | ||
| 206 | */ | ||
| 207 | static int parse_reply_info_filelock(void **p, void *end, | ||
| 208 | struct ceph_mds_reply_info_parsed *info) | ||
| 209 | { | ||
| 210 | if (*p + sizeof(*info->filelock_reply) > end) | ||
| 211 | goto bad; | ||
| 212 | |||
| 213 | info->filelock_reply = *p; | ||
| 214 | *p += sizeof(*info->filelock_reply); | ||
| 215 | |||
| 216 | if (unlikely(*p != end)) | ||
| 217 | goto bad; | ||
| 218 | return 0; | ||
| 219 | |||
| 220 | bad: | ||
| 221 | return -EIO; | ||
| 222 | } | ||
| 223 | |||
| 224 | /* | ||
| 225 | * parse extra results | ||
| 226 | */ | ||
| 227 | static int parse_reply_info_extra(void **p, void *end, | ||
| 228 | struct ceph_mds_reply_info_parsed *info) | ||
| 229 | { | ||
| 230 | if (info->head->op == CEPH_MDS_OP_GETFILELOCK) | ||
| 231 | return parse_reply_info_filelock(p, end, info); | ||
| 232 | else | ||
| 233 | return parse_reply_info_dir(p, end, info); | ||
| 234 | } | ||
| 235 | |||
| 236 | /* | ||
| 205 | * parse entire mds reply | 237 | * parse entire mds reply |
| 206 | */ | 238 | */ |
| 207 | static int parse_reply_info(struct ceph_msg *msg, | 239 | static int parse_reply_info(struct ceph_msg *msg, |
| @@ -223,10 +255,10 @@ static int parse_reply_info(struct ceph_msg *msg, | |||
| 223 | goto out_bad; | 255 | goto out_bad; |
| 224 | } | 256 | } |
| 225 | 257 | ||
| 226 | /* dir content */ | 258 | /* extra */ |
| 227 | ceph_decode_32_safe(&p, end, len, bad); | 259 | ceph_decode_32_safe(&p, end, len, bad); |
| 228 | if (len > 0) { | 260 | if (len > 0) { |
| 229 | err = parse_reply_info_dir(&p, p+len, info); | 261 | err = parse_reply_info_extra(&p, p+len, info); |
| 230 | if (err < 0) | 262 | if (err < 0) |
| 231 | goto out_bad; | 263 | goto out_bad; |
| 232 | } | 264 | } |
| @@ -2074,7 +2106,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) | |||
| 2074 | 2106 | ||
| 2075 | mutex_lock(&session->s_mutex); | 2107 | mutex_lock(&session->s_mutex); |
| 2076 | if (err < 0) { | 2108 | if (err < 0) { |
| 2077 | pr_err("mdsc_handle_reply got corrupt reply mds%d\n", mds); | 2109 | pr_err("mdsc_handle_reply got corrupt reply mds%d(tid:%lld)\n", mds, tid); |
| 2078 | ceph_msg_dump(msg); | 2110 | ceph_msg_dump(msg); |
| 2079 | goto out_err; | 2111 | goto out_err; |
| 2080 | } | 2112 | } |
| @@ -2094,7 +2126,8 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) | |||
| 2094 | mutex_lock(&req->r_fill_mutex); | 2126 | mutex_lock(&req->r_fill_mutex); |
| 2095 | err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session); | 2127 | err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session); |
| 2096 | if (err == 0) { | 2128 | if (err == 0) { |
| 2097 | if (result == 0 && rinfo->dir_nr) | 2129 | if (result == 0 && req->r_op != CEPH_MDS_OP_GETFILELOCK && |
| 2130 | rinfo->dir_nr) | ||
| 2098 | ceph_readdir_prepopulate(req, req->r_session); | 2131 | ceph_readdir_prepopulate(req, req->r_session); |
| 2099 | ceph_unreserve_caps(mdsc, &req->r_caps_reservation); | 2132 | ceph_unreserve_caps(mdsc, &req->r_caps_reservation); |
| 2100 | } | 2133 | } |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 9341fd4f143..aabe563b54d 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
| @@ -42,26 +42,37 @@ struct ceph_mds_reply_info_in { | |||
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | /* | 44 | /* |
| 45 | * parsed info about an mds reply, including information about the | 45 | * parsed info about an mds reply, including information about |
| 46 | * target inode and/or its parent directory and dentry, and directory | 46 | * either: 1) the target inode and/or its parent directory and dentry, |
| 47 | * contents (for readdir results). | 47 | * and directory contents (for readdir results), or |
| 48 | * 2) the file range lock info (for fcntl F_GETLK results). | ||
| 48 | */ | 49 | */ |
| 49 | struct ceph_mds_reply_info_parsed { | 50 | struct ceph_mds_reply_info_parsed { |
| 50 | struct ceph_mds_reply_head *head; | 51 | struct ceph_mds_reply_head *head; |
| 51 | 52 | ||
| 53 | /* trace */ | ||
| 52 | struct ceph_mds_reply_info_in diri, targeti; | 54 | struct ceph_mds_reply_info_in diri, targeti; |
| 53 | struct ceph_mds_reply_dirfrag *dirfrag; | 55 | struct ceph_mds_reply_dirfrag *dirfrag; |
| 54 | char *dname; | 56 | char *dname; |
| 55 | u32 dname_len; | 57 | u32 dname_len; |
| 56 | struct ceph_mds_reply_lease *dlease; | 58 | struct ceph_mds_reply_lease *dlease; |
| 57 | 59 | ||
| 58 | struct ceph_mds_reply_dirfrag *dir_dir; | 60 | /* extra */ |
| 59 | int dir_nr; | 61 | union { |
| 60 | char **dir_dname; | 62 | /* for fcntl F_GETLK results */ |
| 61 | u32 *dir_dname_len; | 63 | struct ceph_filelock *filelock_reply; |
| 62 | struct ceph_mds_reply_lease **dir_dlease; | 64 | |
| 63 | struct ceph_mds_reply_info_in *dir_in; | 65 | /* for readdir results */ |
| 64 | u8 dir_complete, dir_end; | 66 | struct { |
| 67 | struct ceph_mds_reply_dirfrag *dir_dir; | ||
| 68 | int dir_nr; | ||
| 69 | char **dir_dname; | ||
| 70 | u32 *dir_dname_len; | ||
| 71 | struct ceph_mds_reply_lease **dir_dlease; | ||
| 72 | struct ceph_mds_reply_info_in *dir_in; | ||
| 73 | u8 dir_complete, dir_end; | ||
| 74 | }; | ||
| 75 | }; | ||
| 65 | 76 | ||
| 66 | /* encoded blob describing snapshot contexts for certain | 77 | /* encoded blob describing snapshot contexts for certain |
| 67 | operations (e.g., open) */ | 78 | operations (e.g., open) */ |
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile index adefa60a9bd..43b19dd3919 100644 --- a/fs/cifs/Makefile +++ b/fs/cifs/Makefile | |||
| @@ -6,7 +6,9 @@ obj-$(CONFIG_CIFS) += cifs.o | |||
| 6 | cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ | 6 | cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ |
| 7 | link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \ | 7 | link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \ |
| 8 | md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \ | 8 | md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \ |
| 9 | readdir.o ioctl.o sess.o export.o cifsacl.o | 9 | readdir.o ioctl.o sess.o export.o |
| 10 | |||
| 11 | cifs-$(CONFIG_CIFS_ACL) += cifsacl.o | ||
| 10 | 12 | ||
| 11 | cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o | 13 | cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o |
| 12 | 14 | ||
diff --git a/fs/cifs/README b/fs/cifs/README index ee68d103654..46af99ab361 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
| @@ -337,6 +337,15 @@ A partial list of the supported mount options follows: | |||
| 337 | wsize default write size (default 57344) | 337 | wsize default write size (default 57344) |
| 338 | maximum wsize currently allowed by CIFS is 57344 (fourteen | 338 | maximum wsize currently allowed by CIFS is 57344 (fourteen |
| 339 | 4096 byte pages) | 339 | 4096 byte pages) |
| 340 | actimeo=n attribute cache timeout in seconds (default 1 second). | ||
| 341 | After this timeout, the cifs client requests fresh attribute | ||
| 342 | information from the server. This option allows to tune the | ||
| 343 | attribute cache timeout to suit the workload needs. Shorter | ||
| 344 | timeouts mean better the cache coherency, but increased number | ||
| 345 | of calls to the server. Longer timeouts mean reduced number | ||
| 346 | of calls to the server at the expense of less stricter cache | ||
| 347 | coherency checks (i.e. incorrect attribute cache for a short | ||
| 348 | period of time). | ||
| 340 | rw mount the network share read-write (note that the | 349 | rw mount the network share read-write (note that the |
| 341 | server may still consider the share read-only) | 350 | server may still consider the share read-only) |
| 342 | ro mount network share read-only | 351 | ro mount network share read-only |
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index e9a393c9c2c..7852cd67705 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
| @@ -48,6 +48,7 @@ struct cifs_sb_info { | |||
| 48 | struct nls_table *local_nls; | 48 | struct nls_table *local_nls; |
| 49 | unsigned int rsize; | 49 | unsigned int rsize; |
| 50 | unsigned int wsize; | 50 | unsigned int wsize; |
| 51 | unsigned long actimeo; /* attribute cache timeout (jiffies) */ | ||
| 51 | atomic_t active; | 52 | atomic_t active; |
| 52 | uid_t mnt_uid; | 53 | uid_t mnt_uid; |
| 53 | gid_t mnt_gid; | 54 | gid_t mnt_gid; |
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index c6ebea088ac..a437ec391a0 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
| @@ -30,8 +30,6 @@ | |||
| 30 | #include "cifs_debug.h" | 30 | #include "cifs_debug.h" |
| 31 | 31 | ||
| 32 | 32 | ||
| 33 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
| 34 | |||
| 35 | static struct cifs_wksid wksidarr[NUM_WK_SIDS] = { | 33 | static struct cifs_wksid wksidarr[NUM_WK_SIDS] = { |
| 36 | {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"}, | 34 | {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"}, |
| 37 | {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"}, | 35 | {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"}, |
| @@ -774,4 +772,3 @@ int mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode) | |||
| 774 | 772 | ||
| 775 | return rc; | 773 | return rc; |
| 776 | } | 774 | } |
| 777 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | ||
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h index 6c8096cf515..c4ae7d03656 100644 --- a/fs/cifs/cifsacl.h +++ b/fs/cifs/cifsacl.h | |||
| @@ -74,11 +74,7 @@ struct cifs_wksid { | |||
| 74 | char sidname[SIDNAMELENGTH]; | 74 | char sidname[SIDNAMELENGTH]; |
| 75 | } __attribute__((packed)); | 75 | } __attribute__((packed)); |
| 76 | 76 | ||
| 77 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
| 78 | |||
| 79 | extern int match_sid(struct cifs_sid *); | 77 | extern int match_sid(struct cifs_sid *); |
| 80 | extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *); | 78 | extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *); |
| 81 | 79 | ||
| 82 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | ||
| 83 | |||
| 84 | #endif /* _CIFSACL_H */ | 80 | #endif /* _CIFSACL_H */ |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 76c8a906a63..3936aa7f2c2 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -463,6 +463,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) | |||
| 463 | 463 | ||
| 464 | seq_printf(s, ",rsize=%d", cifs_sb->rsize); | 464 | seq_printf(s, ",rsize=%d", cifs_sb->rsize); |
| 465 | seq_printf(s, ",wsize=%d", cifs_sb->wsize); | 465 | seq_printf(s, ",wsize=%d", cifs_sb->wsize); |
| 466 | /* convert actimeo and display it in seconds */ | ||
| 467 | seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); | ||
| 466 | 468 | ||
| 467 | return 0; | 469 | return 0; |
| 468 | } | 470 | } |
| @@ -935,7 +937,6 @@ init_cifs(void) | |||
| 935 | GlobalCurrentXid = 0; | 937 | GlobalCurrentXid = 0; |
| 936 | GlobalTotalActiveXid = 0; | 938 | GlobalTotalActiveXid = 0; |
| 937 | GlobalMaxActiveXid = 0; | 939 | GlobalMaxActiveXid = 0; |
| 938 | memset(Local_System_Name, 0, 15); | ||
| 939 | spin_lock_init(&cifs_tcp_ses_lock); | 940 | spin_lock_init(&cifs_tcp_ses_lock); |
| 940 | spin_lock_init(&cifs_file_list_lock); | 941 | spin_lock_init(&cifs_file_list_lock); |
| 941 | spin_lock_init(&GlobalMid_Lock); | 942 | spin_lock_init(&GlobalMid_Lock); |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index b577bf0a1bb..7136c0c3e2f 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -45,6 +45,16 @@ | |||
| 45 | #define CIFS_MIN_RCV_POOL 4 | 45 | #define CIFS_MIN_RCV_POOL 4 |
| 46 | 46 | ||
| 47 | /* | 47 | /* |
| 48 | * default attribute cache timeout (jiffies) | ||
| 49 | */ | ||
| 50 | #define CIFS_DEF_ACTIMEO (1 * HZ) | ||
| 51 | |||
| 52 | /* | ||
| 53 | * max attribute cache timeout (jiffies) - 2^30 | ||
| 54 | */ | ||
| 55 | #define CIFS_MAX_ACTIMEO (1 << 30) | ||
| 56 | |||
| 57 | /* | ||
| 48 | * MAX_REQ is the maximum number of requests that WE will send | 58 | * MAX_REQ is the maximum number of requests that WE will send |
| 49 | * on one socket concurrently. It also matches the most common | 59 | * on one socket concurrently. It also matches the most common |
| 50 | * value of max multiplex returned by servers. We may | 60 | * value of max multiplex returned by servers. We may |
| @@ -746,8 +756,6 @@ GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */ | |||
| 746 | GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */ | 756 | GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */ |
| 747 | GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */ | 757 | GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */ |
| 748 | /* on midQ entries */ | 758 | /* on midQ entries */ |
| 749 | GLOBAL_EXTERN char Local_System_Name[15]; | ||
| 750 | |||
| 751 | /* | 759 | /* |
| 752 | * Global counters, updated atomically | 760 | * Global counters, updated atomically |
| 753 | */ | 761 | */ |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index db961dc4fd3..e6d1481b16c 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -54,7 +54,8 @@ do { \ | |||
| 54 | __func__, curr_xid, (int)rc); \ | 54 | __func__, curr_xid, (int)rc); \ |
| 55 | } while (0) | 55 | } while (0) |
| 56 | extern char *build_path_from_dentry(struct dentry *); | 56 | extern char *build_path_from_dentry(struct dentry *); |
| 57 | extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb); | 57 | extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb, |
| 58 | struct cifsTconInfo *tcon); | ||
| 58 | extern char *build_wildcard_path_from_dentry(struct dentry *direntry); | 59 | extern char *build_wildcard_path_from_dentry(struct dentry *direntry); |
| 59 | extern char *cifs_compose_mount_options(const char *sb_mountdata, | 60 | extern char *cifs_compose_mount_options(const char *sb_mountdata, |
| 60 | const char *fullpath, const struct dfs_info3_param *ref, | 61 | const char *fullpath, const struct dfs_info3_param *ref, |
| @@ -79,9 +80,7 @@ extern bool is_valid_oplock_break(struct smb_hdr *smb, | |||
| 79 | struct TCP_Server_Info *); | 80 | struct TCP_Server_Info *); |
| 80 | extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); | 81 | extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); |
| 81 | extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool); | 82 | extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool); |
| 82 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
| 83 | extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool); | 83 | extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool); |
| 84 | #endif | ||
| 85 | extern unsigned int smbCalcSize(struct smb_hdr *ptr); | 84 | extern unsigned int smbCalcSize(struct smb_hdr *ptr); |
| 86 | extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); | 85 | extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); |
| 87 | extern int decode_negTokenInit(unsigned char *security_blob, int length, | 86 | extern int decode_negTokenInit(unsigned char *security_blob, int length, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 2f2632b6df5..67acfb3acad 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -2478,95 +2478,6 @@ querySymLinkRetry: | |||
| 2478 | } | 2478 | } |
| 2479 | 2479 | ||
| 2480 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 2480 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
| 2481 | /* Initialize NT TRANSACT SMB into small smb request buffer. | ||
| 2482 | This assumes that all NT TRANSACTS that we init here have | ||
| 2483 | total parm and data under about 400 bytes (to fit in small cifs | ||
| 2484 | buffer size), which is the case so far, it easily fits. NB: | ||
| 2485 | Setup words themselves and ByteCount | ||
| 2486 | MaxSetupCount (size of returned setup area) and | ||
| 2487 | MaxParameterCount (returned parms size) must be set by caller */ | ||
| 2488 | static int | ||
| 2489 | smb_init_nttransact(const __u16 sub_command, const int setup_count, | ||
| 2490 | const int parm_len, struct cifsTconInfo *tcon, | ||
| 2491 | void **ret_buf) | ||
| 2492 | { | ||
| 2493 | int rc; | ||
| 2494 | __u32 temp_offset; | ||
| 2495 | struct smb_com_ntransact_req *pSMB; | ||
| 2496 | |||
| 2497 | rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, | ||
| 2498 | (void **)&pSMB); | ||
| 2499 | if (rc) | ||
| 2500 | return rc; | ||
| 2501 | *ret_buf = (void *)pSMB; | ||
| 2502 | pSMB->Reserved = 0; | ||
| 2503 | pSMB->TotalParameterCount = cpu_to_le32(parm_len); | ||
| 2504 | pSMB->TotalDataCount = 0; | ||
| 2505 | pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf - | ||
| 2506 | MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); | ||
| 2507 | pSMB->ParameterCount = pSMB->TotalParameterCount; | ||
| 2508 | pSMB->DataCount = pSMB->TotalDataCount; | ||
| 2509 | temp_offset = offsetof(struct smb_com_ntransact_req, Parms) + | ||
| 2510 | (setup_count * 2) - 4 /* for rfc1001 length itself */; | ||
| 2511 | pSMB->ParameterOffset = cpu_to_le32(temp_offset); | ||
| 2512 | pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len); | ||
| 2513 | pSMB->SetupCount = setup_count; /* no need to le convert byte fields */ | ||
| 2514 | pSMB->SubCommand = cpu_to_le16(sub_command); | ||
| 2515 | return 0; | ||
| 2516 | } | ||
| 2517 | |||
| 2518 | static int | ||
| 2519 | validate_ntransact(char *buf, char **ppparm, char **ppdata, | ||
| 2520 | __u32 *pparmlen, __u32 *pdatalen) | ||
| 2521 | { | ||
| 2522 | char *end_of_smb; | ||
| 2523 | __u32 data_count, data_offset, parm_count, parm_offset; | ||
| 2524 | struct smb_com_ntransact_rsp *pSMBr; | ||
| 2525 | |||
| 2526 | *pdatalen = 0; | ||
| 2527 | *pparmlen = 0; | ||
| 2528 | |||
| 2529 | if (buf == NULL) | ||
| 2530 | return -EINVAL; | ||
| 2531 | |||
| 2532 | pSMBr = (struct smb_com_ntransact_rsp *)buf; | ||
| 2533 | |||
| 2534 | /* ByteCount was converted from little endian in SendReceive */ | ||
| 2535 | end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount + | ||
| 2536 | (char *)&pSMBr->ByteCount; | ||
| 2537 | |||
| 2538 | data_offset = le32_to_cpu(pSMBr->DataOffset); | ||
| 2539 | data_count = le32_to_cpu(pSMBr->DataCount); | ||
| 2540 | parm_offset = le32_to_cpu(pSMBr->ParameterOffset); | ||
| 2541 | parm_count = le32_to_cpu(pSMBr->ParameterCount); | ||
| 2542 | |||
| 2543 | *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset; | ||
| 2544 | *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset; | ||
| 2545 | |||
| 2546 | /* should we also check that parm and data areas do not overlap? */ | ||
| 2547 | if (*ppparm > end_of_smb) { | ||
| 2548 | cFYI(1, "parms start after end of smb"); | ||
| 2549 | return -EINVAL; | ||
| 2550 | } else if (parm_count + *ppparm > end_of_smb) { | ||
| 2551 | cFYI(1, "parm end after end of smb"); | ||
| 2552 | return -EINVAL; | ||
| 2553 | } else if (*ppdata > end_of_smb) { | ||
| 2554 | cFYI(1, "data starts after end of smb"); | ||
| 2555 | return -EINVAL; | ||
| 2556 | } else if (data_count + *ppdata > end_of_smb) { | ||
| 2557 | cFYI(1, "data %p + count %d (%p) past smb end %p start %p", | ||
| 2558 | *ppdata, data_count, (data_count + *ppdata), | ||
| 2559 | end_of_smb, pSMBr); | ||
| 2560 | return -EINVAL; | ||
| 2561 | } else if (parm_count + data_count > pSMBr->ByteCount) { | ||
| 2562 | cFYI(1, "parm count and data count larger than SMB"); | ||
| 2563 | return -EINVAL; | ||
| 2564 | } | ||
| 2565 | *pdatalen = data_count; | ||
| 2566 | *pparmlen = parm_count; | ||
| 2567 | return 0; | ||
| 2568 | } | ||
| 2569 | |||
| 2570 | int | 2481 | int |
| 2571 | CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, | 2482 | CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, |
| 2572 | const unsigned char *searchName, | 2483 | const unsigned char *searchName, |
| @@ -3056,7 +2967,97 @@ GetExtAttrOut: | |||
| 3056 | 2967 | ||
| 3057 | #endif /* CONFIG_POSIX */ | 2968 | #endif /* CONFIG_POSIX */ |
| 3058 | 2969 | ||
| 3059 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 2970 | #ifdef CONFIG_CIFS_ACL |
| 2971 | /* | ||
| 2972 | * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that | ||
| 2973 | * all NT TRANSACTS that we init here have total parm and data under about 400 | ||
| 2974 | * bytes (to fit in small cifs buffer size), which is the case so far, it | ||
| 2975 | * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of | ||
| 2976 | * returned setup area) and MaxParameterCount (returned parms size) must be set | ||
| 2977 | * by caller | ||
| 2978 | */ | ||
| 2979 | static int | ||
| 2980 | smb_init_nttransact(const __u16 sub_command, const int setup_count, | ||
| 2981 | const int parm_len, struct cifsTconInfo *tcon, | ||
| 2982 | void **ret_buf) | ||
| 2983 | { | ||
| 2984 | int rc; | ||
| 2985 | __u32 temp_offset; | ||
| 2986 | struct smb_com_ntransact_req *pSMB; | ||
| 2987 | |||
| 2988 | rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, | ||
| 2989 | (void **)&pSMB); | ||
| 2990 | if (rc) | ||
| 2991 | return rc; | ||
| 2992 | *ret_buf = (void *)pSMB; | ||
| 2993 | pSMB->Reserved = 0; | ||
| 2994 | pSMB->TotalParameterCount = cpu_to_le32(parm_len); | ||
| 2995 | pSMB->TotalDataCount = 0; | ||
| 2996 | pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf - | ||
| 2997 | MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); | ||
| 2998 | pSMB->ParameterCount = pSMB->TotalParameterCount; | ||
| 2999 | pSMB->DataCount = pSMB->TotalDataCount; | ||
| 3000 | temp_offset = offsetof(struct smb_com_ntransact_req, Parms) + | ||
| 3001 | (setup_count * 2) - 4 /* for rfc1001 length itself */; | ||
| 3002 | pSMB->ParameterOffset = cpu_to_le32(temp_offset); | ||
| 3003 | pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len); | ||
| 3004 | pSMB->SetupCount = setup_count; /* no need to le convert byte fields */ | ||
| 3005 | pSMB->SubCommand = cpu_to_le16(sub_command); | ||
| 3006 | return 0; | ||
| 3007 | } | ||
| 3008 | |||
| 3009 | static int | ||
| 3010 | validate_ntransact(char *buf, char **ppparm, char **ppdata, | ||
| 3011 | __u32 *pparmlen, __u32 *pdatalen) | ||
| 3012 | { | ||
| 3013 | char *end_of_smb; | ||
| 3014 | __u32 data_count, data_offset, parm_count, parm_offset; | ||
| 3015 | struct smb_com_ntransact_rsp *pSMBr; | ||
| 3016 | |||
| 3017 | *pdatalen = 0; | ||
| 3018 | *pparmlen = 0; | ||
| 3019 | |||
| 3020 | if (buf == NULL) | ||
| 3021 | return -EINVAL; | ||
| 3022 | |||
| 3023 | pSMBr = (struct smb_com_ntransact_rsp *)buf; | ||
| 3024 | |||
| 3025 | /* ByteCount was converted from little endian in SendReceive */ | ||
| 3026 | end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount + | ||
| 3027 | (char *)&pSMBr->ByteCount; | ||
| 3028 | |||
| 3029 | data_offset = le32_to_cpu(pSMBr->DataOffset); | ||
| 3030 | data_count = le32_to_cpu(pSMBr->DataCount); | ||
| 3031 | parm_offset = le32_to_cpu(pSMBr->ParameterOffset); | ||
| 3032 | parm_count = le32_to_cpu(pSMBr->ParameterCount); | ||
| 3033 | |||
| 3034 | *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset; | ||
| 3035 | *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset; | ||
| 3036 | |||
| 3037 | /* should we also check that parm and data areas do not overlap? */ | ||
| 3038 | if (*ppparm > end_of_smb) { | ||
| 3039 | cFYI(1, "parms start after end of smb"); | ||
| 3040 | return -EINVAL; | ||
| 3041 | } else if (parm_count + *ppparm > end_of_smb) { | ||
| 3042 | cFYI(1, "parm end after end of smb"); | ||
| 3043 | return -EINVAL; | ||
| 3044 | } else if (*ppdata > end_of_smb) { | ||
| 3045 | cFYI(1, "data starts after end of smb"); | ||
| 3046 | return -EINVAL; | ||
| 3047 | } else if (data_count + *ppdata > end_of_smb) { | ||
| 3048 | cFYI(1, "data %p + count %d (%p) past smb end %p start %p", | ||
| 3049 | *ppdata, data_count, (data_count + *ppdata), | ||
| 3050 | end_of_smb, pSMBr); | ||
| 3051 | return -EINVAL; | ||
| 3052 | } else if (parm_count + data_count > pSMBr->ByteCount) { | ||
| 3053 | cFYI(1, "parm count and data count larger than SMB"); | ||
| 3054 | return -EINVAL; | ||
| 3055 | } | ||
| 3056 | *pdatalen = data_count; | ||
| 3057 | *pparmlen = parm_count; | ||
| 3058 | return 0; | ||
| 3059 | } | ||
| 3060 | |||
| 3060 | /* Get Security Descriptor (by handle) from remote server for a file or dir */ | 3061 | /* Get Security Descriptor (by handle) from remote server for a file or dir */ |
| 3061 | int | 3062 | int |
| 3062 | CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | 3063 | CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, |
| @@ -3214,7 +3215,7 @@ setCifsAclRetry: | |||
| 3214 | return (rc); | 3215 | return (rc); |
| 3215 | } | 3216 | } |
| 3216 | 3217 | ||
| 3217 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 3218 | #endif /* CONFIG_CIFS_ACL */ |
| 3218 | 3219 | ||
| 3219 | /* Legacy Query Path Information call for lookup to old servers such | 3220 | /* Legacy Query Path Information call for lookup to old servers such |
| 3220 | as Win9x/WinME */ | 3221 | as Win9x/WinME */ |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 32fa4d9b5db..cc1a8604a79 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -105,6 +105,7 @@ struct smb_vol { | |||
| 105 | unsigned int wsize; | 105 | unsigned int wsize; |
| 106 | bool sockopt_tcp_nodelay:1; | 106 | bool sockopt_tcp_nodelay:1; |
| 107 | unsigned short int port; | 107 | unsigned short int port; |
| 108 | unsigned long actimeo; /* attribute cache timeout (jiffies) */ | ||
| 108 | char *prepath; | 109 | char *prepath; |
| 109 | struct sockaddr_storage srcaddr; /* allow binding to a local IP */ | 110 | struct sockaddr_storage srcaddr; /* allow binding to a local IP */ |
| 110 | struct nls_table *local_nls; | 111 | struct nls_table *local_nls; |
| @@ -806,23 +807,20 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
| 806 | short int override_gid = -1; | 807 | short int override_gid = -1; |
| 807 | bool uid_specified = false; | 808 | bool uid_specified = false; |
| 808 | bool gid_specified = false; | 809 | bool gid_specified = false; |
| 810 | char *nodename = utsname()->nodename; | ||
| 809 | 811 | ||
| 810 | separator[0] = ','; | 812 | separator[0] = ','; |
| 811 | separator[1] = 0; | 813 | separator[1] = 0; |
| 812 | 814 | ||
| 813 | if (Local_System_Name[0] != 0) | 815 | /* |
| 814 | memcpy(vol->source_rfc1001_name, Local_System_Name, 15); | 816 | * does not have to be perfect mapping since field is |
| 815 | else { | 817 | * informational, only used for servers that do not support |
| 816 | char *nodename = utsname()->nodename; | 818 | * port 445 and it can be overridden at mount time |
| 817 | int n = strnlen(nodename, 15); | 819 | */ |
| 818 | memset(vol->source_rfc1001_name, 0x20, 15); | 820 | memset(vol->source_rfc1001_name, 0x20, 15); |
| 819 | for (i = 0; i < n; i++) { | 821 | for (i = 0; i < strnlen(nodename, 15); i++) |
| 820 | /* does not have to be perfect mapping since field is | 822 | vol->source_rfc1001_name[i] = toupper(nodename[i]); |
| 821 | informational, only used for servers that do not support | 823 | |
| 822 | port 445 and it can be overridden at mount time */ | ||
| 823 | vol->source_rfc1001_name[i] = toupper(nodename[i]); | ||
| 824 | } | ||
| 825 | } | ||
| 826 | vol->source_rfc1001_name[15] = 0; | 824 | vol->source_rfc1001_name[15] = 0; |
| 827 | /* null target name indicates to use *SMBSERVR default called name | 825 | /* null target name indicates to use *SMBSERVR default called name |
| 828 | if we end up sending RFC1001 session initialize */ | 826 | if we end up sending RFC1001 session initialize */ |
| @@ -840,6 +838,8 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
| 840 | /* default to using server inode numbers where available */ | 838 | /* default to using server inode numbers where available */ |
| 841 | vol->server_ino = 1; | 839 | vol->server_ino = 1; |
| 842 | 840 | ||
| 841 | vol->actimeo = CIFS_DEF_ACTIMEO; | ||
| 842 | |||
| 843 | if (!options) | 843 | if (!options) |
| 844 | return 1; | 844 | return 1; |
| 845 | 845 | ||
| @@ -1214,6 +1214,16 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
| 1214 | printk(KERN_WARNING "CIFS: server net" | 1214 | printk(KERN_WARNING "CIFS: server net" |
| 1215 | "biosname longer than 15 truncated.\n"); | 1215 | "biosname longer than 15 truncated.\n"); |
| 1216 | } | 1216 | } |
| 1217 | } else if (strnicmp(data, "actimeo", 7) == 0) { | ||
| 1218 | if (value && *value) { | ||
| 1219 | vol->actimeo = HZ * simple_strtoul(value, | ||
| 1220 | &value, 0); | ||
| 1221 | if (vol->actimeo > CIFS_MAX_ACTIMEO) { | ||
| 1222 | cERROR(1, "CIFS: attribute cache" | ||
| 1223 | "timeout too large"); | ||
| 1224 | return 1; | ||
| 1225 | } | ||
| 1226 | } | ||
| 1217 | } else if (strnicmp(data, "credentials", 4) == 0) { | 1227 | } else if (strnicmp(data, "credentials", 4) == 0) { |
| 1218 | /* ignore */ | 1228 | /* ignore */ |
| 1219 | } else if (strnicmp(data, "version", 3) == 0) { | 1229 | } else if (strnicmp(data, "version", 3) == 0) { |
| @@ -2571,6 +2581,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, | |||
| 2571 | cFYI(1, "file mode: 0x%x dir mode: 0x%x", | 2581 | cFYI(1, "file mode: 0x%x dir mode: 0x%x", |
| 2572 | cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode); | 2582 | cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode); |
| 2573 | 2583 | ||
| 2584 | cifs_sb->actimeo = pvolume_info->actimeo; | ||
| 2585 | |||
| 2574 | if (pvolume_info->noperm) | 2586 | if (pvolume_info->noperm) |
| 2575 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; | 2587 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; |
| 2576 | if (pvolume_info->setuids) | 2588 | if (pvolume_info->setuids) |
| @@ -2821,13 +2833,13 @@ remote_path_check: | |||
| 2821 | /* check if a whole path (including prepath) is not remote */ | 2833 | /* check if a whole path (including prepath) is not remote */ |
| 2822 | if (!rc && cifs_sb->prepathlen && tcon) { | 2834 | if (!rc && cifs_sb->prepathlen && tcon) { |
| 2823 | /* build_path_to_root works only when we have a valid tcon */ | 2835 | /* build_path_to_root works only when we have a valid tcon */ |
| 2824 | full_path = cifs_build_path_to_root(cifs_sb); | 2836 | full_path = cifs_build_path_to_root(cifs_sb, tcon); |
| 2825 | if (full_path == NULL) { | 2837 | if (full_path == NULL) { |
| 2826 | rc = -ENOMEM; | 2838 | rc = -ENOMEM; |
| 2827 | goto mount_fail_check; | 2839 | goto mount_fail_check; |
| 2828 | } | 2840 | } |
| 2829 | rc = is_path_accessible(xid, tcon, cifs_sb, full_path); | 2841 | rc = is_path_accessible(xid, tcon, cifs_sb, full_path); |
| 2830 | if (rc != -EREMOTE) { | 2842 | if (rc != 0 && rc != -EREMOTE) { |
| 2831 | kfree(full_path); | 2843 | kfree(full_path); |
| 2832 | goto mount_fail_check; | 2844 | goto mount_fail_check; |
| 2833 | } | 2845 | } |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index b857ce5db77..5a28660ca2b 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -1108,7 +1108,6 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file, | |||
| 1108 | return total_written; | 1108 | return total_written; |
| 1109 | } | 1109 | } |
| 1110 | 1110 | ||
| 1111 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
| 1112 | struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, | 1111 | struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, |
| 1113 | bool fsuid_only) | 1112 | bool fsuid_only) |
| 1114 | { | 1113 | { |
| @@ -1142,7 +1141,6 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, | |||
| 1142 | spin_unlock(&cifs_file_list_lock); | 1141 | spin_unlock(&cifs_file_list_lock); |
| 1143 | return NULL; | 1142 | return NULL; |
| 1144 | } | 1143 | } |
| 1145 | #endif | ||
| 1146 | 1144 | ||
| 1147 | struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, | 1145 | struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, |
| 1148 | bool fsuid_only) | 1146 | bool fsuid_only) |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 28cb6e73594..589f3e3f6e0 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -686,7 +686,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
| 686 | cFYI(1, "cifs_sfu_type failed: %d", tmprc); | 686 | cFYI(1, "cifs_sfu_type failed: %d", tmprc); |
| 687 | } | 687 | } |
| 688 | 688 | ||
| 689 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 689 | #ifdef CONFIG_CIFS_ACL |
| 690 | /* fill in 0777 bits from ACL */ | 690 | /* fill in 0777 bits from ACL */ |
| 691 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 691 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
| 692 | rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, | 692 | rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, |
| @@ -697,7 +697,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
| 697 | goto cgii_exit; | 697 | goto cgii_exit; |
| 698 | } | 698 | } |
| 699 | } | 699 | } |
| 700 | #endif | 700 | #endif /* CONFIG_CIFS_ACL */ |
| 701 | 701 | ||
| 702 | /* fill in remaining high mode bits e.g. SUID, VTX */ | 702 | /* fill in remaining high mode bits e.g. SUID, VTX */ |
| 703 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) | 703 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) |
| @@ -728,12 +728,12 @@ static const struct inode_operations cifs_ipc_inode_ops = { | |||
| 728 | .lookup = cifs_lookup, | 728 | .lookup = cifs_lookup, |
| 729 | }; | 729 | }; |
| 730 | 730 | ||
| 731 | char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) | 731 | char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb, |
| 732 | struct cifsTconInfo *tcon) | ||
| 732 | { | 733 | { |
| 733 | int pplen = cifs_sb->prepathlen; | 734 | int pplen = cifs_sb->prepathlen; |
| 734 | int dfsplen; | 735 | int dfsplen; |
| 735 | char *full_path = NULL; | 736 | char *full_path = NULL; |
| 736 | struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); | ||
| 737 | 737 | ||
| 738 | /* if no prefix path, simply set path to the root of share to "" */ | 738 | /* if no prefix path, simply set path to the root of share to "" */ |
| 739 | if (pplen == 0) { | 739 | if (pplen == 0) { |
| @@ -875,7 +875,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) | |||
| 875 | char *full_path; | 875 | char *full_path; |
| 876 | struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); | 876 | struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); |
| 877 | 877 | ||
| 878 | full_path = cifs_build_path_to_root(cifs_sb); | 878 | full_path = cifs_build_path_to_root(cifs_sb, tcon); |
| 879 | if (full_path == NULL) | 879 | if (full_path == NULL) |
| 880 | return ERR_PTR(-ENOMEM); | 880 | return ERR_PTR(-ENOMEM); |
| 881 | 881 | ||
| @@ -1653,6 +1653,7 @@ static bool | |||
| 1653 | cifs_inode_needs_reval(struct inode *inode) | 1653 | cifs_inode_needs_reval(struct inode *inode) |
| 1654 | { | 1654 | { |
| 1655 | struct cifsInodeInfo *cifs_i = CIFS_I(inode); | 1655 | struct cifsInodeInfo *cifs_i = CIFS_I(inode); |
| 1656 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
| 1656 | 1657 | ||
| 1657 | if (cifs_i->clientCanCacheRead) | 1658 | if (cifs_i->clientCanCacheRead) |
| 1658 | return false; | 1659 | return false; |
| @@ -1663,12 +1664,12 @@ cifs_inode_needs_reval(struct inode *inode) | |||
| 1663 | if (cifs_i->time == 0) | 1664 | if (cifs_i->time == 0) |
| 1664 | return true; | 1665 | return true; |
| 1665 | 1666 | ||
| 1666 | /* FIXME: the actimeo should be tunable */ | 1667 | if (!time_in_range(jiffies, cifs_i->time, |
| 1667 | if (time_after_eq(jiffies, cifs_i->time + HZ)) | 1668 | cifs_i->time + cifs_sb->actimeo)) |
| 1668 | return true; | 1669 | return true; |
| 1669 | 1670 | ||
| 1670 | /* hardlinked files w/ noserverino get "special" treatment */ | 1671 | /* hardlinked files w/ noserverino get "special" treatment */ |
| 1671 | if (!(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && | 1672 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && |
| 1672 | S_ISREG(inode->i_mode) && inode->i_nlink != 1) | 1673 | S_ISREG(inode->i_mode) && inode->i_nlink != 1) |
| 1673 | return true; | 1674 | return true; |
| 1674 | 1675 | ||
| @@ -2121,7 +2122,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
| 2121 | 2122 | ||
| 2122 | if (attrs->ia_valid & ATTR_MODE) { | 2123 | if (attrs->ia_valid & ATTR_MODE) { |
| 2123 | rc = 0; | 2124 | rc = 0; |
| 2124 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 2125 | #ifdef CONFIG_CIFS_ACL |
| 2125 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 2126 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
| 2126 | rc = mode_to_cifs_acl(inode, full_path, mode); | 2127 | rc = mode_to_cifs_acl(inode, full_path, mode); |
| 2127 | if (rc) { | 2128 | if (rc) { |
| @@ -2130,7 +2131,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
| 2130 | goto cifs_setattr_exit; | 2131 | goto cifs_setattr_exit; |
| 2131 | } | 2132 | } |
| 2132 | } else | 2133 | } else |
| 2133 | #endif | 2134 | #endif /* CONFIG_CIFS_ACL */ |
| 2134 | if (((mode & S_IWUGO) == 0) && | 2135 | if (((mode & S_IWUGO) == 0) && |
| 2135 | (cifsInode->cifsAttrs & ATTR_READONLY) == 0) { | 2136 | (cifsInode->cifsAttrs & ATTR_READONLY) == 0) { |
| 2136 | 2137 | ||
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 32d300e8f20..a73eb9f4bda 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
| @@ -759,18 +759,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir, | |||
| 759 | rc = filldir(direntry, qstring.name, qstring.len, file->f_pos, | 759 | rc = filldir(direntry, qstring.name, qstring.len, file->f_pos, |
| 760 | ino, fattr.cf_dtype); | 760 | ino, fattr.cf_dtype); |
| 761 | 761 | ||
| 762 | /* | ||
| 763 | * we can not return filldir errors to the caller since they are | ||
| 764 | * "normal" when the stat blocksize is too small - we return remapped | ||
| 765 | * error instead | ||
| 766 | * | ||
| 767 | * FIXME: This looks bogus. filldir returns -EOVERFLOW in the above | ||
| 768 | * case already. Why should we be clobbering other errors from it? | ||
| 769 | */ | ||
| 770 | if (rc) { | ||
| 771 | cFYI(1, "filldir rc = %d", rc); | ||
| 772 | rc = -EOVERFLOW; | ||
| 773 | } | ||
| 774 | dput(tmp_dentry); | 762 | dput(tmp_dentry); |
| 775 | return rc; | 763 | return rc; |
| 776 | } | 764 | } |
| @@ -275,6 +275,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm) | |||
| 275 | vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP; | 275 | vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP; |
| 276 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); | 276 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
| 277 | INIT_LIST_HEAD(&vma->anon_vma_chain); | 277 | INIT_LIST_HEAD(&vma->anon_vma_chain); |
| 278 | |||
| 279 | err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1); | ||
| 280 | if (err) | ||
| 281 | goto err; | ||
| 282 | |||
| 278 | err = insert_vm_struct(mm, vma); | 283 | err = insert_vm_struct(mm, vma); |
| 279 | if (err) | 284 | if (err) |
| 280 | goto err; | 285 | goto err; |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 6a5edea2d70..94ce3d7a1c4 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
| @@ -910,6 +910,7 @@ struct ext4_inode_info { | |||
| 910 | #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ | 910 | #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ |
| 911 | #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ | 911 | #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ |
| 912 | #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ | 912 | #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ |
| 913 | #define EXT4_MOUNT_MBLK_IO_SUBMIT 0x4000000 /* multi-block io submits */ | ||
| 913 | #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ | 914 | #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ |
| 914 | #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ | 915 | #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ |
| 915 | #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ | 916 | #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index bdbe6990220..e659597b690 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -2125,9 +2125,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, | |||
| 2125 | */ | 2125 | */ |
| 2126 | if (unlikely(journal_data && PageChecked(page))) | 2126 | if (unlikely(journal_data && PageChecked(page))) |
| 2127 | err = __ext4_journalled_writepage(page, len); | 2127 | err = __ext4_journalled_writepage(page, len); |
| 2128 | else | 2128 | else if (test_opt(inode->i_sb, MBLK_IO_SUBMIT)) |
| 2129 | err = ext4_bio_write_page(&io_submit, page, | 2129 | err = ext4_bio_write_page(&io_submit, page, |
| 2130 | len, mpd->wbc); | 2130 | len, mpd->wbc); |
| 2131 | else | ||
| 2132 | err = block_write_full_page(page, | ||
| 2133 | noalloc_get_block_write, mpd->wbc); | ||
| 2131 | 2134 | ||
| 2132 | if (!err) | 2135 | if (!err) |
| 2133 | mpd->pages_written++; | 2136 | mpd->pages_written++; |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 92203b8a099..dc40e75cba8 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
| @@ -872,7 +872,7 @@ static struct buffer_head * ext4_find_entry (struct inode *dir, | |||
| 872 | if (namelen > EXT4_NAME_LEN) | 872 | if (namelen > EXT4_NAME_LEN) |
| 873 | return NULL; | 873 | return NULL; |
| 874 | if ((namelen <= 2) && (name[0] == '.') && | 874 | if ((namelen <= 2) && (name[0] == '.') && |
| 875 | (name[1] == '.' || name[1] == '0')) { | 875 | (name[1] == '.' || name[1] == '\0')) { |
| 876 | /* | 876 | /* |
| 877 | * "." or ".." will only be in the first block | 877 | * "." or ".." will only be in the first block |
| 878 | * NFS may look up ".."; "." should be handled by the VFS | 878 | * NFS may look up ".."; "." should be handled by the VFS |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index e32195d6aac..fb15c9c0be7 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -1026,6 +1026,8 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 1026 | !(def_mount_opts & EXT4_DEFM_NODELALLOC)) | 1026 | !(def_mount_opts & EXT4_DEFM_NODELALLOC)) |
| 1027 | seq_puts(seq, ",nodelalloc"); | 1027 | seq_puts(seq, ",nodelalloc"); |
| 1028 | 1028 | ||
| 1029 | if (test_opt(sb, MBLK_IO_SUBMIT)) | ||
| 1030 | seq_puts(seq, ",mblk_io_submit"); | ||
| 1029 | if (sbi->s_stripe) | 1031 | if (sbi->s_stripe) |
| 1030 | seq_printf(seq, ",stripe=%lu", sbi->s_stripe); | 1032 | seq_printf(seq, ",stripe=%lu", sbi->s_stripe); |
| 1031 | /* | 1033 | /* |
| @@ -1239,8 +1241,8 @@ enum { | |||
| 1239 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, | 1241 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, |
| 1240 | Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, | 1242 | Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, |
| 1241 | Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version, | 1243 | Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version, |
| 1242 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, | 1244 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit, |
| 1243 | Opt_block_validity, Opt_noblock_validity, | 1245 | Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity, |
| 1244 | Opt_inode_readahead_blks, Opt_journal_ioprio, | 1246 | Opt_inode_readahead_blks, Opt_journal_ioprio, |
| 1245 | Opt_dioread_nolock, Opt_dioread_lock, | 1247 | Opt_dioread_nolock, Opt_dioread_lock, |
| 1246 | Opt_discard, Opt_nodiscard, | 1248 | Opt_discard, Opt_nodiscard, |
| @@ -1304,6 +1306,8 @@ static const match_table_t tokens = { | |||
| 1304 | {Opt_resize, "resize"}, | 1306 | {Opt_resize, "resize"}, |
| 1305 | {Opt_delalloc, "delalloc"}, | 1307 | {Opt_delalloc, "delalloc"}, |
| 1306 | {Opt_nodelalloc, "nodelalloc"}, | 1308 | {Opt_nodelalloc, "nodelalloc"}, |
| 1309 | {Opt_mblk_io_submit, "mblk_io_submit"}, | ||
| 1310 | {Opt_nomblk_io_submit, "nomblk_io_submit"}, | ||
| 1307 | {Opt_block_validity, "block_validity"}, | 1311 | {Opt_block_validity, "block_validity"}, |
| 1308 | {Opt_noblock_validity, "noblock_validity"}, | 1312 | {Opt_noblock_validity, "noblock_validity"}, |
| 1309 | {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, | 1313 | {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, |
| @@ -1725,6 +1729,12 @@ set_qf_format: | |||
| 1725 | case Opt_nodelalloc: | 1729 | case Opt_nodelalloc: |
| 1726 | clear_opt(sbi->s_mount_opt, DELALLOC); | 1730 | clear_opt(sbi->s_mount_opt, DELALLOC); |
| 1727 | break; | 1731 | break; |
| 1732 | case Opt_mblk_io_submit: | ||
| 1733 | set_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT); | ||
| 1734 | break; | ||
| 1735 | case Opt_nomblk_io_submit: | ||
| 1736 | clear_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT); | ||
| 1737 | break; | ||
| 1728 | case Opt_stripe: | 1738 | case Opt_stripe: |
| 1729 | if (match_int(&args[0], &option)) | 1739 | if (match_int(&args[0], &option)) |
| 1730 | return 0; | 1740 | return 0; |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 9242d294fe9..8b984a2cebb 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/compat.h> | ||
| 16 | 17 | ||
| 17 | static const struct file_operations fuse_direct_io_file_operations; | 18 | static const struct file_operations fuse_direct_io_file_operations; |
| 18 | 19 | ||
| @@ -1628,6 +1629,58 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov, | |||
| 1628 | } | 1629 | } |
| 1629 | 1630 | ||
| 1630 | /* | 1631 | /* |
| 1632 | * CUSE servers compiled on 32bit broke on 64bit kernels because the | ||
| 1633 | * ABI was defined to be 'struct iovec' which is different on 32bit | ||
| 1634 | * and 64bit. Fortunately we can determine which structure the server | ||
| 1635 | * used from the size of the reply. | ||
| 1636 | */ | ||
| 1637 | static int fuse_copy_ioctl_iovec(struct iovec *dst, void *src, | ||
| 1638 | size_t transferred, unsigned count, | ||
| 1639 | bool is_compat) | ||
| 1640 | { | ||
| 1641 | #ifdef CONFIG_COMPAT | ||
| 1642 | if (count * sizeof(struct compat_iovec) == transferred) { | ||
| 1643 | struct compat_iovec *ciov = src; | ||
| 1644 | unsigned i; | ||
| 1645 | |||
| 1646 | /* | ||
| 1647 | * With this interface a 32bit server cannot support | ||
| 1648 | * non-compat (i.e. ones coming from 64bit apps) ioctl | ||
| 1649 | * requests | ||
| 1650 | */ | ||
| 1651 | if (!is_compat) | ||
| 1652 | return -EINVAL; | ||
| 1653 | |||
| 1654 | for (i = 0; i < count; i++) { | ||
| 1655 | dst[i].iov_base = compat_ptr(ciov[i].iov_base); | ||
| 1656 | dst[i].iov_len = ciov[i].iov_len; | ||
| 1657 | } | ||
| 1658 | return 0; | ||
| 1659 | } | ||
| 1660 | #endif | ||
| 1661 | |||
| 1662 | if (count * sizeof(struct iovec) != transferred) | ||
| 1663 | return -EIO; | ||
| 1664 | |||
| 1665 | memcpy(dst, src, transferred); | ||
| 1666 | return 0; | ||
| 1667 | } | ||
| 1668 | |||
| 1669 | /* Make sure iov_length() won't overflow */ | ||
| 1670 | static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count) | ||
| 1671 | { | ||
| 1672 | size_t n; | ||
| 1673 | u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT; | ||
| 1674 | |||
| 1675 | for (n = 0; n < count; n++) { | ||
| 1676 | if (iov->iov_len > (size_t) max) | ||
| 1677 | return -ENOMEM; | ||
| 1678 | max -= iov->iov_len; | ||
| 1679 | } | ||
| 1680 | return 0; | ||
| 1681 | } | ||
| 1682 | |||
| 1683 | /* | ||
| 1631 | * For ioctls, there is no generic way to determine how much memory | 1684 | * For ioctls, there is no generic way to determine how much memory |
| 1632 | * needs to be read and/or written. Furthermore, ioctls are allowed | 1685 | * needs to be read and/or written. Furthermore, ioctls are allowed |
| 1633 | * to dereference the passed pointer, so the parameter requires deep | 1686 | * to dereference the passed pointer, so the parameter requires deep |
| @@ -1808,18 +1861,25 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, | |||
| 1808 | in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV) | 1861 | in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV) |
| 1809 | goto out; | 1862 | goto out; |
| 1810 | 1863 | ||
| 1811 | err = -EIO; | ||
| 1812 | if ((in_iovs + out_iovs) * sizeof(struct iovec) != transferred) | ||
| 1813 | goto out; | ||
| 1814 | |||
| 1815 | /* okay, copy in iovs and retry */ | ||
| 1816 | vaddr = kmap_atomic(pages[0], KM_USER0); | 1864 | vaddr = kmap_atomic(pages[0], KM_USER0); |
| 1817 | memcpy(page_address(iov_page), vaddr, transferred); | 1865 | err = fuse_copy_ioctl_iovec(page_address(iov_page), vaddr, |
| 1866 | transferred, in_iovs + out_iovs, | ||
| 1867 | (flags & FUSE_IOCTL_COMPAT) != 0); | ||
| 1818 | kunmap_atomic(vaddr, KM_USER0); | 1868 | kunmap_atomic(vaddr, KM_USER0); |
| 1869 | if (err) | ||
| 1870 | goto out; | ||
| 1819 | 1871 | ||
| 1820 | in_iov = page_address(iov_page); | 1872 | in_iov = page_address(iov_page); |
| 1821 | out_iov = in_iov + in_iovs; | 1873 | out_iov = in_iov + in_iovs; |
| 1822 | 1874 | ||
| 1875 | err = fuse_verify_ioctl_iov(in_iov, in_iovs); | ||
| 1876 | if (err) | ||
| 1877 | goto out; | ||
| 1878 | |||
| 1879 | err = fuse_verify_ioctl_iov(out_iov, out_iovs); | ||
| 1880 | if (err) | ||
| 1881 | goto out; | ||
| 1882 | |||
| 1823 | goto retry; | 1883 | goto retry; |
| 1824 | } | 1884 | } |
| 1825 | 1885 | ||
diff --git a/fs/namei.c b/fs/namei.c index 5362af9b737..4ff7ca53053 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -1748,6 +1748,9 @@ struct file *do_filp_open(int dfd, const char *pathname, | |||
| 1748 | if (!(open_flag & O_CREAT)) | 1748 | if (!(open_flag & O_CREAT)) |
| 1749 | mode = 0; | 1749 | mode = 0; |
| 1750 | 1750 | ||
| 1751 | /* Must never be set by userspace */ | ||
| 1752 | open_flag &= ~FMODE_NONOTIFY; | ||
| 1753 | |||
| 1751 | /* | 1754 | /* |
| 1752 | * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only | 1755 | * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only |
| 1753 | * check for O_DSYNC if the need any syncing at all we enforce it's | 1756 | * check for O_DSYNC if the need any syncing at all we enforce it's |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index f0a384e2ae6..996dd8989a9 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -57,7 +57,7 @@ static int nfs_rename(struct inode *, struct dentry *, | |||
| 57 | struct inode *, struct dentry *); | 57 | struct inode *, struct dentry *); |
| 58 | static int nfs_fsync_dir(struct file *, int); | 58 | static int nfs_fsync_dir(struct file *, int); |
| 59 | static loff_t nfs_llseek_dir(struct file *, loff_t, int); | 59 | static loff_t nfs_llseek_dir(struct file *, loff_t, int); |
| 60 | static int nfs_readdir_clear_array(struct page*, gfp_t); | 60 | static void nfs_readdir_clear_array(struct page*); |
| 61 | 61 | ||
| 62 | const struct file_operations nfs_dir_operations = { | 62 | const struct file_operations nfs_dir_operations = { |
| 63 | .llseek = nfs_llseek_dir, | 63 | .llseek = nfs_llseek_dir, |
| @@ -83,8 +83,8 @@ const struct inode_operations nfs_dir_inode_operations = { | |||
| 83 | .setattr = nfs_setattr, | 83 | .setattr = nfs_setattr, |
| 84 | }; | 84 | }; |
| 85 | 85 | ||
| 86 | const struct address_space_operations nfs_dir_addr_space_ops = { | 86 | const struct address_space_operations nfs_dir_aops = { |
| 87 | .releasepage = nfs_readdir_clear_array, | 87 | .freepage = nfs_readdir_clear_array, |
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | #ifdef CONFIG_NFS_V3 | 90 | #ifdef CONFIG_NFS_V3 |
| @@ -178,6 +178,7 @@ typedef struct { | |||
| 178 | struct page *page; | 178 | struct page *page; |
| 179 | unsigned long page_index; | 179 | unsigned long page_index; |
| 180 | u64 *dir_cookie; | 180 | u64 *dir_cookie; |
| 181 | u64 last_cookie; | ||
| 181 | loff_t current_index; | 182 | loff_t current_index; |
| 182 | decode_dirent_t decode; | 183 | decode_dirent_t decode; |
| 183 | 184 | ||
| @@ -213,17 +214,15 @@ void nfs_readdir_release_array(struct page *page) | |||
| 213 | * we are freeing strings created by nfs_add_to_readdir_array() | 214 | * we are freeing strings created by nfs_add_to_readdir_array() |
| 214 | */ | 215 | */ |
| 215 | static | 216 | static |
| 216 | int nfs_readdir_clear_array(struct page *page, gfp_t mask) | 217 | void nfs_readdir_clear_array(struct page *page) |
| 217 | { | 218 | { |
| 218 | struct nfs_cache_array *array = nfs_readdir_get_array(page); | 219 | struct nfs_cache_array *array; |
| 219 | int i; | 220 | int i; |
| 220 | 221 | ||
| 221 | if (IS_ERR(array)) | 222 | array = kmap_atomic(page, KM_USER0); |
| 222 | return PTR_ERR(array); | ||
| 223 | for (i = 0; i < array->size; i++) | 223 | for (i = 0; i < array->size; i++) |
| 224 | kfree(array->array[i].string.name); | 224 | kfree(array->array[i].string.name); |
| 225 | nfs_readdir_release_array(page); | 225 | kunmap_atomic(array, KM_USER0); |
| 226 | return 0; | ||
| 227 | } | 226 | } |
| 228 | 227 | ||
| 229 | /* | 228 | /* |
| @@ -272,7 +271,7 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page) | |||
| 272 | goto out; | 271 | goto out; |
| 273 | array->last_cookie = entry->cookie; | 272 | array->last_cookie = entry->cookie; |
| 274 | array->size++; | 273 | array->size++; |
| 275 | if (entry->eof == 1) | 274 | if (entry->eof != 0) |
| 276 | array->eof_index = array->size; | 275 | array->eof_index = array->size; |
| 277 | out: | 276 | out: |
| 278 | nfs_readdir_release_array(page); | 277 | nfs_readdir_release_array(page); |
| @@ -312,15 +311,14 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des | |||
| 312 | for (i = 0; i < array->size; i++) { | 311 | for (i = 0; i < array->size; i++) { |
| 313 | if (array->array[i].cookie == *desc->dir_cookie) { | 312 | if (array->array[i].cookie == *desc->dir_cookie) { |
| 314 | desc->cache_entry_index = i; | 313 | desc->cache_entry_index = i; |
| 315 | status = 0; | 314 | return 0; |
| 316 | goto out; | ||
| 317 | } | 315 | } |
| 318 | } | 316 | } |
| 319 | if (i == array->eof_index) { | 317 | if (array->eof_index >= 0) { |
| 320 | desc->eof = 1; | ||
| 321 | status = -EBADCOOKIE; | 318 | status = -EBADCOOKIE; |
| 319 | if (*desc->dir_cookie == array->last_cookie) | ||
| 320 | desc->eof = 1; | ||
| 322 | } | 321 | } |
| 323 | out: | ||
| 324 | return status; | 322 | return status; |
| 325 | } | 323 | } |
| 326 | 324 | ||
| @@ -328,10 +326,7 @@ static | |||
| 328 | int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc) | 326 | int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc) |
| 329 | { | 327 | { |
| 330 | struct nfs_cache_array *array; | 328 | struct nfs_cache_array *array; |
| 331 | int status = -EBADCOOKIE; | 329 | int status; |
| 332 | |||
| 333 | if (desc->dir_cookie == NULL) | ||
| 334 | goto out; | ||
| 335 | 330 | ||
| 336 | array = nfs_readdir_get_array(desc->page); | 331 | array = nfs_readdir_get_array(desc->page); |
| 337 | if (IS_ERR(array)) { | 332 | if (IS_ERR(array)) { |
| @@ -344,6 +339,10 @@ int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc) | |||
| 344 | else | 339 | else |
| 345 | status = nfs_readdir_search_for_cookie(array, desc); | 340 | status = nfs_readdir_search_for_cookie(array, desc); |
| 346 | 341 | ||
| 342 | if (status == -EAGAIN) { | ||
| 343 | desc->last_cookie = array->last_cookie; | ||
| 344 | desc->page_index++; | ||
| 345 | } | ||
| 347 | nfs_readdir_release_array(desc->page); | 346 | nfs_readdir_release_array(desc->page); |
| 348 | out: | 347 | out: |
| 349 | return status; | 348 | return status; |
| @@ -490,7 +489,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en | |||
| 490 | 489 | ||
| 491 | count++; | 490 | count++; |
| 492 | 491 | ||
| 493 | if (desc->plus == 1) | 492 | if (desc->plus != 0) |
| 494 | nfs_prime_dcache(desc->file->f_path.dentry, entry); | 493 | nfs_prime_dcache(desc->file->f_path.dentry, entry); |
| 495 | 494 | ||
| 496 | status = nfs_readdir_add_to_array(entry, page); | 495 | status = nfs_readdir_add_to_array(entry, page); |
| @@ -498,7 +497,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en | |||
| 498 | break; | 497 | break; |
| 499 | } while (!entry->eof); | 498 | } while (!entry->eof); |
| 500 | 499 | ||
| 501 | if (count == 0 || (status == -EBADCOOKIE && entry->eof == 1)) { | 500 | if (count == 0 || (status == -EBADCOOKIE && entry->eof != 0)) { |
| 502 | array = nfs_readdir_get_array(page); | 501 | array = nfs_readdir_get_array(page); |
| 503 | if (!IS_ERR(array)) { | 502 | if (!IS_ERR(array)) { |
| 504 | array->eof_index = array->size; | 503 | array->eof_index = array->size; |
| @@ -563,7 +562,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, | |||
| 563 | unsigned int array_size = ARRAY_SIZE(pages); | 562 | unsigned int array_size = ARRAY_SIZE(pages); |
| 564 | 563 | ||
| 565 | entry.prev_cookie = 0; | 564 | entry.prev_cookie = 0; |
| 566 | entry.cookie = *desc->dir_cookie; | 565 | entry.cookie = desc->last_cookie; |
| 567 | entry.eof = 0; | 566 | entry.eof = 0; |
| 568 | entry.fh = nfs_alloc_fhandle(); | 567 | entry.fh = nfs_alloc_fhandle(); |
| 569 | entry.fattr = nfs_alloc_fattr(); | 568 | entry.fattr = nfs_alloc_fattr(); |
| @@ -636,6 +635,8 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page) | |||
| 636 | static | 635 | static |
| 637 | void cache_page_release(nfs_readdir_descriptor_t *desc) | 636 | void cache_page_release(nfs_readdir_descriptor_t *desc) |
| 638 | { | 637 | { |
| 638 | if (!desc->page->mapping) | ||
| 639 | nfs_readdir_clear_array(desc->page); | ||
| 639 | page_cache_release(desc->page); | 640 | page_cache_release(desc->page); |
| 640 | desc->page = NULL; | 641 | desc->page = NULL; |
| 641 | } | 642 | } |
| @@ -660,9 +661,8 @@ int find_cache_page(nfs_readdir_descriptor_t *desc) | |||
| 660 | return PTR_ERR(desc->page); | 661 | return PTR_ERR(desc->page); |
| 661 | 662 | ||
| 662 | res = nfs_readdir_search_array(desc); | 663 | res = nfs_readdir_search_array(desc); |
| 663 | if (res == 0) | 664 | if (res != 0) |
| 664 | return 0; | 665 | cache_page_release(desc); |
| 665 | cache_page_release(desc); | ||
| 666 | return res; | 666 | return res; |
| 667 | } | 667 | } |
| 668 | 668 | ||
| @@ -672,22 +672,16 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc) | |||
| 672 | { | 672 | { |
| 673 | int res; | 673 | int res; |
| 674 | 674 | ||
| 675 | if (desc->page_index == 0) | 675 | if (desc->page_index == 0) { |
| 676 | desc->current_index = 0; | 676 | desc->current_index = 0; |
| 677 | while (1) { | 677 | desc->last_cookie = 0; |
| 678 | res = find_cache_page(desc); | ||
| 679 | if (res != -EAGAIN) | ||
| 680 | break; | ||
| 681 | desc->page_index++; | ||
| 682 | } | 678 | } |
| 679 | do { | ||
| 680 | res = find_cache_page(desc); | ||
| 681 | } while (res == -EAGAIN); | ||
| 683 | return res; | 682 | return res; |
| 684 | } | 683 | } |
| 685 | 684 | ||
| 686 | static inline unsigned int dt_type(struct inode *inode) | ||
| 687 | { | ||
| 688 | return (inode->i_mode >> 12) & 15; | ||
| 689 | } | ||
| 690 | |||
| 691 | /* | 685 | /* |
| 692 | * Once we've found the start of the dirent within a page: fill 'er up... | 686 | * Once we've found the start of the dirent within a page: fill 'er up... |
| 693 | */ | 687 | */ |
| @@ -717,13 +711,12 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
| 717 | break; | 711 | break; |
| 718 | } | 712 | } |
| 719 | file->f_pos++; | 713 | file->f_pos++; |
| 720 | desc->cache_entry_index = i; | ||
| 721 | if (i < (array->size-1)) | 714 | if (i < (array->size-1)) |
| 722 | *desc->dir_cookie = array->array[i+1].cookie; | 715 | *desc->dir_cookie = array->array[i+1].cookie; |
| 723 | else | 716 | else |
| 724 | *desc->dir_cookie = array->last_cookie; | 717 | *desc->dir_cookie = array->last_cookie; |
| 725 | } | 718 | } |
| 726 | if (i == array->eof_index) | 719 | if (array->eof_index >= 0) |
| 727 | desc->eof = 1; | 720 | desc->eof = 1; |
| 728 | 721 | ||
| 729 | nfs_readdir_release_array(desc->page); | 722 | nfs_readdir_release_array(desc->page); |
| @@ -764,6 +757,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
| 764 | } | 757 | } |
| 765 | 758 | ||
| 766 | desc->page_index = 0; | 759 | desc->page_index = 0; |
| 760 | desc->last_cookie = *desc->dir_cookie; | ||
| 767 | desc->page = page; | 761 | desc->page = page; |
| 768 | 762 | ||
| 769 | status = nfs_readdir_xdr_to_array(desc, page, inode); | 763 | status = nfs_readdir_xdr_to_array(desc, page, inode); |
| @@ -791,7 +785,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 791 | struct inode *inode = dentry->d_inode; | 785 | struct inode *inode = dentry->d_inode; |
| 792 | nfs_readdir_descriptor_t my_desc, | 786 | nfs_readdir_descriptor_t my_desc, |
| 793 | *desc = &my_desc; | 787 | *desc = &my_desc; |
| 794 | int res = -ENOMEM; | 788 | int res; |
| 795 | 789 | ||
| 796 | dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n", | 790 | dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n", |
| 797 | dentry->d_parent->d_name.name, dentry->d_name.name, | 791 | dentry->d_parent->d_name.name, dentry->d_name.name, |
| @@ -816,7 +810,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 816 | if (res < 0) | 810 | if (res < 0) |
| 817 | goto out; | 811 | goto out; |
| 818 | 812 | ||
| 819 | while (desc->eof != 1) { | 813 | do { |
| 820 | res = readdir_search_pagecache(desc); | 814 | res = readdir_search_pagecache(desc); |
| 821 | 815 | ||
| 822 | if (res == -EBADCOOKIE) { | 816 | if (res == -EBADCOOKIE) { |
| @@ -844,7 +838,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 844 | res = nfs_do_filldir(desc, dirent, filldir); | 838 | res = nfs_do_filldir(desc, dirent, filldir); |
| 845 | if (res < 0) | 839 | if (res < 0) |
| 846 | break; | 840 | break; |
| 847 | } | 841 | } while (!desc->eof); |
| 848 | out: | 842 | out: |
| 849 | nfs_unblock_sillyrename(dentry); | 843 | nfs_unblock_sillyrename(dentry); |
| 850 | if (res > 0) | 844 | if (res > 0) |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 60677f9f131..7bf029ef408 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
| @@ -693,6 +693,7 @@ do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) | |||
| 693 | { | 693 | { |
| 694 | struct inode *inode = filp->f_mapping->host; | 694 | struct inode *inode = filp->f_mapping->host; |
| 695 | int status = 0; | 695 | int status = 0; |
| 696 | unsigned int saved_type = fl->fl_type; | ||
| 696 | 697 | ||
| 697 | /* Try local locking first */ | 698 | /* Try local locking first */ |
| 698 | posix_test_lock(filp, fl); | 699 | posix_test_lock(filp, fl); |
| @@ -700,6 +701,7 @@ do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) | |||
| 700 | /* found a conflict */ | 701 | /* found a conflict */ |
| 701 | goto out; | 702 | goto out; |
| 702 | } | 703 | } |
| 704 | fl->fl_type = saved_type; | ||
| 703 | 705 | ||
| 704 | if (nfs_have_delegation(inode, FMODE_READ)) | 706 | if (nfs_have_delegation(inode, FMODE_READ)) |
| 705 | goto out_noconflict; | 707 | goto out_noconflict; |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 314f5716460..e67e31c7341 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
| @@ -289,6 +289,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
| 289 | } else if (S_ISDIR(inode->i_mode)) { | 289 | } else if (S_ISDIR(inode->i_mode)) { |
| 290 | inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops; | 290 | inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops; |
| 291 | inode->i_fop = &nfs_dir_operations; | 291 | inode->i_fop = &nfs_dir_operations; |
| 292 | inode->i_data.a_ops = &nfs_dir_aops; | ||
| 292 | if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS)) | 293 | if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS)) |
| 293 | set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags); | 294 | set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags); |
| 294 | /* Deal with crossing mountpoints */ | 295 | /* Deal with crossing mountpoints */ |
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index eceafe74f47..4f981f1f668 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c | |||
| @@ -505,13 +505,13 @@ static struct rpc_procinfo mnt3_procedures[] = { | |||
| 505 | 505 | ||
| 506 | static struct rpc_version mnt_version1 = { | 506 | static struct rpc_version mnt_version1 = { |
| 507 | .number = 1, | 507 | .number = 1, |
| 508 | .nrprocs = 2, | 508 | .nrprocs = ARRAY_SIZE(mnt_procedures), |
| 509 | .procs = mnt_procedures, | 509 | .procs = mnt_procedures, |
| 510 | }; | 510 | }; |
| 511 | 511 | ||
| 512 | static struct rpc_version mnt_version3 = { | 512 | static struct rpc_version mnt_version3 = { |
| 513 | .number = 3, | 513 | .number = 3, |
| 514 | .nrprocs = 2, | 514 | .nrprocs = ARRAY_SIZE(mnt3_procedures), |
| 515 | .procs = mnt3_procedures, | 515 | .procs = mnt3_procedures, |
| 516 | }; | 516 | }; |
| 517 | 517 | ||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 6a653ffd8e4..4435e5e1f90 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -3361,6 +3361,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen) | |||
| 3361 | ret = nfs_revalidate_inode(server, inode); | 3361 | ret = nfs_revalidate_inode(server, inode); |
| 3362 | if (ret < 0) | 3362 | if (ret < 0) |
| 3363 | return ret; | 3363 | return ret; |
| 3364 | if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL) | ||
| 3365 | nfs_zap_acl_cache(inode); | ||
| 3364 | ret = nfs4_read_cached_acl(inode, buf, buflen); | 3366 | ret = nfs4_read_cached_acl(inode, buf, buflen); |
| 3365 | if (ret != -ENOENT) | 3367 | if (ret != -ENOENT) |
| 3366 | return ret; | 3368 | return ret; |
| @@ -3389,6 +3391,13 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl | |||
| 3389 | nfs_inode_return_delegation(inode); | 3391 | nfs_inode_return_delegation(inode); |
| 3390 | buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); | 3392 | buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); |
| 3391 | ret = nfs4_call_sync(server, &msg, &arg, &res, 1); | 3393 | ret = nfs4_call_sync(server, &msg, &arg, &res, 1); |
| 3394 | /* | ||
| 3395 | * Acl update can result in inode attribute update. | ||
| 3396 | * so mark the attribute cache invalid. | ||
| 3397 | */ | ||
| 3398 | spin_lock(&inode->i_lock); | ||
| 3399 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR; | ||
| 3400 | spin_unlock(&inode->i_lock); | ||
| 3392 | nfs_access_zap_cache(inode); | 3401 | nfs_access_zap_cache(inode); |
| 3393 | nfs_zap_acl_cache(inode); | 3402 | nfs_zap_acl_cache(inode); |
| 3394 | return ret; | 3403 | return ret; |
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 137b549e63d..b68536cc904 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
| @@ -115,7 +115,7 @@ int nfs_set_page_tag_locked(struct nfs_page *req) | |||
| 115 | { | 115 | { |
| 116 | if (!nfs_lock_request_dontget(req)) | 116 | if (!nfs_lock_request_dontget(req)) |
| 117 | return 0; | 117 | return 0; |
| 118 | if (req->wb_page != NULL) | 118 | if (test_bit(PG_MAPPED, &req->wb_flags)) |
| 119 | radix_tree_tag_set(&NFS_I(req->wb_context->path.dentry->d_inode)->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); | 119 | radix_tree_tag_set(&NFS_I(req->wb_context->path.dentry->d_inode)->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); |
| 120 | return 1; | 120 | return 1; |
| 121 | } | 121 | } |
| @@ -125,7 +125,7 @@ int nfs_set_page_tag_locked(struct nfs_page *req) | |||
| 125 | */ | 125 | */ |
| 126 | void nfs_clear_page_tag_locked(struct nfs_page *req) | 126 | void nfs_clear_page_tag_locked(struct nfs_page *req) |
| 127 | { | 127 | { |
| 128 | if (req->wb_page != NULL) { | 128 | if (test_bit(PG_MAPPED, &req->wb_flags)) { |
| 129 | struct inode *inode = req->wb_context->path.dentry->d_inode; | 129 | struct inode *inode = req->wb_context->path.dentry->d_inode; |
| 130 | struct nfs_inode *nfsi = NFS_I(inode); | 130 | struct nfs_inode *nfsi = NFS_I(inode); |
| 131 | 131 | ||
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index e4b62c6f5a6..aedcaa7f291 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
| @@ -152,7 +152,6 @@ static void nfs_readpage_release(struct nfs_page *req) | |||
| 152 | (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), | 152 | (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), |
| 153 | req->wb_bytes, | 153 | req->wb_bytes, |
| 154 | (long long)req_offset(req)); | 154 | (long long)req_offset(req)); |
| 155 | nfs_clear_request(req); | ||
| 156 | nfs_release_request(req); | 155 | nfs_release_request(req); |
| 157 | } | 156 | } |
| 158 | 157 | ||
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 3c045044fca..4100630c9a5 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
| @@ -1069,12 +1069,10 @@ static int nfs_parse_mount_options(char *raw, | |||
| 1069 | mnt->flags |= NFS_MOUNT_VER3; | 1069 | mnt->flags |= NFS_MOUNT_VER3; |
| 1070 | mnt->version = 3; | 1070 | mnt->version = 3; |
| 1071 | break; | 1071 | break; |
| 1072 | #ifdef CONFIG_NFS_V4 | ||
| 1073 | case Opt_v4: | 1072 | case Opt_v4: |
| 1074 | mnt->flags &= ~NFS_MOUNT_VER3; | 1073 | mnt->flags &= ~NFS_MOUNT_VER3; |
| 1075 | mnt->version = 4; | 1074 | mnt->version = 4; |
| 1076 | break; | 1075 | break; |
| 1077 | #endif | ||
| 1078 | case Opt_udp: | 1076 | case Opt_udp: |
| 1079 | mnt->flags &= ~NFS_MOUNT_TCP; | 1077 | mnt->flags &= ~NFS_MOUNT_TCP; |
| 1080 | mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; | 1078 | mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; |
| @@ -1286,12 +1284,10 @@ static int nfs_parse_mount_options(char *raw, | |||
| 1286 | mnt->flags |= NFS_MOUNT_VER3; | 1284 | mnt->flags |= NFS_MOUNT_VER3; |
| 1287 | mnt->version = 3; | 1285 | mnt->version = 3; |
| 1288 | break; | 1286 | break; |
| 1289 | #ifdef CONFIG_NFS_V4 | ||
| 1290 | case NFS4_VERSION: | 1287 | case NFS4_VERSION: |
| 1291 | mnt->flags &= ~NFS_MOUNT_VER3; | 1288 | mnt->flags &= ~NFS_MOUNT_VER3; |
| 1292 | mnt->version = 4; | 1289 | mnt->version = 4; |
| 1293 | break; | 1290 | break; |
| 1294 | #endif | ||
| 1295 | default: | 1291 | default: |
| 1296 | goto out_invalid_value; | 1292 | goto out_invalid_value; |
| 1297 | } | 1293 | } |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 4c14c17a527..10d648ea128 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
| @@ -390,6 +390,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) | |||
| 390 | if (nfs_have_delegation(inode, FMODE_WRITE)) | 390 | if (nfs_have_delegation(inode, FMODE_WRITE)) |
| 391 | nfsi->change_attr++; | 391 | nfsi->change_attr++; |
| 392 | } | 392 | } |
| 393 | set_bit(PG_MAPPED, &req->wb_flags); | ||
| 393 | SetPagePrivate(req->wb_page); | 394 | SetPagePrivate(req->wb_page); |
| 394 | set_page_private(req->wb_page, (unsigned long)req); | 395 | set_page_private(req->wb_page, (unsigned long)req); |
| 395 | nfsi->npages++; | 396 | nfsi->npages++; |
| @@ -415,6 +416,7 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
| 415 | spin_lock(&inode->i_lock); | 416 | spin_lock(&inode->i_lock); |
| 416 | set_page_private(req->wb_page, 0); | 417 | set_page_private(req->wb_page, 0); |
| 417 | ClearPagePrivate(req->wb_page); | 418 | ClearPagePrivate(req->wb_page); |
| 419 | clear_bit(PG_MAPPED, &req->wb_flags); | ||
| 418 | radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); | 420 | radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); |
| 419 | nfsi->npages--; | 421 | nfsi->npages--; |
| 420 | if (!nfsi->npages) { | 422 | if (!nfsi->npages) { |
| @@ -422,7 +424,6 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
| 422 | iput(inode); | 424 | iput(inode); |
| 423 | } else | 425 | } else |
| 424 | spin_unlock(&inode->i_lock); | 426 | spin_unlock(&inode->i_lock); |
| 425 | nfs_clear_request(req); | ||
| 426 | nfs_release_request(req); | 427 | nfs_release_request(req); |
| 427 | } | 428 | } |
| 428 | 429 | ||
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 2a533a0af2a..7e84a852cda 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
| @@ -260,9 +260,11 @@ void fill_post_wcc(struct svc_fh *fhp) | |||
| 260 | err = vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry, | 260 | err = vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry, |
| 261 | &fhp->fh_post_attr); | 261 | &fhp->fh_post_attr); |
| 262 | fhp->fh_post_change = fhp->fh_dentry->d_inode->i_version; | 262 | fhp->fh_post_change = fhp->fh_dentry->d_inode->i_version; |
| 263 | if (err) | 263 | if (err) { |
| 264 | fhp->fh_post_saved = 0; | 264 | fhp->fh_post_saved = 0; |
| 265 | else | 265 | /* Grab the ctime anyway - set_change_info might use it */ |
| 266 | fhp->fh_post_attr.ctime = fhp->fh_dentry->d_inode->i_ctime; | ||
| 267 | } else | ||
| 266 | fhp->fh_post_saved = 1; | 268 | fhp->fh_post_saved = 1; |
| 267 | } | 269 | } |
| 268 | 270 | ||
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 4d476ff08ae..60fce3dc5cb 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h | |||
| @@ -484,18 +484,17 @@ static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp) | |||
| 484 | static inline void | 484 | static inline void |
| 485 | set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) | 485 | set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) |
| 486 | { | 486 | { |
| 487 | BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved); | 487 | BUG_ON(!fhp->fh_pre_saved); |
| 488 | cinfo->atomic = 1; | 488 | cinfo->atomic = fhp->fh_post_saved; |
| 489 | cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode); | 489 | cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode); |
| 490 | if (cinfo->change_supported) { | 490 | |
| 491 | cinfo->before_change = fhp->fh_pre_change; | 491 | cinfo->before_change = fhp->fh_pre_change; |
| 492 | cinfo->after_change = fhp->fh_post_change; | 492 | cinfo->after_change = fhp->fh_post_change; |
| 493 | } else { | 493 | cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec; |
| 494 | cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec; | 494 | cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec; |
| 495 | cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec; | 495 | cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec; |
| 496 | cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec; | 496 | cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec; |
| 497 | cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec; | 497 | |
| 498 | } | ||
| 499 | } | 498 | } |
| 500 | 499 | ||
| 501 | int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); | 500 | int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); |
diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c index 33ad25ddd5c..caf9a6a3fb5 100644 --- a/fs/nilfs2/gcinode.c +++ b/fs/nilfs2/gcinode.c | |||
| @@ -176,7 +176,6 @@ int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *bh) | |||
| 176 | int nilfs_init_gcinode(struct inode *inode) | 176 | int nilfs_init_gcinode(struct inode *inode) |
| 177 | { | 177 | { |
| 178 | struct nilfs_inode_info *ii = NILFS_I(inode); | 178 | struct nilfs_inode_info *ii = NILFS_I(inode); |
| 179 | struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs; | ||
| 180 | 179 | ||
| 181 | inode->i_mode = S_IFREG; | 180 | inode->i_mode = S_IFREG; |
| 182 | mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); | 181 | mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); |
| @@ -186,14 +185,6 @@ int nilfs_init_gcinode(struct inode *inode) | |||
| 186 | ii->i_flags = 0; | 185 | ii->i_flags = 0; |
| 187 | nilfs_bmap_init_gc(ii->i_bmap); | 186 | nilfs_bmap_init_gc(ii->i_bmap); |
| 188 | 187 | ||
| 189 | /* | ||
| 190 | * Add the inode to GC inode list. Garbage Collection | ||
| 191 | * is serialized and no two processes manipulate the | ||
| 192 | * list simultaneously. | ||
| 193 | */ | ||
| 194 | igrab(inode); | ||
| 195 | list_add(&NILFS_I(inode)->i_dirty, &nilfs->ns_gc_inodes); | ||
| 196 | |||
| 197 | return 0; | 188 | return 0; |
| 198 | } | 189 | } |
| 199 | 190 | ||
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index e00d9457c25..b185e937a33 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c | |||
| @@ -337,6 +337,7 @@ static int nilfs_ioctl_move_blocks(struct super_block *sb, | |||
| 337 | struct nilfs_argv *argv, void *buf) | 337 | struct nilfs_argv *argv, void *buf) |
| 338 | { | 338 | { |
| 339 | size_t nmembs = argv->v_nmembs; | 339 | size_t nmembs = argv->v_nmembs; |
| 340 | struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs; | ||
| 340 | struct inode *inode; | 341 | struct inode *inode; |
| 341 | struct nilfs_vdesc *vdesc; | 342 | struct nilfs_vdesc *vdesc; |
| 342 | struct buffer_head *bh, *n; | 343 | struct buffer_head *bh, *n; |
| @@ -353,6 +354,17 @@ static int nilfs_ioctl_move_blocks(struct super_block *sb, | |||
| 353 | ret = PTR_ERR(inode); | 354 | ret = PTR_ERR(inode); |
| 354 | goto failed; | 355 | goto failed; |
| 355 | } | 356 | } |
| 357 | if (list_empty(&NILFS_I(inode)->i_dirty)) { | ||
| 358 | /* | ||
| 359 | * Add the inode to GC inode list. Garbage Collection | ||
| 360 | * is serialized and no two processes manipulate the | ||
| 361 | * list simultaneously. | ||
| 362 | */ | ||
| 363 | igrab(inode); | ||
| 364 | list_add(&NILFS_I(inode)->i_dirty, | ||
| 365 | &nilfs->ns_gc_inodes); | ||
| 366 | } | ||
| 367 | |||
| 356 | do { | 368 | do { |
| 357 | ret = nilfs_ioctl_move_inode_block(inode, vdesc, | 369 | ret = nilfs_ioctl_move_inode_block(inode, vdesc, |
| 358 | &buffers); | 370 | &buffers); |
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index b04f88eed09..f35794b97e8 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
| @@ -92,7 +92,11 @@ static int fanotify_get_response_from_access(struct fsnotify_group *group, | |||
| 92 | 92 | ||
| 93 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); | 93 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); |
| 94 | 94 | ||
| 95 | wait_event(group->fanotify_data.access_waitq, event->response); | 95 | wait_event(group->fanotify_data.access_waitq, event->response || |
| 96 | atomic_read(&group->fanotify_data.bypass_perm)); | ||
| 97 | |||
| 98 | if (!event->response) /* bypass_perm set */ | ||
| 99 | return 0; | ||
| 96 | 100 | ||
| 97 | /* userspace responded, convert to something usable */ | 101 | /* userspace responded, convert to something usable */ |
| 98 | spin_lock(&event->lock); | 102 | spin_lock(&event->lock); |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 063224812b7..8b61220cffc 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
| @@ -106,20 +106,29 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event) | |||
| 106 | return client_fd; | 106 | return client_fd; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | static ssize_t fill_event_metadata(struct fsnotify_group *group, | 109 | static int fill_event_metadata(struct fsnotify_group *group, |
| 110 | struct fanotify_event_metadata *metadata, | 110 | struct fanotify_event_metadata *metadata, |
| 111 | struct fsnotify_event *event) | 111 | struct fsnotify_event *event) |
| 112 | { | 112 | { |
| 113 | int ret = 0; | ||
| 114 | |||
| 113 | pr_debug("%s: group=%p metadata=%p event=%p\n", __func__, | 115 | pr_debug("%s: group=%p metadata=%p event=%p\n", __func__, |
| 114 | group, metadata, event); | 116 | group, metadata, event); |
| 115 | 117 | ||
| 116 | metadata->event_len = FAN_EVENT_METADATA_LEN; | 118 | metadata->event_len = FAN_EVENT_METADATA_LEN; |
| 119 | metadata->metadata_len = FAN_EVENT_METADATA_LEN; | ||
| 117 | metadata->vers = FANOTIFY_METADATA_VERSION; | 120 | metadata->vers = FANOTIFY_METADATA_VERSION; |
| 118 | metadata->mask = event->mask & FAN_ALL_OUTGOING_EVENTS; | 121 | metadata->mask = event->mask & FAN_ALL_OUTGOING_EVENTS; |
| 119 | metadata->pid = pid_vnr(event->tgid); | 122 | metadata->pid = pid_vnr(event->tgid); |
| 120 | metadata->fd = create_fd(group, event); | 123 | if (unlikely(event->mask & FAN_Q_OVERFLOW)) |
| 124 | metadata->fd = FAN_NOFD; | ||
| 125 | else { | ||
| 126 | metadata->fd = create_fd(group, event); | ||
| 127 | if (metadata->fd < 0) | ||
| 128 | ret = metadata->fd; | ||
| 129 | } | ||
| 121 | 130 | ||
| 122 | return metadata->fd; | 131 | return ret; |
| 123 | } | 132 | } |
| 124 | 133 | ||
| 125 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | 134 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS |
| @@ -200,7 +209,7 @@ static int prepare_for_access_response(struct fsnotify_group *group, | |||
| 200 | 209 | ||
| 201 | mutex_lock(&group->fanotify_data.access_mutex); | 210 | mutex_lock(&group->fanotify_data.access_mutex); |
| 202 | 211 | ||
| 203 | if (group->fanotify_data.bypass_perm) { | 212 | if (atomic_read(&group->fanotify_data.bypass_perm)) { |
| 204 | mutex_unlock(&group->fanotify_data.access_mutex); | 213 | mutex_unlock(&group->fanotify_data.access_mutex); |
| 205 | kmem_cache_free(fanotify_response_event_cache, re); | 214 | kmem_cache_free(fanotify_response_event_cache, re); |
| 206 | event->response = FAN_ALLOW; | 215 | event->response = FAN_ALLOW; |
| @@ -257,24 +266,34 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, | |||
| 257 | 266 | ||
| 258 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); | 267 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); |
| 259 | 268 | ||
| 260 | fd = fill_event_metadata(group, &fanotify_event_metadata, event); | 269 | ret = fill_event_metadata(group, &fanotify_event_metadata, event); |
| 261 | if (fd < 0) | 270 | if (ret < 0) |
| 262 | return fd; | 271 | goto out; |
| 263 | 272 | ||
| 273 | fd = fanotify_event_metadata.fd; | ||
| 264 | ret = prepare_for_access_response(group, event, fd); | 274 | ret = prepare_for_access_response(group, event, fd); |
| 265 | if (ret) | 275 | if (ret) |
| 266 | goto out_close_fd; | 276 | goto out_close_fd; |
| 267 | 277 | ||
| 268 | ret = -EFAULT; | 278 | ret = -EFAULT; |
| 269 | if (copy_to_user(buf, &fanotify_event_metadata, FAN_EVENT_METADATA_LEN)) | 279 | if (copy_to_user(buf, &fanotify_event_metadata, |
| 280 | fanotify_event_metadata.event_len)) | ||
| 270 | goto out_kill_access_response; | 281 | goto out_kill_access_response; |
| 271 | 282 | ||
| 272 | return FAN_EVENT_METADATA_LEN; | 283 | return fanotify_event_metadata.event_len; |
| 273 | 284 | ||
| 274 | out_kill_access_response: | 285 | out_kill_access_response: |
| 275 | remove_access_response(group, event, fd); | 286 | remove_access_response(group, event, fd); |
| 276 | out_close_fd: | 287 | out_close_fd: |
| 277 | sys_close(fd); | 288 | if (fd != FAN_NOFD) |
| 289 | sys_close(fd); | ||
| 290 | out: | ||
| 291 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | ||
| 292 | if (event->mask & FAN_ALL_PERM_EVENTS) { | ||
| 293 | event->response = FAN_DENY; | ||
| 294 | wake_up(&group->fanotify_data.access_waitq); | ||
| 295 | } | ||
| 296 | #endif | ||
| 278 | return ret; | 297 | return ret; |
| 279 | } | 298 | } |
| 280 | 299 | ||
| @@ -382,7 +401,7 @@ static int fanotify_release(struct inode *ignored, struct file *file) | |||
| 382 | 401 | ||
| 383 | mutex_lock(&group->fanotify_data.access_mutex); | 402 | mutex_lock(&group->fanotify_data.access_mutex); |
| 384 | 403 | ||
| 385 | group->fanotify_data.bypass_perm = true; | 404 | atomic_inc(&group->fanotify_data.bypass_perm); |
| 386 | 405 | ||
| 387 | list_for_each_entry_safe(re, lre, &group->fanotify_data.access_list, list) { | 406 | list_for_each_entry_safe(re, lre, &group->fanotify_data.access_list, list) { |
| 388 | pr_debug("%s: found group=%p re=%p event=%p\n", __func__, group, | 407 | pr_debug("%s: found group=%p re=%p event=%p\n", __func__, group, |
| @@ -586,11 +605,10 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group, | |||
| 586 | { | 605 | { |
| 587 | struct fsnotify_mark *fsn_mark; | 606 | struct fsnotify_mark *fsn_mark; |
| 588 | __u32 added; | 607 | __u32 added; |
| 608 | int ret = 0; | ||
| 589 | 609 | ||
| 590 | fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); | 610 | fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); |
| 591 | if (!fsn_mark) { | 611 | if (!fsn_mark) { |
| 592 | int ret; | ||
| 593 | |||
| 594 | if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) | 612 | if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) |
| 595 | return -ENOSPC; | 613 | return -ENOSPC; |
| 596 | 614 | ||
| @@ -600,17 +618,16 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group, | |||
| 600 | 618 | ||
| 601 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); | 619 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); |
| 602 | ret = fsnotify_add_mark(fsn_mark, group, NULL, mnt, 0); | 620 | ret = fsnotify_add_mark(fsn_mark, group, NULL, mnt, 0); |
| 603 | if (ret) { | 621 | if (ret) |
| 604 | fanotify_free_mark(fsn_mark); | 622 | goto err; |
| 605 | return ret; | ||
| 606 | } | ||
| 607 | } | 623 | } |
| 608 | added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); | 624 | added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); |
| 609 | fsnotify_put_mark(fsn_mark); | 625 | |
| 610 | if (added & ~mnt->mnt_fsnotify_mask) | 626 | if (added & ~mnt->mnt_fsnotify_mask) |
| 611 | fsnotify_recalc_vfsmount_mask(mnt); | 627 | fsnotify_recalc_vfsmount_mask(mnt); |
| 612 | 628 | err: | |
| 613 | return 0; | 629 | fsnotify_put_mark(fsn_mark); |
| 630 | return ret; | ||
| 614 | } | 631 | } |
| 615 | 632 | ||
| 616 | static int fanotify_add_inode_mark(struct fsnotify_group *group, | 633 | static int fanotify_add_inode_mark(struct fsnotify_group *group, |
| @@ -619,6 +636,7 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group, | |||
| 619 | { | 636 | { |
| 620 | struct fsnotify_mark *fsn_mark; | 637 | struct fsnotify_mark *fsn_mark; |
| 621 | __u32 added; | 638 | __u32 added; |
| 639 | int ret = 0; | ||
| 622 | 640 | ||
| 623 | pr_debug("%s: group=%p inode=%p\n", __func__, group, inode); | 641 | pr_debug("%s: group=%p inode=%p\n", __func__, group, inode); |
| 624 | 642 | ||
| @@ -634,8 +652,6 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group, | |||
| 634 | 652 | ||
| 635 | fsn_mark = fsnotify_find_inode_mark(group, inode); | 653 | fsn_mark = fsnotify_find_inode_mark(group, inode); |
| 636 | if (!fsn_mark) { | 654 | if (!fsn_mark) { |
| 637 | int ret; | ||
| 638 | |||
| 639 | if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) | 655 | if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) |
| 640 | return -ENOSPC; | 656 | return -ENOSPC; |
| 641 | 657 | ||
| @@ -645,16 +661,16 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group, | |||
| 645 | 661 | ||
| 646 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); | 662 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); |
| 647 | ret = fsnotify_add_mark(fsn_mark, group, inode, NULL, 0); | 663 | ret = fsnotify_add_mark(fsn_mark, group, inode, NULL, 0); |
| 648 | if (ret) { | 664 | if (ret) |
| 649 | fanotify_free_mark(fsn_mark); | 665 | goto err; |
| 650 | return ret; | ||
| 651 | } | ||
| 652 | } | 666 | } |
| 653 | added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); | 667 | added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); |
| 654 | fsnotify_put_mark(fsn_mark); | 668 | |
| 655 | if (added & ~inode->i_fsnotify_mask) | 669 | if (added & ~inode->i_fsnotify_mask) |
| 656 | fsnotify_recalc_inode_mask(inode); | 670 | fsnotify_recalc_inode_mask(inode); |
| 657 | return 0; | 671 | err: |
| 672 | fsnotify_put_mark(fsn_mark); | ||
| 673 | return ret; | ||
| 658 | } | 674 | } |
| 659 | 675 | ||
| 660 | /* fanotify syscalls */ | 676 | /* fanotify syscalls */ |
| @@ -687,8 +703,10 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
| 687 | 703 | ||
| 688 | /* fsnotify_alloc_group takes a ref. Dropped in fanotify_release */ | 704 | /* fsnotify_alloc_group takes a ref. Dropped in fanotify_release */ |
| 689 | group = fsnotify_alloc_group(&fanotify_fsnotify_ops); | 705 | group = fsnotify_alloc_group(&fanotify_fsnotify_ops); |
| 690 | if (IS_ERR(group)) | 706 | if (IS_ERR(group)) { |
| 707 | free_uid(user); | ||
| 691 | return PTR_ERR(group); | 708 | return PTR_ERR(group); |
| 709 | } | ||
| 692 | 710 | ||
| 693 | group->fanotify_data.user = user; | 711 | group->fanotify_data.user = user; |
| 694 | atomic_inc(&user->fanotify_listeners); | 712 | atomic_inc(&user->fanotify_listeners); |
| @@ -698,6 +716,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
| 698 | mutex_init(&group->fanotify_data.access_mutex); | 716 | mutex_init(&group->fanotify_data.access_mutex); |
| 699 | init_waitqueue_head(&group->fanotify_data.access_waitq); | 717 | init_waitqueue_head(&group->fanotify_data.access_waitq); |
| 700 | INIT_LIST_HEAD(&group->fanotify_data.access_list); | 718 | INIT_LIST_HEAD(&group->fanotify_data.access_list); |
| 719 | atomic_set(&group->fanotify_data.bypass_perm, 0); | ||
| 701 | #endif | 720 | #endif |
| 702 | switch (flags & FAN_ALL_CLASS_BITS) { | 721 | switch (flags & FAN_ALL_CLASS_BITS) { |
| 703 | case FAN_CLASS_NOTIF: | 722 | case FAN_CLASS_NOTIF: |
| @@ -764,8 +783,10 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags, | |||
| 764 | if (flags & ~FAN_ALL_MARK_FLAGS) | 783 | if (flags & ~FAN_ALL_MARK_FLAGS) |
| 765 | return -EINVAL; | 784 | return -EINVAL; |
| 766 | switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) { | 785 | switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) { |
| 767 | case FAN_MARK_ADD: | 786 | case FAN_MARK_ADD: /* fallthrough */ |
| 768 | case FAN_MARK_REMOVE: | 787 | case FAN_MARK_REMOVE: |
| 788 | if (!mask) | ||
| 789 | return -EINVAL; | ||
| 769 | case FAN_MARK_FLUSH: | 790 | case FAN_MARK_FLUSH: |
| 770 | break; | 791 | break; |
| 771 | default: | 792 | default: |
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 444c305a468..4cd5d5d78f9 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
| @@ -752,6 +752,7 @@ SYSCALL_DEFINE1(inotify_init1, int, flags) | |||
| 752 | if (ret >= 0) | 752 | if (ret >= 0) |
| 753 | return ret; | 753 | return ret; |
| 754 | 754 | ||
| 755 | fsnotify_put_group(group); | ||
| 755 | atomic_dec(&user->inotify_devs); | 756 | atomic_dec(&user->inotify_devs); |
| 756 | out_free_uid: | 757 | out_free_uid: |
| 757 | free_uid(user); | 758 | free_uid(user); |
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index d2af0a8381a..77a59891734 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c | |||
| @@ -297,6 +297,7 @@ xfs_rename( | |||
| 297 | * it and some incremental backup programs won't work without it. | 297 | * it and some incremental backup programs won't work without it. |
| 298 | */ | 298 | */ |
| 299 | xfs_trans_ichgtime(tp, src_ip, XFS_ICHGTIME_CHG); | 299 | xfs_trans_ichgtime(tp, src_ip, XFS_ICHGTIME_CHG); |
| 300 | xfs_trans_log_inode(tp, src_ip, XFS_ILOG_CORE); | ||
| 300 | 301 | ||
| 301 | /* | 302 | /* |
| 302 | * Adjust the link count on src_dp. This is necessary when | 303 | * Adjust the link count on src_dp. This is necessary when |
diff --git a/include/acpi/video.h b/include/acpi/video.h index 551793c9b6e..0e98e679d3a 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h | |||
| @@ -1,6 +1,10 @@ | |||
| 1 | #ifndef __ACPI_VIDEO_H | 1 | #ifndef __ACPI_VIDEO_H |
| 2 | #define __ACPI_VIDEO_H | 2 | #define __ACPI_VIDEO_H |
| 3 | 3 | ||
| 4 | #include <linux/errno.h> /* for ENODEV */ | ||
| 5 | |||
| 6 | struct acpi_device; | ||
| 7 | |||
| 4 | #define ACPI_VIDEO_DISPLAY_CRT 1 | 8 | #define ACPI_VIDEO_DISPLAY_CRT 1 |
| 5 | #define ACPI_VIDEO_DISPLAY_TV 2 | 9 | #define ACPI_VIDEO_DISPLAY_TV 2 |
| 6 | #define ACPI_VIDEO_DISPLAY_DVI 3 | 10 | #define ACPI_VIDEO_DISPLAY_DVI 3 |
| @@ -26,4 +30,3 @@ static inline int acpi_video_get_edid(struct acpi_device *device, int type, | |||
| 26 | #endif | 30 | #endif |
| 27 | 31 | ||
| 28 | #endif | 32 | #endif |
| 29 | |||
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 050a7bccb83..67c91b4418b 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
| @@ -219,7 +219,7 @@ static inline int acpi_video_display_switch_support(void) | |||
| 219 | 219 | ||
| 220 | extern int acpi_blacklisted(void); | 220 | extern int acpi_blacklisted(void); |
| 221 | extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d); | 221 | extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d); |
| 222 | extern int acpi_osi_setup(char *str); | 222 | extern void acpi_osi_setup(char *str); |
| 223 | 223 | ||
| 224 | #ifdef CONFIG_ACPI_NUMA | 224 | #ifdef CONFIG_ACPI_NUMA |
| 225 | int acpi_get_pxm(acpi_handle handle); | 225 | int acpi_get_pxm(acpi_handle handle); |
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index a8e4e832cdb..475f8c42c0e 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h | |||
| @@ -427,8 +427,10 @@ extern rwlock_t vcc_sklist_lock; | |||
| 427 | 427 | ||
| 428 | #define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb)) | 428 | #define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb)) |
| 429 | 429 | ||
| 430 | struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops, | 430 | struct atm_dev *atm_dev_register(const char *type, struct device *parent, |
| 431 | int number,unsigned long *flags); /* number == -1: pick first available */ | 431 | const struct atmdev_ops *ops, |
| 432 | int number, /* -1 == pick first available */ | ||
| 433 | unsigned long *flags); | ||
| 432 | struct atm_dev *atm_dev_lookup(int number); | 434 | struct atm_dev *atm_dev_lookup(int number); |
| 433 | void atm_dev_deregister(struct atm_dev *dev); | 435 | void atm_dev_deregister(struct atm_dev *dev); |
| 434 | 436 | ||
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h index 0f0121467fc..6c6133f76e1 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h | |||
| @@ -83,11 +83,13 @@ | |||
| 83 | FAN_ALL_PERM_EVENTS |\ | 83 | FAN_ALL_PERM_EVENTS |\ |
| 84 | FAN_Q_OVERFLOW) | 84 | FAN_Q_OVERFLOW) |
| 85 | 85 | ||
| 86 | #define FANOTIFY_METADATA_VERSION 2 | 86 | #define FANOTIFY_METADATA_VERSION 3 |
| 87 | 87 | ||
| 88 | struct fanotify_event_metadata { | 88 | struct fanotify_event_metadata { |
| 89 | __u32 event_len; | 89 | __u32 event_len; |
| 90 | __u32 vers; | 90 | __u8 vers; |
| 91 | __u8 reserved; | ||
| 92 | __u16 metadata_len; | ||
| 91 | __aligned_u64 mask; | 93 | __aligned_u64 mask; |
| 92 | __s32 fd; | 94 | __s32 fd; |
| 93 | __s32 pid; | 95 | __s32 pid; |
| @@ -96,11 +98,13 @@ struct fanotify_event_metadata { | |||
| 96 | struct fanotify_response { | 98 | struct fanotify_response { |
| 97 | __s32 fd; | 99 | __s32 fd; |
| 98 | __u32 response; | 100 | __u32 response; |
| 99 | } __attribute__ ((packed)); | 101 | }; |
| 100 | 102 | ||
| 101 | /* Legit userspace responses to a _PERM event */ | 103 | /* Legit userspace responses to a _PERM event */ |
| 102 | #define FAN_ALLOW 0x01 | 104 | #define FAN_ALLOW 0x01 |
| 103 | #define FAN_DENY 0x02 | 105 | #define FAN_DENY 0x02 |
| 106 | /* No fd set in event */ | ||
| 107 | #define FAN_NOFD -1 | ||
| 104 | 108 | ||
| 105 | /* Helper functions to deal with fanotify_event_metadata buffers */ | 109 | /* Helper functions to deal with fanotify_event_metadata buffers */ |
| 106 | #define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata)) | 110 | #define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata)) |
diff --git a/include/linux/fs.h b/include/linux/fs.h index c9e06cc70da..090f0eacde2 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -602,6 +602,7 @@ struct address_space_operations { | |||
| 602 | sector_t (*bmap)(struct address_space *, sector_t); | 602 | sector_t (*bmap)(struct address_space *, sector_t); |
| 603 | void (*invalidatepage) (struct page *, unsigned long); | 603 | void (*invalidatepage) (struct page *, unsigned long); |
| 604 | int (*releasepage) (struct page *, gfp_t); | 604 | int (*releasepage) (struct page *, gfp_t); |
| 605 | void (*freepage)(struct page *); | ||
| 605 | ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov, | 606 | ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov, |
| 606 | loff_t offset, unsigned long nr_segs); | 607 | loff_t offset, unsigned long nr_segs); |
| 607 | int (*get_xip_mem)(struct address_space *, pgoff_t, int, | 608 | int (*get_xip_mem)(struct address_space *, pgoff_t, int, |
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 5c185fa2708..b10bcdeaef7 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h | |||
| @@ -235,9 +235,6 @@ static inline void fsnotify_open(struct file *file) | |||
| 235 | if (S_ISDIR(inode->i_mode)) | 235 | if (S_ISDIR(inode->i_mode)) |
| 236 | mask |= FS_ISDIR; | 236 | mask |= FS_ISDIR; |
| 237 | 237 | ||
| 238 | /* FMODE_NONOTIFY must never be set from user */ | ||
| 239 | file->f_mode &= ~FMODE_NONOTIFY; | ||
| 240 | |||
| 241 | fsnotify_parent(path, NULL, mask); | 238 | fsnotify_parent(path, NULL, mask); |
| 242 | fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); | 239 | fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); |
| 243 | } | 240 | } |
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 0a68f924f06..7380763595d 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
| @@ -166,7 +166,7 @@ struct fsnotify_group { | |||
| 166 | struct mutex access_mutex; | 166 | struct mutex access_mutex; |
| 167 | struct list_head access_list; | 167 | struct list_head access_list; |
| 168 | wait_queue_head_t access_waitq; | 168 | wait_queue_head_t access_waitq; |
| 169 | bool bypass_perm; /* protected by access_mutex */ | 169 | atomic_t bypass_perm; |
| 170 | #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ | 170 | #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ |
| 171 | int f_flags; | 171 | int f_flags; |
| 172 | unsigned int max_marks; | 172 | unsigned int max_marks; |
diff --git a/include/linux/input.h b/include/linux/input.h index a8af21d42bc..9777668883b 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
| @@ -104,8 +104,10 @@ struct input_keymap_entry { | |||
| 104 | #define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) /* get repeat settings */ | 104 | #define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) /* get repeat settings */ |
| 105 | #define EVIOCSREP _IOW('E', 0x03, unsigned int[2]) /* set repeat settings */ | 105 | #define EVIOCSREP _IOW('E', 0x03, unsigned int[2]) /* set repeat settings */ |
| 106 | 106 | ||
| 107 | #define EVIOCGKEYCODE _IOR('E', 0x04, struct input_keymap_entry) /* get keycode */ | 107 | #define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2]) /* get keycode */ |
| 108 | #define EVIOCSKEYCODE _IOW('E', 0x04, struct input_keymap_entry) /* set keycode */ | 108 | #define EVIOCGKEYCODE_V2 _IOR('E', 0x04, struct input_keymap_entry) |
| 109 | #define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2]) /* set keycode */ | ||
| 110 | #define EVIOCSKEYCODE_V2 _IOW('E', 0x04, struct input_keymap_entry) | ||
| 109 | 111 | ||
| 110 | #define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */ | 112 | #define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */ |
| 111 | #define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */ | 113 | #define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */ |
diff --git a/include/linux/ioport.h b/include/linux/ioport.h index d377ea815d4..e9bb22cba76 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
| @@ -112,7 +112,6 @@ struct resource_list { | |||
| 112 | /* PC/ISA/whatever - the normal PC address spaces: IO and memory */ | 112 | /* PC/ISA/whatever - the normal PC address spaces: IO and memory */ |
| 113 | extern struct resource ioport_resource; | 113 | extern struct resource ioport_resource; |
| 114 | extern struct resource iomem_resource; | 114 | extern struct resource iomem_resource; |
| 115 | extern int resource_alloc_from_bottom; | ||
| 116 | 115 | ||
| 117 | extern struct resource *request_resource_conflict(struct resource *root, struct resource *new); | 116 | extern struct resource *request_resource_conflict(struct resource *root, struct resource *new); |
| 118 | extern int request_resource(struct resource *root, struct resource *new); | 117 | extern int request_resource(struct resource *root, struct resource *new); |
| @@ -124,6 +123,7 @@ extern void reserve_region_with_split(struct resource *root, | |||
| 124 | extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new); | 123 | extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new); |
| 125 | extern int insert_resource(struct resource *parent, struct resource *new); | 124 | extern int insert_resource(struct resource *parent, struct resource *new); |
| 126 | extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new); | 125 | extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new); |
| 126 | extern void arch_remove_reservations(struct resource *avail); | ||
| 127 | extern int allocate_resource(struct resource *root, struct resource *new, | 127 | extern int allocate_resource(struct resource *root, struct resource *new, |
| 128 | resource_size_t size, resource_size_t min, | 128 | resource_size_t size, resource_size_t min, |
| 129 | resource_size_t max, resource_size_t align, | 129 | resource_size_t max, resource_size_t align, |
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index 5c51f367c06..add8a1b8bcf 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h | |||
| @@ -29,7 +29,7 @@ struct wm8994_ldo_pdata { | |||
| 29 | #define WM8994_CONFIGURE_GPIO 0x8000 | 29 | #define WM8994_CONFIGURE_GPIO 0x8000 |
| 30 | 30 | ||
| 31 | #define WM8994_DRC_REGS 5 | 31 | #define WM8994_DRC_REGS 5 |
| 32 | #define WM8994_EQ_REGS 19 | 32 | #define WM8994_EQ_REGS 20 |
| 33 | 33 | ||
| 34 | /** | 34 | /** |
| 35 | * DRC configurations are specified with a label and a set of register | 35 | * DRC configurations are specified with a label and a set of register |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index c66fdb7d699..29d504d5d1c 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
| @@ -401,6 +401,7 @@ extern const struct inode_operations nfs3_file_inode_operations; | |||
| 401 | #endif /* CONFIG_NFS_V3 */ | 401 | #endif /* CONFIG_NFS_V3 */ |
| 402 | extern const struct file_operations nfs_file_operations; | 402 | extern const struct file_operations nfs_file_operations; |
| 403 | extern const struct address_space_operations nfs_file_aops; | 403 | extern const struct address_space_operations nfs_file_aops; |
| 404 | extern const struct address_space_operations nfs_dir_aops; | ||
| 404 | 405 | ||
| 405 | static inline struct nfs_open_context *nfs_file_open_context(struct file *filp) | 406 | static inline struct nfs_open_context *nfs_file_open_context(struct file *filp) |
| 406 | { | 407 | { |
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index f8b60e7f4c4..d55cee73f63 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | */ | 29 | */ |
| 30 | enum { | 30 | enum { |
| 31 | PG_BUSY = 0, | 31 | PG_BUSY = 0, |
| 32 | PG_MAPPED, | ||
| 32 | PG_CLEAN, | 33 | PG_CLEAN, |
| 33 | PG_NEED_COMMIT, | 34 | PG_NEED_COMMIT, |
| 34 | PG_NEED_RESCHED, | 35 | PG_NEED_RESCHED, |
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 3ec2358f869..d19f1cca7f7 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h | |||
| @@ -77,7 +77,8 @@ static inline void device_set_run_wake(struct device *dev, bool enable) | |||
| 77 | 77 | ||
| 78 | static inline bool pm_runtime_suspended(struct device *dev) | 78 | static inline bool pm_runtime_suspended(struct device *dev) |
| 79 | { | 79 | { |
| 80 | return dev->power.runtime_status == RPM_SUSPENDED; | 80 | return dev->power.runtime_status == RPM_SUSPENDED |
| 81 | && !dev->power.disable_depth; | ||
| 81 | } | 82 | } |
| 82 | 83 | ||
| 83 | static inline void pm_runtime_mark_last_busy(struct device *dev) | 84 | static inline void pm_runtime_mark_last_busy(struct device *dev) |
diff --git a/include/linux/snmp.h b/include/linux/snmp.h index ebb0c80ffd6..12b2b18e50c 100644 --- a/include/linux/snmp.h +++ b/include/linux/snmp.h | |||
| @@ -230,6 +230,7 @@ enum | |||
| 230 | LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */ | 230 | LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */ |
| 231 | LINUX_MIB_TCPDEFERACCEPTDROP, | 231 | LINUX_MIB_TCPDEFERACCEPTDROP, |
| 232 | LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */ | 232 | LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */ |
| 233 | LINUX_MIB_TCPTIMEWAITOVERFLOW, /* TCPTimeWaitOverflow */ | ||
| 233 | __LINUX_MIB_MAX | 234 | __LINUX_MIB_MAX |
| 234 | }; | 235 | }; |
| 235 | 236 | ||
diff --git a/include/linux/ssb/ssb_driver_gige.h b/include/linux/ssb/ssb_driver_gige.h index 942e3873690..eba52a10053 100644 --- a/include/linux/ssb/ssb_driver_gige.h +++ b/include/linux/ssb/ssb_driver_gige.h | |||
| @@ -96,16 +96,21 @@ static inline bool ssb_gige_must_flush_posted_writes(struct pci_dev *pdev) | |||
| 96 | return 0; | 96 | return 0; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | extern char * nvram_get(const char *name); | 99 | #ifdef CONFIG_BCM47XX |
| 100 | #include <asm/mach-bcm47xx/nvram.h> | ||
| 100 | /* Get the device MAC address */ | 101 | /* Get the device MAC address */ |
| 101 | static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) | 102 | static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) |
| 102 | { | 103 | { |
| 103 | #ifdef CONFIG_BCM47XX | 104 | char buf[20]; |
| 104 | char *res = nvram_get("et0macaddr"); | 105 | if (nvram_getenv("et0macaddr", buf, sizeof(buf)) < 0) |
| 105 | if (res) | 106 | return; |
| 106 | memcpy(macaddr, res, 6); | 107 | nvram_parse_macaddr(buf, macaddr); |
| 107 | #endif | ||
| 108 | } | 108 | } |
| 109 | #else | ||
| 110 | static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) | ||
| 111 | { | ||
| 112 | } | ||
| 113 | #endif | ||
| 109 | 114 | ||
| 110 | extern int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev, | 115 | extern int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev, |
| 111 | struct pci_dev *pdev); | 116 | struct pci_dev *pdev); |
diff --git a/include/linux/video_output.h b/include/linux/video_output.h index 2fb46bc9340..ed5cdeb3604 100644 --- a/include/linux/video_output.h +++ b/include/linux/video_output.h | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #ifndef _LINUX_VIDEO_OUTPUT_H | 23 | #ifndef _LINUX_VIDEO_OUTPUT_H |
| 24 | #define _LINUX_VIDEO_OUTPUT_H | 24 | #define _LINUX_VIDEO_OUTPUT_H |
| 25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
| 26 | #include <linux/err.h> | ||
| 26 | struct output_device; | 27 | struct output_device; |
| 27 | struct output_properties { | 28 | struct output_properties { |
| 28 | int (*set_state)(struct output_device *); | 29 | int (*set_state)(struct output_device *); |
| @@ -34,9 +35,23 @@ struct output_device { | |||
| 34 | struct device dev; | 35 | struct device dev; |
| 35 | }; | 36 | }; |
| 36 | #define to_output_device(obj) container_of(obj, struct output_device, dev) | 37 | #define to_output_device(obj) container_of(obj, struct output_device, dev) |
| 38 | #if defined(CONFIG_VIDEO_OUTPUT_CONTROL) || defined(CONFIG_VIDEO_OUTPUT_CONTROL_MODULE) | ||
| 37 | struct output_device *video_output_register(const char *name, | 39 | struct output_device *video_output_register(const char *name, |
| 38 | struct device *dev, | 40 | struct device *dev, |
| 39 | void *devdata, | 41 | void *devdata, |
| 40 | struct output_properties *op); | 42 | struct output_properties *op); |
| 41 | void video_output_unregister(struct output_device *dev); | 43 | void video_output_unregister(struct output_device *dev); |
| 44 | #else | ||
| 45 | static struct output_device *video_output_register(const char *name, | ||
| 46 | struct device *dev, | ||
| 47 | void *devdata, | ||
| 48 | struct output_properties *op) | ||
| 49 | { | ||
| 50 | return ERR_PTR(-ENODEV); | ||
| 51 | } | ||
| 52 | static void video_output_unregister(struct output_device *dev) | ||
| 53 | { | ||
| 54 | return; | ||
| 55 | } | ||
| 56 | #endif | ||
| 42 | #endif | 57 | #endif |
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index 6648036b728..b16f307d471 100644 --- a/include/media/v4l2-device.h +++ b/include/media/v4l2-device.h | |||
| @@ -51,6 +51,8 @@ struct v4l2_device { | |||
| 51 | unsigned int notification, void *arg); | 51 | unsigned int notification, void *arg); |
| 52 | /* The control handler. May be NULL. */ | 52 | /* The control handler. May be NULL. */ |
| 53 | struct v4l2_ctrl_handler *ctrl_handler; | 53 | struct v4l2_ctrl_handler *ctrl_handler; |
| 54 | /* BKL replacement mutex. Temporary solution only. */ | ||
| 55 | struct mutex ioctl_lock; | ||
| 54 | }; | 56 | }; |
| 55 | 57 | ||
| 56 | /* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev. | 58 | /* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev. |
diff --git a/include/net/sock.h b/include/net/sock.h index a6338d03985..659d968d95c 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
| @@ -1155,6 +1155,8 @@ extern void sk_common_release(struct sock *sk); | |||
| 1155 | /* Initialise core socket variables */ | 1155 | /* Initialise core socket variables */ |
| 1156 | extern void sock_init_data(struct socket *sock, struct sock *sk); | 1156 | extern void sock_init_data(struct socket *sock, struct sock *sk); |
| 1157 | 1157 | ||
| 1158 | extern void sk_filter_release_rcu(struct rcu_head *rcu); | ||
| 1159 | |||
| 1158 | /** | 1160 | /** |
| 1159 | * sk_filter_release - release a socket filter | 1161 | * sk_filter_release - release a socket filter |
| 1160 | * @fp: filter to remove | 1162 | * @fp: filter to remove |
| @@ -1165,7 +1167,7 @@ extern void sock_init_data(struct socket *sock, struct sock *sk); | |||
| 1165 | static inline void sk_filter_release(struct sk_filter *fp) | 1167 | static inline void sk_filter_release(struct sk_filter *fp) |
| 1166 | { | 1168 | { |
| 1167 | if (atomic_dec_and_test(&fp->refcnt)) | 1169 | if (atomic_dec_and_test(&fp->refcnt)) |
| 1168 | kfree(fp); | 1170 | call_rcu_bh(&fp->rcu, sk_filter_release_rcu); |
| 1169 | } | 1171 | } |
| 1170 | 1172 | ||
| 1171 | static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp) | 1173 | static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp) |
diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h index e8cbf431c8c..75271b9a8f6 100644 --- a/include/xen/interface/io/ring.h +++ b/include/xen/interface/io/ring.h | |||
| @@ -24,8 +24,15 @@ typedef unsigned int RING_IDX; | |||
| 24 | * A ring contains as many entries as will fit, rounded down to the nearest | 24 | * A ring contains as many entries as will fit, rounded down to the nearest |
| 25 | * power of two (so we can mask with (size-1) to loop around). | 25 | * power of two (so we can mask with (size-1) to loop around). |
| 26 | */ | 26 | */ |
| 27 | #define __RING_SIZE(_s, _sz) \ | 27 | #define __CONST_RING_SIZE(_s, _sz) \ |
| 28 | (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0]))) | 28 | (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \ |
| 29 | sizeof(((struct _s##_sring *)0)->ring[0]))) | ||
| 30 | |||
| 31 | /* | ||
| 32 | * The same for passing in an actual pointer instead of a name tag. | ||
| 33 | */ | ||
| 34 | #define __RING_SIZE(_s, _sz) \ | ||
| 35 | (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0]))) | ||
| 29 | 36 | ||
| 30 | /* | 37 | /* |
| 31 | * Macros to make the correct C datatypes for a new kind of ring. | 38 | * Macros to make the correct C datatypes for a new kind of ring. |
diff --git a/kernel/power/swap.c b/kernel/power/swap.c index baf667bb279..8c7e4832b9b 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | #include "power.h" | 31 | #include "power.h" |
| 32 | 32 | ||
| 33 | #define HIBERNATE_SIG "LINHIB0001" | 33 | #define HIBERNATE_SIG "S1SUSPEND" |
| 34 | 34 | ||
| 35 | /* | 35 | /* |
| 36 | * The swap map is a data structure used for keeping track of each page | 36 | * The swap map is a data structure used for keeping track of each page |
diff --git a/kernel/power/user.c b/kernel/power/user.c index 1b2ea31e6bd..c36c3b9e8a8 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
| @@ -137,7 +137,7 @@ static int snapshot_release(struct inode *inode, struct file *filp) | |||
| 137 | free_all_swap_pages(data->swap); | 137 | free_all_swap_pages(data->swap); |
| 138 | if (data->frozen) | 138 | if (data->frozen) |
| 139 | thaw_processes(); | 139 | thaw_processes(); |
| 140 | pm_notifier_call_chain(data->mode == O_WRONLY ? | 140 | pm_notifier_call_chain(data->mode == O_RDONLY ? |
| 141 | PM_POST_HIBERNATION : PM_POST_RESTORE); | 141 | PM_POST_HIBERNATION : PM_POST_RESTORE); |
| 142 | atomic_inc(&snapshot_device_available); | 142 | atomic_inc(&snapshot_device_available); |
| 143 | 143 | ||
diff --git a/kernel/resource.c b/kernel/resource.c index 9fad33efd0d..798e2fae2a0 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
| @@ -40,23 +40,6 @@ EXPORT_SYMBOL(iomem_resource); | |||
| 40 | 40 | ||
| 41 | static DEFINE_RWLOCK(resource_lock); | 41 | static DEFINE_RWLOCK(resource_lock); |
| 42 | 42 | ||
| 43 | /* | ||
| 44 | * By default, we allocate free space bottom-up. The architecture can request | ||
| 45 | * top-down by clearing this flag. The user can override the architecture's | ||
| 46 | * choice with the "resource_alloc_from_bottom" kernel boot option, but that | ||
| 47 | * should only be a debugging tool. | ||
| 48 | */ | ||
| 49 | int resource_alloc_from_bottom = 1; | ||
| 50 | |||
| 51 | static __init int setup_alloc_from_bottom(char *s) | ||
| 52 | { | ||
| 53 | printk(KERN_INFO | ||
| 54 | "resource: allocating from bottom-up; please report a bug\n"); | ||
| 55 | resource_alloc_from_bottom = 1; | ||
| 56 | return 0; | ||
| 57 | } | ||
| 58 | early_param("resource_alloc_from_bottom", setup_alloc_from_bottom); | ||
| 59 | |||
| 60 | static void *r_next(struct seq_file *m, void *v, loff_t *pos) | 43 | static void *r_next(struct seq_file *m, void *v, loff_t *pos) |
| 61 | { | 44 | { |
| 62 | struct resource *p = v; | 45 | struct resource *p = v; |
| @@ -374,6 +357,10 @@ int __weak page_is_ram(unsigned long pfn) | |||
| 374 | return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1; | 357 | return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1; |
| 375 | } | 358 | } |
| 376 | 359 | ||
| 360 | void __weak arch_remove_reservations(struct resource *avail) | ||
| 361 | { | ||
| 362 | } | ||
| 363 | |||
| 377 | static resource_size_t simple_align_resource(void *data, | 364 | static resource_size_t simple_align_resource(void *data, |
| 378 | const struct resource *avail, | 365 | const struct resource *avail, |
| 379 | resource_size_t size, | 366 | resource_size_t size, |
| @@ -397,74 +384,7 @@ static bool resource_contains(struct resource *res1, struct resource *res2) | |||
| 397 | } | 384 | } |
| 398 | 385 | ||
| 399 | /* | 386 | /* |
| 400 | * Find the resource before "child" in the sibling list of "root" children. | ||
| 401 | */ | ||
| 402 | static struct resource *find_sibling_prev(struct resource *root, struct resource *child) | ||
| 403 | { | ||
| 404 | struct resource *this; | ||
| 405 | |||
| 406 | for (this = root->child; this; this = this->sibling) | ||
| 407 | if (this->sibling == child) | ||
| 408 | return this; | ||
| 409 | |||
| 410 | return NULL; | ||
| 411 | } | ||
| 412 | |||
| 413 | /* | ||
| 414 | * Find empty slot in the resource tree given range and alignment. | 387 | * Find empty slot in the resource tree given range and alignment. |
| 415 | * This version allocates from the end of the root resource first. | ||
| 416 | */ | ||
| 417 | static int find_resource_from_top(struct resource *root, struct resource *new, | ||
| 418 | resource_size_t size, resource_size_t min, | ||
| 419 | resource_size_t max, resource_size_t align, | ||
| 420 | resource_size_t (*alignf)(void *, | ||
| 421 | const struct resource *, | ||
| 422 | resource_size_t, | ||
| 423 | resource_size_t), | ||
| 424 | void *alignf_data) | ||
| 425 | { | ||
| 426 | struct resource *this; | ||
| 427 | struct resource tmp, avail, alloc; | ||
| 428 | |||
| 429 | tmp.start = root->end; | ||
| 430 | tmp.end = root->end; | ||
| 431 | |||
| 432 | this = find_sibling_prev(root, NULL); | ||
| 433 | for (;;) { | ||
| 434 | if (this) { | ||
| 435 | if (this->end < root->end) | ||
| 436 | tmp.start = this->end + 1; | ||
| 437 | } else | ||
| 438 | tmp.start = root->start; | ||
| 439 | |||
| 440 | resource_clip(&tmp, min, max); | ||
| 441 | |||
| 442 | /* Check for overflow after ALIGN() */ | ||
| 443 | avail = *new; | ||
| 444 | avail.start = ALIGN(tmp.start, align); | ||
| 445 | avail.end = tmp.end; | ||
| 446 | if (avail.start >= tmp.start) { | ||
| 447 | alloc.start = alignf(alignf_data, &avail, size, align); | ||
| 448 | alloc.end = alloc.start + size - 1; | ||
| 449 | if (resource_contains(&avail, &alloc)) { | ||
| 450 | new->start = alloc.start; | ||
| 451 | new->end = alloc.end; | ||
| 452 | return 0; | ||
| 453 | } | ||
| 454 | } | ||
| 455 | |||
| 456 | if (!this || this->start == root->start) | ||
| 457 | break; | ||
| 458 | |||
| 459 | tmp.end = this->start - 1; | ||
| 460 | this = find_sibling_prev(root, this); | ||
| 461 | } | ||
| 462 | return -EBUSY; | ||
| 463 | } | ||
| 464 | |||
| 465 | /* | ||
| 466 | * Find empty slot in the resource tree given range and alignment. | ||
| 467 | * This version allocates from the beginning of the root resource first. | ||
| 468 | */ | 388 | */ |
| 469 | static int find_resource(struct resource *root, struct resource *new, | 389 | static int find_resource(struct resource *root, struct resource *new, |
| 470 | resource_size_t size, resource_size_t min, | 390 | resource_size_t size, resource_size_t min, |
| @@ -478,23 +398,24 @@ static int find_resource(struct resource *root, struct resource *new, | |||
| 478 | struct resource *this = root->child; | 398 | struct resource *this = root->child; |
| 479 | struct resource tmp = *new, avail, alloc; | 399 | struct resource tmp = *new, avail, alloc; |
| 480 | 400 | ||
| 401 | tmp.flags = new->flags; | ||
| 481 | tmp.start = root->start; | 402 | tmp.start = root->start; |
| 482 | /* | 403 | /* |
| 483 | * Skip past an allocated resource that starts at 0, since the | 404 | * Skip past an allocated resource that starts at 0, since the assignment |
| 484 | * assignment of this->start - 1 to tmp->end below would cause an | 405 | * of this->start - 1 to tmp->end below would cause an underflow. |
| 485 | * underflow. | ||
| 486 | */ | 406 | */ |
| 487 | if (this && this->start == 0) { | 407 | if (this && this->start == 0) { |
| 488 | tmp.start = this->end + 1; | 408 | tmp.start = this->end + 1; |
| 489 | this = this->sibling; | 409 | this = this->sibling; |
| 490 | } | 410 | } |
| 491 | for (;;) { | 411 | for(;;) { |
| 492 | if (this) | 412 | if (this) |
| 493 | tmp.end = this->start - 1; | 413 | tmp.end = this->start - 1; |
| 494 | else | 414 | else |
| 495 | tmp.end = root->end; | 415 | tmp.end = root->end; |
| 496 | 416 | ||
| 497 | resource_clip(&tmp, min, max); | 417 | resource_clip(&tmp, min, max); |
| 418 | arch_remove_reservations(&tmp); | ||
| 498 | 419 | ||
| 499 | /* Check for overflow after ALIGN() */ | 420 | /* Check for overflow after ALIGN() */ |
| 500 | avail = *new; | 421 | avail = *new; |
| @@ -509,10 +430,8 @@ static int find_resource(struct resource *root, struct resource *new, | |||
| 509 | return 0; | 430 | return 0; |
| 510 | } | 431 | } |
| 511 | } | 432 | } |
| 512 | |||
| 513 | if (!this) | 433 | if (!this) |
| 514 | break; | 434 | break; |
| 515 | |||
| 516 | tmp.start = this->end + 1; | 435 | tmp.start = this->end + 1; |
| 517 | this = this->sibling; | 436 | this = this->sibling; |
| 518 | } | 437 | } |
| @@ -545,10 +464,7 @@ int allocate_resource(struct resource *root, struct resource *new, | |||
| 545 | alignf = simple_align_resource; | 464 | alignf = simple_align_resource; |
| 546 | 465 | ||
| 547 | write_lock(&resource_lock); | 466 | write_lock(&resource_lock); |
| 548 | if (resource_alloc_from_bottom) | 467 | err = find_resource(root, new, size, min, max, align, alignf, alignf_data); |
| 549 | err = find_resource(root, new, size, min, max, align, alignf, alignf_data); | ||
| 550 | else | ||
| 551 | err = find_resource_from_top(root, new, size, min, max, align, alignf, alignf_data); | ||
| 552 | if (err >= 0 && __request_resource(root, new)) | 468 | if (err >= 0 && __request_resource(root, new)) |
| 553 | err = -EBUSY; | 469 | err = -EBUSY; |
| 554 | write_unlock(&resource_lock); | 470 | write_unlock(&resource_lock); |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 90db1bd1a97..e785b0f2aea 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
| @@ -661,7 +661,7 @@ void wq_worker_waking_up(struct task_struct *task, unsigned int cpu) | |||
| 661 | { | 661 | { |
| 662 | struct worker *worker = kthread_data(task); | 662 | struct worker *worker = kthread_data(task); |
| 663 | 663 | ||
| 664 | if (likely(!(worker->flags & WORKER_NOT_RUNNING))) | 664 | if (!(worker->flags & WORKER_NOT_RUNNING)) |
| 665 | atomic_inc(get_gcwq_nr_running(cpu)); | 665 | atomic_inc(get_gcwq_nr_running(cpu)); |
| 666 | } | 666 | } |
| 667 | 667 | ||
| @@ -687,7 +687,7 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task, | |||
| 687 | struct global_cwq *gcwq = get_gcwq(cpu); | 687 | struct global_cwq *gcwq = get_gcwq(cpu); |
| 688 | atomic_t *nr_running = get_gcwq_nr_running(cpu); | 688 | atomic_t *nr_running = get_gcwq_nr_running(cpu); |
| 689 | 689 | ||
| 690 | if (unlikely(worker->flags & WORKER_NOT_RUNNING)) | 690 | if (worker->flags & WORKER_NOT_RUNNING) |
| 691 | return NULL; | 691 | return NULL; |
| 692 | 692 | ||
| 693 | /* this can only happen on the local cpu */ | 693 | /* this can only happen on the local cpu */ |
| @@ -3692,7 +3692,8 @@ static int __init init_workqueues(void) | |||
| 3692 | system_nrt_wq = alloc_workqueue("events_nrt", WQ_NON_REENTRANT, 0); | 3692 | system_nrt_wq = alloc_workqueue("events_nrt", WQ_NON_REENTRANT, 0); |
| 3693 | system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND, | 3693 | system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND, |
| 3694 | WQ_UNBOUND_MAX_ACTIVE); | 3694 | WQ_UNBOUND_MAX_ACTIVE); |
| 3695 | BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq); | 3695 | BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq || |
| 3696 | !system_unbound_wq); | ||
| 3696 | return 0; | 3697 | return 0; |
| 3697 | } | 3698 | } |
| 3698 | early_initcall(init_workqueues); | 3699 | early_initcall(init_workqueues); |
diff --git a/mm/filemap.c b/mm/filemap.c index ea89840fc65..6b9aee20f24 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
| @@ -143,13 +143,18 @@ void __remove_from_page_cache(struct page *page) | |||
| 143 | void remove_from_page_cache(struct page *page) | 143 | void remove_from_page_cache(struct page *page) |
| 144 | { | 144 | { |
| 145 | struct address_space *mapping = page->mapping; | 145 | struct address_space *mapping = page->mapping; |
| 146 | void (*freepage)(struct page *); | ||
| 146 | 147 | ||
| 147 | BUG_ON(!PageLocked(page)); | 148 | BUG_ON(!PageLocked(page)); |
| 148 | 149 | ||
| 150 | freepage = mapping->a_ops->freepage; | ||
| 149 | spin_lock_irq(&mapping->tree_lock); | 151 | spin_lock_irq(&mapping->tree_lock); |
| 150 | __remove_from_page_cache(page); | 152 | __remove_from_page_cache(page); |
| 151 | spin_unlock_irq(&mapping->tree_lock); | 153 | spin_unlock_irq(&mapping->tree_lock); |
| 152 | mem_cgroup_uncharge_cache_page(page); | 154 | mem_cgroup_uncharge_cache_page(page); |
| 155 | |||
| 156 | if (freepage) | ||
| 157 | freepage(page); | ||
| 153 | } | 158 | } |
| 154 | EXPORT_SYMBOL(remove_from_page_cache); | 159 | EXPORT_SYMBOL(remove_from_page_cache); |
| 155 | 160 | ||
| @@ -2462,6 +2462,7 @@ int install_special_mapping(struct mm_struct *mm, | |||
| 2462 | unsigned long addr, unsigned long len, | 2462 | unsigned long addr, unsigned long len, |
| 2463 | unsigned long vm_flags, struct page **pages) | 2463 | unsigned long vm_flags, struct page **pages) |
| 2464 | { | 2464 | { |
| 2465 | int ret; | ||
| 2465 | struct vm_area_struct *vma; | 2466 | struct vm_area_struct *vma; |
| 2466 | 2467 | ||
| 2467 | vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); | 2468 | vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
| @@ -2479,16 +2480,23 @@ int install_special_mapping(struct mm_struct *mm, | |||
| 2479 | vma->vm_ops = &special_mapping_vmops; | 2480 | vma->vm_ops = &special_mapping_vmops; |
| 2480 | vma->vm_private_data = pages; | 2481 | vma->vm_private_data = pages; |
| 2481 | 2482 | ||
| 2482 | if (unlikely(insert_vm_struct(mm, vma))) { | 2483 | ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1); |
| 2483 | kmem_cache_free(vm_area_cachep, vma); | 2484 | if (ret) |
| 2484 | return -ENOMEM; | 2485 | goto out; |
| 2485 | } | 2486 | |
| 2487 | ret = insert_vm_struct(mm, vma); | ||
| 2488 | if (ret) | ||
| 2489 | goto out; | ||
| 2486 | 2490 | ||
| 2487 | mm->total_vm += len >> PAGE_SHIFT; | 2491 | mm->total_vm += len >> PAGE_SHIFT; |
| 2488 | 2492 | ||
| 2489 | perf_event_mmap(vma); | 2493 | perf_event_mmap(vma); |
| 2490 | 2494 | ||
| 2491 | return 0; | 2495 | return 0; |
| 2496 | |||
| 2497 | out: | ||
| 2498 | kmem_cache_free(vm_area_cachep, vma); | ||
| 2499 | return ret; | ||
| 2492 | } | 2500 | } |
| 2493 | 2501 | ||
| 2494 | static DEFINE_MUTEX(mm_all_locks_mutex); | 2502 | static DEFINE_MUTEX(mm_all_locks_mutex); |
diff --git a/mm/truncate.c b/mm/truncate.c index ba887bff48c..3c2d5ddfa0d 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
| @@ -390,6 +390,10 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page) | |||
| 390 | __remove_from_page_cache(page); | 390 | __remove_from_page_cache(page); |
| 391 | spin_unlock_irq(&mapping->tree_lock); | 391 | spin_unlock_irq(&mapping->tree_lock); |
| 392 | mem_cgroup_uncharge_cache_page(page); | 392 | mem_cgroup_uncharge_cache_page(page); |
| 393 | |||
| 394 | if (mapping->a_ops->freepage) | ||
| 395 | mapping->a_ops->freepage(page); | ||
| 396 | |||
| 393 | page_cache_release(page); /* pagecache ref */ | 397 | page_cache_release(page); /* pagecache ref */ |
| 394 | return 1; | 398 | return 1; |
| 395 | failed: | 399 | failed: |
diff --git a/mm/vmscan.c b/mm/vmscan.c index d31d7ce52c0..9ca587c6927 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
| @@ -494,9 +494,16 @@ static int __remove_mapping(struct address_space *mapping, struct page *page) | |||
| 494 | spin_unlock_irq(&mapping->tree_lock); | 494 | spin_unlock_irq(&mapping->tree_lock); |
| 495 | swapcache_free(swap, page); | 495 | swapcache_free(swap, page); |
| 496 | } else { | 496 | } else { |
| 497 | void (*freepage)(struct page *); | ||
| 498 | |||
| 499 | freepage = mapping->a_ops->freepage; | ||
| 500 | |||
| 497 | __remove_from_page_cache(page); | 501 | __remove_from_page_cache(page); |
| 498 | spin_unlock_irq(&mapping->tree_lock); | 502 | spin_unlock_irq(&mapping->tree_lock); |
| 499 | mem_cgroup_uncharge_cache_page(page); | 503 | mem_cgroup_uncharge_cache_page(page); |
| 504 | |||
| 505 | if (freepage != NULL) | ||
| 506 | freepage(page); | ||
| 500 | } | 507 | } |
| 501 | 508 | ||
| 502 | return 1; | 509 | return 1; |
diff --git a/net/atm/atm_sysfs.c b/net/atm/atm_sysfs.c index 799c631f0fe..f7fa67c7876 100644 --- a/net/atm/atm_sysfs.c +++ b/net/atm/atm_sysfs.c | |||
| @@ -143,12 +143,13 @@ static struct class atm_class = { | |||
| 143 | .dev_uevent = atm_uevent, | 143 | .dev_uevent = atm_uevent, |
| 144 | }; | 144 | }; |
| 145 | 145 | ||
| 146 | int atm_register_sysfs(struct atm_dev *adev) | 146 | int atm_register_sysfs(struct atm_dev *adev, struct device *parent) |
| 147 | { | 147 | { |
| 148 | struct device *cdev = &adev->class_dev; | 148 | struct device *cdev = &adev->class_dev; |
| 149 | int i, j, err; | 149 | int i, j, err; |
| 150 | 150 | ||
| 151 | cdev->class = &atm_class; | 151 | cdev->class = &atm_class; |
| 152 | cdev->parent = parent; | ||
| 152 | dev_set_drvdata(cdev, adev); | 153 | dev_set_drvdata(cdev, adev); |
| 153 | 154 | ||
| 154 | dev_set_name(cdev, "%s%d", adev->type, adev->number); | 155 | dev_set_name(cdev, "%s%d", adev->type, adev->number); |
diff --git a/net/atm/resources.c b/net/atm/resources.c index d29e5826151..23f45ce6f35 100644 --- a/net/atm/resources.c +++ b/net/atm/resources.c | |||
| @@ -74,8 +74,9 @@ struct atm_dev *atm_dev_lookup(int number) | |||
| 74 | } | 74 | } |
| 75 | EXPORT_SYMBOL(atm_dev_lookup); | 75 | EXPORT_SYMBOL(atm_dev_lookup); |
| 76 | 76 | ||
| 77 | struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, | 77 | struct atm_dev *atm_dev_register(const char *type, struct device *parent, |
| 78 | int number, unsigned long *flags) | 78 | const struct atmdev_ops *ops, int number, |
| 79 | unsigned long *flags) | ||
| 79 | { | 80 | { |
| 80 | struct atm_dev *dev, *inuse; | 81 | struct atm_dev *dev, *inuse; |
| 81 | 82 | ||
| @@ -115,7 +116,7 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, | |||
| 115 | goto out_fail; | 116 | goto out_fail; |
| 116 | } | 117 | } |
| 117 | 118 | ||
| 118 | if (atm_register_sysfs(dev) < 0) { | 119 | if (atm_register_sysfs(dev, parent) < 0) { |
| 119 | pr_err("atm_register_sysfs failed for dev %s\n", type); | 120 | pr_err("atm_register_sysfs failed for dev %s\n", type); |
| 120 | atm_proc_dev_deregister(dev); | 121 | atm_proc_dev_deregister(dev); |
| 121 | goto out_fail; | 122 | goto out_fail; |
diff --git a/net/atm/resources.h b/net/atm/resources.h index 126fb1840df..521431e3050 100644 --- a/net/atm/resources.h +++ b/net/atm/resources.h | |||
| @@ -42,6 +42,6 @@ static inline void atm_proc_dev_deregister(struct atm_dev *dev) | |||
| 42 | 42 | ||
| 43 | #endif /* CONFIG_PROC_FS */ | 43 | #endif /* CONFIG_PROC_FS */ |
| 44 | 44 | ||
| 45 | int atm_register_sysfs(struct atm_dev *adev); | 45 | int atm_register_sysfs(struct atm_dev *adev, struct device *parent); |
| 46 | void atm_unregister_sysfs(struct atm_dev *adev); | 46 | void atm_unregister_sysfs(struct atm_dev *adev); |
| 47 | #endif | 47 | #endif |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index d0927d1fdad..66b9e5c0523 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
| @@ -882,7 +882,7 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) | |||
| 882 | int lm = 0; | 882 | int lm = 0; |
| 883 | 883 | ||
| 884 | if (type != SCO_LINK && type != ESCO_LINK) | 884 | if (type != SCO_LINK && type != ESCO_LINK) |
| 885 | return 0; | 885 | return -EINVAL; |
| 886 | 886 | ||
| 887 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); | 887 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); |
| 888 | 888 | ||
| @@ -908,7 +908,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status) | |||
| 908 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); | 908 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); |
| 909 | 909 | ||
| 910 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) | 910 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) |
| 911 | return 0; | 911 | return -EINVAL; |
| 912 | 912 | ||
| 913 | if (!status) { | 913 | if (!status) { |
| 914 | struct sco_conn *conn; | 914 | struct sco_conn *conn; |
| @@ -927,7 +927,7 @@ static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) | |||
| 927 | BT_DBG("hcon %p reason %d", hcon, reason); | 927 | BT_DBG("hcon %p reason %d", hcon, reason); |
| 928 | 928 | ||
| 929 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) | 929 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) |
| 930 | return 0; | 930 | return -EINVAL; |
| 931 | 931 | ||
| 932 | sco_conn_del(hcon, bt_err(reason)); | 932 | sco_conn_del(hcon, bt_err(reason)); |
| 933 | 933 | ||
diff --git a/net/core/filter.c b/net/core/filter.c index c1ee800bc08..ae21a0d3c4a 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
| @@ -589,23 +589,16 @@ int sk_chk_filter(struct sock_filter *filter, int flen) | |||
| 589 | EXPORT_SYMBOL(sk_chk_filter); | 589 | EXPORT_SYMBOL(sk_chk_filter); |
| 590 | 590 | ||
| 591 | /** | 591 | /** |
| 592 | * sk_filter_rcu_release - Release a socket filter by rcu_head | 592 | * sk_filter_release_rcu - Release a socket filter by rcu_head |
| 593 | * @rcu: rcu_head that contains the sk_filter to free | 593 | * @rcu: rcu_head that contains the sk_filter to free |
| 594 | */ | 594 | */ |
| 595 | static void sk_filter_rcu_release(struct rcu_head *rcu) | 595 | void sk_filter_release_rcu(struct rcu_head *rcu) |
| 596 | { | 596 | { |
| 597 | struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); | 597 | struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); |
| 598 | 598 | ||
| 599 | sk_filter_release(fp); | 599 | kfree(fp); |
| 600 | } | ||
| 601 | |||
| 602 | static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp) | ||
| 603 | { | ||
| 604 | unsigned int size = sk_filter_len(fp); | ||
| 605 | |||
| 606 | atomic_sub(size, &sk->sk_omem_alloc); | ||
| 607 | call_rcu_bh(&fp->rcu, sk_filter_rcu_release); | ||
| 608 | } | 600 | } |
| 601 | EXPORT_SYMBOL(sk_filter_release_rcu); | ||
| 609 | 602 | ||
| 610 | /** | 603 | /** |
| 611 | * sk_attach_filter - attach a socket filter | 604 | * sk_attach_filter - attach a socket filter |
| @@ -649,7 +642,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) | |||
| 649 | rcu_assign_pointer(sk->sk_filter, fp); | 642 | rcu_assign_pointer(sk->sk_filter, fp); |
| 650 | 643 | ||
| 651 | if (old_fp) | 644 | if (old_fp) |
| 652 | sk_filter_delayed_uncharge(sk, old_fp); | 645 | sk_filter_uncharge(sk, old_fp); |
| 653 | return 0; | 646 | return 0; |
| 654 | } | 647 | } |
| 655 | EXPORT_SYMBOL_GPL(sk_attach_filter); | 648 | EXPORT_SYMBOL_GPL(sk_attach_filter); |
| @@ -663,7 +656,7 @@ int sk_detach_filter(struct sock *sk) | |||
| 663 | sock_owned_by_user(sk)); | 656 | sock_owned_by_user(sk)); |
| 664 | if (filter) { | 657 | if (filter) { |
| 665 | rcu_assign_pointer(sk->sk_filter, NULL); | 658 | rcu_assign_pointer(sk->sk_filter, NULL); |
| 666 | sk_filter_delayed_uncharge(sk, filter); | 659 | sk_filter_uncharge(sk, filter); |
| 667 | ret = 0; | 660 | ret = 0; |
| 668 | } | 661 | } |
| 669 | return ret; | 662 | return ret; |
diff --git a/net/core/timestamping.c b/net/core/timestamping.c index 0ae6c22da85..c19bb4ee405 100644 --- a/net/core/timestamping.c +++ b/net/core/timestamping.c | |||
| @@ -96,11 +96,13 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb) | |||
| 96 | struct phy_device *phydev; | 96 | struct phy_device *phydev; |
| 97 | unsigned int type; | 97 | unsigned int type; |
| 98 | 98 | ||
| 99 | skb_push(skb, ETH_HLEN); | 99 | if (skb_headroom(skb) < ETH_HLEN) |
| 100 | return false; | ||
| 101 | __skb_push(skb, ETH_HLEN); | ||
| 100 | 102 | ||
| 101 | type = classify(skb); | 103 | type = classify(skb); |
| 102 | 104 | ||
| 103 | skb_pull(skb, ETH_HLEN); | 105 | __skb_pull(skb, ETH_HLEN); |
| 104 | 106 | ||
| 105 | switch (type) { | 107 | switch (type) { |
| 106 | case PTP_CLASS_V1_IPV4: | 108 | case PTP_CLASS_V1_IPV4: |
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 13992e1d272..15dcc1a586b 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c | |||
| @@ -661,8 +661,10 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg) | |||
| 661 | err = 0; | 661 | err = 0; |
| 662 | switch (cmd) { | 662 | switch (cmd) { |
| 663 | case SIOCSIFADDR: | 663 | case SIOCSIFADDR: |
| 664 | if (!capable(CAP_NET_ADMIN)) | 664 | if (!capable(CAP_NET_ADMIN)) { |
| 665 | return -EPERM; | 665 | err = -EPERM; |
| 666 | break; | ||
| 667 | } | ||
| 666 | 668 | ||
| 667 | edev = dev->ec_ptr; | 669 | edev = dev->ec_ptr; |
| 668 | if (edev == NULL) { | 670 | if (edev == NULL) { |
| @@ -849,9 +851,13 @@ static void aun_incoming(struct sk_buff *skb, struct aunhdr *ah, size_t len) | |||
| 849 | { | 851 | { |
| 850 | struct iphdr *ip = ip_hdr(skb); | 852 | struct iphdr *ip = ip_hdr(skb); |
| 851 | unsigned char stn = ntohl(ip->saddr) & 0xff; | 853 | unsigned char stn = ntohl(ip->saddr) & 0xff; |
| 854 | struct dst_entry *dst = skb_dst(skb); | ||
| 855 | struct ec_device *edev = NULL; | ||
| 852 | struct sock *sk = NULL; | 856 | struct sock *sk = NULL; |
| 853 | struct sk_buff *newskb; | 857 | struct sk_buff *newskb; |
| 854 | struct ec_device *edev = skb->dev->ec_ptr; | 858 | |
| 859 | if (dst) | ||
| 860 | edev = dst->dev->ec_ptr; | ||
| 855 | 861 | ||
| 856 | if (! edev) | 862 | if (! edev) |
| 857 | goto bad; | 863 | goto bad; |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 1b48eb1ed45..b14ec7d03b6 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
| @@ -253,6 +253,7 @@ static const struct snmp_mib snmp4_net_list[] = { | |||
| 253 | SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP), | 253 | SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP), |
| 254 | SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP), | 254 | SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP), |
| 255 | SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER), | 255 | SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER), |
| 256 | SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW), | ||
| 256 | SNMP_MIB_SENTINEL | 257 | SNMP_MIB_SENTINEL |
| 257 | }; | 258 | }; |
| 258 | 259 | ||
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 43cf901d765..a66735f7596 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
| @@ -347,7 +347,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) | |||
| 347 | * socket up. We've got bigger problems than | 347 | * socket up. We've got bigger problems than |
| 348 | * non-graceful socket closings. | 348 | * non-graceful socket closings. |
| 349 | */ | 349 | */ |
| 350 | LIMIT_NETDEBUG(KERN_INFO "TCP: time wait bucket table overflow\n"); | 350 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW); |
| 351 | } | 351 | } |
| 352 | 352 | ||
| 353 | tcp_update_metrics(sk); | 353 | tcp_update_metrics(sk); |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 05b1ecf3676..61c2463e275 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -231,11 +231,10 @@ void tcp_select_initial_window(int __space, __u32 mss, | |||
| 231 | /* when initializing use the value from init_rcv_wnd | 231 | /* when initializing use the value from init_rcv_wnd |
| 232 | * rather than the default from above | 232 | * rather than the default from above |
| 233 | */ | 233 | */ |
| 234 | if (init_rcv_wnd && | 234 | if (init_rcv_wnd) |
| 235 | (*rcv_wnd > init_rcv_wnd * mss)) | 235 | *rcv_wnd = min(*rcv_wnd, init_rcv_wnd * mss); |
| 236 | *rcv_wnd = init_rcv_wnd * mss; | 236 | else |
| 237 | else if (*rcv_wnd > init_cwnd * mss) | 237 | *rcv_wnd = min(*rcv_wnd, init_cwnd * mss); |
| 238 | *rcv_wnd = init_cwnd * mss; | ||
| 239 | } | 238 | } |
| 240 | 239 | ||
| 241 | /* Set the clamp no higher than max representable value */ | 240 | /* Set the clamp no higher than max representable value */ |
| @@ -386,27 +385,30 @@ struct tcp_out_options { | |||
| 386 | */ | 385 | */ |
| 387 | static u8 tcp_cookie_size_check(u8 desired) | 386 | static u8 tcp_cookie_size_check(u8 desired) |
| 388 | { | 387 | { |
| 389 | if (desired > 0) { | 388 | int cookie_size; |
| 389 | |||
| 390 | if (desired > 0) | ||
| 390 | /* previously specified */ | 391 | /* previously specified */ |
| 391 | return desired; | 392 | return desired; |
| 392 | } | 393 | |
| 393 | if (sysctl_tcp_cookie_size <= 0) { | 394 | cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size); |
| 395 | if (cookie_size <= 0) | ||
| 394 | /* no default specified */ | 396 | /* no default specified */ |
| 395 | return 0; | 397 | return 0; |
| 396 | } | 398 | |
| 397 | if (sysctl_tcp_cookie_size <= TCP_COOKIE_MIN) { | 399 | if (cookie_size <= TCP_COOKIE_MIN) |
| 398 | /* value too small, specify minimum */ | 400 | /* value too small, specify minimum */ |
| 399 | return TCP_COOKIE_MIN; | 401 | return TCP_COOKIE_MIN; |
| 400 | } | 402 | |
| 401 | if (sysctl_tcp_cookie_size >= TCP_COOKIE_MAX) { | 403 | if (cookie_size >= TCP_COOKIE_MAX) |
| 402 | /* value too large, specify maximum */ | 404 | /* value too large, specify maximum */ |
| 403 | return TCP_COOKIE_MAX; | 405 | return TCP_COOKIE_MAX; |
| 404 | } | 406 | |
| 405 | if (0x1 & sysctl_tcp_cookie_size) { | 407 | if (cookie_size & 1) |
| 406 | /* 8-bit multiple, illegal, fix it */ | 408 | /* 8-bit multiple, illegal, fix it */ |
| 407 | return (u8)(sysctl_tcp_cookie_size + 0x1); | 409 | cookie_size++; |
| 408 | } | 410 | |
| 409 | return (u8)sysctl_tcp_cookie_size; | 411 | return (u8)cookie_size; |
| 410 | } | 412 | } |
| 411 | 413 | ||
| 412 | /* Write previously computed TCP options to the packet. | 414 | /* Write previously computed TCP options to the packet. |
| @@ -1513,6 +1515,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) | |||
| 1513 | struct tcp_sock *tp = tcp_sk(sk); | 1515 | struct tcp_sock *tp = tcp_sk(sk); |
| 1514 | const struct inet_connection_sock *icsk = inet_csk(sk); | 1516 | const struct inet_connection_sock *icsk = inet_csk(sk); |
| 1515 | u32 send_win, cong_win, limit, in_flight; | 1517 | u32 send_win, cong_win, limit, in_flight; |
| 1518 | int win_divisor; | ||
| 1516 | 1519 | ||
| 1517 | if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN) | 1520 | if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN) |
| 1518 | goto send_now; | 1521 | goto send_now; |
| @@ -1544,13 +1547,14 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) | |||
| 1544 | if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len)) | 1547 | if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len)) |
| 1545 | goto send_now; | 1548 | goto send_now; |
| 1546 | 1549 | ||
| 1547 | if (sysctl_tcp_tso_win_divisor) { | 1550 | win_divisor = ACCESS_ONCE(sysctl_tcp_tso_win_divisor); |
| 1551 | if (win_divisor) { | ||
| 1548 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); | 1552 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); |
| 1549 | 1553 | ||
| 1550 | /* If at least some fraction of a window is available, | 1554 | /* If at least some fraction of a window is available, |
| 1551 | * just use it. | 1555 | * just use it. |
| 1552 | */ | 1556 | */ |
| 1553 | chunk /= sysctl_tcp_tso_win_divisor; | 1557 | chunk /= win_divisor; |
| 1554 | if (limit >= chunk) | 1558 | if (limit >= chunk) |
| 1555 | goto send_now; | 1559 | goto send_now; |
| 1556 | } else { | 1560 | } else { |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 23cc8e1ce8d..93b7a933a77 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -4021,11 +4021,11 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev) | |||
| 4021 | kfree_skb(skb); | 4021 | kfree_skb(skb); |
| 4022 | goto errout; | 4022 | goto errout; |
| 4023 | } | 4023 | } |
| 4024 | rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); | 4024 | rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFINFO, NULL, GFP_ATOMIC); |
| 4025 | return; | 4025 | return; |
| 4026 | errout: | 4026 | errout: |
| 4027 | if (err < 0) | 4027 | if (err < 0) |
| 4028 | rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err); | 4028 | rtnl_set_sk_err(net, RTNLGRP_IPV6_IFINFO, err); |
| 4029 | } | 4029 | } |
| 4030 | 4030 | ||
| 4031 | static inline size_t inet6_prefix_nlmsg_size(void) | 4031 | static inline size_t inet6_prefix_nlmsg_size(void) |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 2a59610c2a5..70e891a20fb 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
| @@ -1175,6 +1175,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t) | |||
| 1175 | sizeof (struct ipv6hdr); | 1175 | sizeof (struct ipv6hdr); |
| 1176 | 1176 | ||
| 1177 | dev->mtu = rt->rt6i_dev->mtu - sizeof (struct ipv6hdr); | 1177 | dev->mtu = rt->rt6i_dev->mtu - sizeof (struct ipv6hdr); |
| 1178 | if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) | ||
| 1179 | dev->mtu-=8; | ||
| 1178 | 1180 | ||
| 1179 | if (dev->mtu < IPV6_MIN_MTU) | 1181 | if (dev->mtu < IPV6_MIN_MTU) |
| 1180 | dev->mtu = IPV6_MIN_MTU; | 1182 | dev->mtu = IPV6_MIN_MTU; |
| @@ -1363,12 +1365,17 @@ static const struct net_device_ops ip6_tnl_netdev_ops = { | |||
| 1363 | 1365 | ||
| 1364 | static void ip6_tnl_dev_setup(struct net_device *dev) | 1366 | static void ip6_tnl_dev_setup(struct net_device *dev) |
| 1365 | { | 1367 | { |
| 1368 | struct ip6_tnl *t; | ||
| 1369 | |||
| 1366 | dev->netdev_ops = &ip6_tnl_netdev_ops; | 1370 | dev->netdev_ops = &ip6_tnl_netdev_ops; |
| 1367 | dev->destructor = ip6_dev_free; | 1371 | dev->destructor = ip6_dev_free; |
| 1368 | 1372 | ||
| 1369 | dev->type = ARPHRD_TUNNEL6; | 1373 | dev->type = ARPHRD_TUNNEL6; |
| 1370 | dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr); | 1374 | dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr); |
| 1371 | dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr); | 1375 | dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr); |
| 1376 | t = netdev_priv(dev); | ||
| 1377 | if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) | ||
| 1378 | dev->mtu-=8; | ||
| 1372 | dev->flags |= IFF_NOARP; | 1379 | dev->flags |= IFF_NOARP; |
| 1373 | dev->addr_len = sizeof(struct in6_addr); | 1380 | dev->addr_len = sizeof(struct in6_addr); |
| 1374 | dev->features |= NETIF_F_NETNS_LOCAL; | 1381 | dev->features |= NETIF_F_NETNS_LOCAL; |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index d6bfaec3bbb..8c4d00c7cd2 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
| @@ -606,8 +606,9 @@ static int ipip6_rcv(struct sk_buff *skb) | |||
| 606 | return 0; | 606 | return 0; |
| 607 | } | 607 | } |
| 608 | 608 | ||
| 609 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); | 609 | /* no tunnel matched, let upstream know, ipsec may handle it */ |
| 610 | rcu_read_unlock(); | 610 | rcu_read_unlock(); |
| 611 | return 1; | ||
| 611 | out: | 612 | out: |
| 612 | kfree_skb(skb); | 613 | kfree_skb(skb); |
| 613 | return 0; | 614 | return 0; |
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 0bf6a59545a..522e219f355 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c | |||
| @@ -674,4 +674,8 @@ MODULE_LICENSE("GPL"); | |||
| 674 | MODULE_AUTHOR("James Chapman <jchapman@katalix.com>"); | 674 | MODULE_AUTHOR("James Chapman <jchapman@katalix.com>"); |
| 675 | MODULE_DESCRIPTION("L2TP over IP"); | 675 | MODULE_DESCRIPTION("L2TP over IP"); |
| 676 | MODULE_VERSION("1.0"); | 676 | MODULE_VERSION("1.0"); |
| 677 | MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, SOCK_DGRAM, IPPROTO_L2TP); | 677 | |
| 678 | /* Use the value of SOCK_DGRAM (2) directory, because __stringify does't like | ||
| 679 | * enums | ||
| 680 | */ | ||
| 681 | MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 2, IPPROTO_L2TP); | ||
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 58261299821..e35dbe55f52 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
| @@ -317,8 +317,9 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) | |||
| 317 | goto out; | 317 | goto out; |
| 318 | rc = -ENODEV; | 318 | rc = -ENODEV; |
| 319 | rtnl_lock(); | 319 | rtnl_lock(); |
| 320 | rcu_read_lock(); | ||
| 320 | if (sk->sk_bound_dev_if) { | 321 | if (sk->sk_bound_dev_if) { |
| 321 | llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); | 322 | llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if); |
| 322 | if (llc->dev) { | 323 | if (llc->dev) { |
| 323 | if (!addr->sllc_arphrd) | 324 | if (!addr->sllc_arphrd) |
| 324 | addr->sllc_arphrd = llc->dev->type; | 325 | addr->sllc_arphrd = llc->dev->type; |
| @@ -329,13 +330,13 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) | |||
| 329 | !llc_mac_match(addr->sllc_mac, | 330 | !llc_mac_match(addr->sllc_mac, |
| 330 | llc->dev->dev_addr)) { | 331 | llc->dev->dev_addr)) { |
| 331 | rc = -EINVAL; | 332 | rc = -EINVAL; |
| 332 | dev_put(llc->dev); | ||
| 333 | llc->dev = NULL; | 333 | llc->dev = NULL; |
| 334 | } | 334 | } |
| 335 | } | 335 | } |
| 336 | } else | 336 | } else |
| 337 | llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd, | 337 | llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd, |
| 338 | addr->sllc_mac); | 338 | addr->sllc_mac); |
| 339 | rcu_read_unlock(); | ||
| 339 | rtnl_unlock(); | 340 | rtnl_unlock(); |
| 340 | if (!llc->dev) | 341 | if (!llc->dev) |
| 341 | goto out; | 342 | goto out; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 902b03ee8f6..54fb4a0e76f 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -2247,6 +2247,10 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | |||
| 2247 | break; | 2247 | break; |
| 2248 | case cpu_to_le16(IEEE80211_STYPE_DEAUTH): | 2248 | case cpu_to_le16(IEEE80211_STYPE_DEAUTH): |
| 2249 | case cpu_to_le16(IEEE80211_STYPE_DISASSOC): | 2249 | case cpu_to_le16(IEEE80211_STYPE_DISASSOC): |
| 2250 | if (is_multicast_ether_addr(mgmt->da) && | ||
| 2251 | !is_broadcast_ether_addr(mgmt->da)) | ||
| 2252 | return RX_DROP_MONITOR; | ||
| 2253 | |||
| 2250 | /* process only for station */ | 2254 | /* process only for station */ |
| 2251 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 2255 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
| 2252 | return RX_DROP_MONITOR; | 2256 | return RX_DROP_MONITOR; |
| @@ -2741,6 +2745,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
| 2741 | 2745 | ||
| 2742 | if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) | 2746 | if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) |
| 2743 | return; | 2747 | return; |
| 2748 | goto out; | ||
| 2744 | } | 2749 | } |
| 2745 | } | 2750 | } |
| 2746 | 2751 | ||
| @@ -2780,6 +2785,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
| 2780 | return; | 2785 | return; |
| 2781 | } | 2786 | } |
| 2782 | 2787 | ||
| 2788 | out: | ||
| 2783 | dev_kfree_skb(skb); | 2789 | dev_kfree_skb(skb); |
| 2784 | } | 2790 | } |
| 2785 | 2791 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 96c59430950..7a637b80a62 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -1587,7 +1587,12 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
| 1587 | list) { | 1587 | list) { |
| 1588 | if (!ieee80211_sdata_running(tmp_sdata)) | 1588 | if (!ieee80211_sdata_running(tmp_sdata)) |
| 1589 | continue; | 1589 | continue; |
| 1590 | if (tmp_sdata->vif.type != NL80211_IFTYPE_AP) | 1590 | if (tmp_sdata->vif.type == |
| 1591 | NL80211_IFTYPE_MONITOR || | ||
| 1592 | tmp_sdata->vif.type == | ||
| 1593 | NL80211_IFTYPE_AP_VLAN || | ||
| 1594 | tmp_sdata->vif.type == | ||
| 1595 | NL80211_IFTYPE_WDS) | ||
| 1591 | continue; | 1596 | continue; |
| 1592 | if (compare_ether_addr(tmp_sdata->vif.addr, | 1597 | if (compare_ether_addr(tmp_sdata->vif.addr, |
| 1593 | hdr->addr2) == 0) { | 1598 | hdr->addr2) == 0) { |
| @@ -1732,15 +1737,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1732 | int nh_pos, h_pos; | 1737 | int nh_pos, h_pos; |
| 1733 | struct sta_info *sta = NULL; | 1738 | struct sta_info *sta = NULL; |
| 1734 | u32 sta_flags = 0; | 1739 | u32 sta_flags = 0; |
| 1740 | struct sk_buff *tmp_skb; | ||
| 1735 | 1741 | ||
| 1736 | if (unlikely(skb->len < ETH_HLEN)) { | 1742 | if (unlikely(skb->len < ETH_HLEN)) { |
| 1737 | ret = NETDEV_TX_OK; | 1743 | ret = NETDEV_TX_OK; |
| 1738 | goto fail; | 1744 | goto fail; |
| 1739 | } | 1745 | } |
| 1740 | 1746 | ||
| 1741 | nh_pos = skb_network_header(skb) - skb->data; | ||
| 1742 | h_pos = skb_transport_header(skb) - skb->data; | ||
| 1743 | |||
| 1744 | /* convert Ethernet header to proper 802.11 header (based on | 1747 | /* convert Ethernet header to proper 802.11 header (based on |
| 1745 | * operation mode) */ | 1748 | * operation mode) */ |
| 1746 | ethertype = (skb->data[12] << 8) | skb->data[13]; | 1749 | ethertype = (skb->data[12] << 8) | skb->data[13]; |
| @@ -1913,6 +1916,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1913 | goto fail; | 1916 | goto fail; |
| 1914 | } | 1917 | } |
| 1915 | 1918 | ||
| 1919 | /* | ||
| 1920 | * If the skb is shared we need to obtain our own copy. | ||
| 1921 | */ | ||
| 1922 | if (skb_shared(skb)) { | ||
| 1923 | tmp_skb = skb; | ||
| 1924 | skb = skb_copy(skb, GFP_ATOMIC); | ||
| 1925 | kfree_skb(tmp_skb); | ||
| 1926 | |||
| 1927 | if (!skb) { | ||
| 1928 | ret = NETDEV_TX_OK; | ||
| 1929 | goto fail; | ||
| 1930 | } | ||
| 1931 | } | ||
| 1932 | |||
| 1916 | hdr.frame_control = fc; | 1933 | hdr.frame_control = fc; |
| 1917 | hdr.duration_id = 0; | 1934 | hdr.duration_id = 0; |
| 1918 | hdr.seq_ctrl = 0; | 1935 | hdr.seq_ctrl = 0; |
| @@ -1931,6 +1948,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1931 | encaps_len = 0; | 1948 | encaps_len = 0; |
| 1932 | } | 1949 | } |
| 1933 | 1950 | ||
| 1951 | nh_pos = skb_network_header(skb) - skb->data; | ||
| 1952 | h_pos = skb_transport_header(skb) - skb->data; | ||
| 1953 | |||
| 1934 | skb_pull(skb, skip_header_bytes); | 1954 | skb_pull(skb, skip_header_bytes); |
| 1935 | nh_pos -= skip_header_bytes; | 1955 | nh_pos -= skip_header_bytes; |
| 1936 | h_pos -= skip_header_bytes; | 1956 | h_pos -= skip_header_bytes; |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 6bd554323a3..0b9ee34ad35 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -2932,6 +2932,7 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva | |||
| 2932 | struct sctp_association *asoc = NULL; | 2932 | struct sctp_association *asoc = NULL; |
| 2933 | struct sctp_setpeerprim prim; | 2933 | struct sctp_setpeerprim prim; |
| 2934 | struct sctp_chunk *chunk; | 2934 | struct sctp_chunk *chunk; |
| 2935 | struct sctp_af *af; | ||
| 2935 | int err; | 2936 | int err; |
| 2936 | 2937 | ||
| 2937 | sp = sctp_sk(sk); | 2938 | sp = sctp_sk(sk); |
| @@ -2959,6 +2960,13 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva | |||
| 2959 | if (!sctp_state(asoc, ESTABLISHED)) | 2960 | if (!sctp_state(asoc, ESTABLISHED)) |
| 2960 | return -ENOTCONN; | 2961 | return -ENOTCONN; |
| 2961 | 2962 | ||
| 2963 | af = sctp_get_af_specific(prim.sspp_addr.ss_family); | ||
| 2964 | if (!af) | ||
| 2965 | return -EINVAL; | ||
| 2966 | |||
| 2967 | if (!af->addr_valid((union sctp_addr *)&prim.sspp_addr, sp, NULL)) | ||
| 2968 | return -EADDRNOTAVAIL; | ||
| 2969 | |||
| 2962 | if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr)) | 2970 | if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr)) |
| 2963 | return -EADDRNOTAVAIL; | 2971 | return -EADDRNOTAVAIL; |
| 2964 | 2972 | ||
diff --git a/net/socket.c b/net/socket.c index 3ca2fd9e372..088fb3fd45e 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -732,6 +732,21 @@ static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg, | |||
| 732 | return ret; | 732 | return ret; |
| 733 | } | 733 | } |
| 734 | 734 | ||
| 735 | /** | ||
| 736 | * kernel_recvmsg - Receive a message from a socket (kernel space) | ||
| 737 | * @sock: The socket to receive the message from | ||
| 738 | * @msg: Received message | ||
| 739 | * @vec: Input s/g array for message data | ||
| 740 | * @num: Size of input s/g array | ||
| 741 | * @size: Number of bytes to read | ||
| 742 | * @flags: Message flags (MSG_DONTWAIT, etc...) | ||
| 743 | * | ||
| 744 | * On return the msg structure contains the scatter/gather array passed in the | ||
| 745 | * vec argument. The array is modified so that it consists of the unfilled | ||
| 746 | * portion of the original array. | ||
| 747 | * | ||
| 748 | * The returned value is the total number of bytes received, or an error. | ||
| 749 | */ | ||
| 735 | int kernel_recvmsg(struct socket *sock, struct msghdr *msg, | 750 | int kernel_recvmsg(struct socket *sock, struct msghdr *msg, |
| 736 | struct kvec *vec, size_t num, size_t size, int flags) | 751 | struct kvec *vec, size_t num, size_t size, int flags) |
| 737 | { | 752 | { |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index ea2ff78dcf7..3f2c5559ca1 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
| @@ -212,6 +212,7 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, | |||
| 212 | spin_lock(&svc_xprt_class_lock); | 212 | spin_lock(&svc_xprt_class_lock); |
| 213 | list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) { | 213 | list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) { |
| 214 | struct svc_xprt *newxprt; | 214 | struct svc_xprt *newxprt; |
| 215 | unsigned short newport; | ||
| 215 | 216 | ||
| 216 | if (strcmp(xprt_name, xcl->xcl_name)) | 217 | if (strcmp(xprt_name, xcl->xcl_name)) |
| 217 | continue; | 218 | continue; |
| @@ -230,8 +231,9 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, | |||
| 230 | spin_lock_bh(&serv->sv_lock); | 231 | spin_lock_bh(&serv->sv_lock); |
| 231 | list_add(&newxprt->xpt_list, &serv->sv_permsocks); | 232 | list_add(&newxprt->xpt_list, &serv->sv_permsocks); |
| 232 | spin_unlock_bh(&serv->sv_lock); | 233 | spin_unlock_bh(&serv->sv_lock); |
| 234 | newport = svc_xprt_local_port(newxprt); | ||
| 233 | clear_bit(XPT_BUSY, &newxprt->xpt_flags); | 235 | clear_bit(XPT_BUSY, &newxprt->xpt_flags); |
| 234 | return svc_xprt_local_port(newxprt); | 236 | return newport; |
| 235 | } | 237 | } |
| 236 | err: | 238 | err: |
| 237 | spin_unlock(&svc_xprt_class_lock); | 239 | spin_unlock(&svc_xprt_class_lock); |
| @@ -425,8 +427,13 @@ void svc_xprt_received(struct svc_xprt *xprt) | |||
| 425 | { | 427 | { |
| 426 | BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); | 428 | BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); |
| 427 | xprt->xpt_pool = NULL; | 429 | xprt->xpt_pool = NULL; |
| 430 | /* As soon as we clear busy, the xprt could be closed and | ||
| 431 | * 'put', so we need a reference to call svc_xprt_enqueue with: | ||
| 432 | */ | ||
| 433 | svc_xprt_get(xprt); | ||
| 428 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | 434 | clear_bit(XPT_BUSY, &xprt->xpt_flags); |
| 429 | svc_xprt_enqueue(xprt); | 435 | svc_xprt_enqueue(xprt); |
| 436 | svc_xprt_put(xprt); | ||
| 430 | } | 437 | } |
| 431 | EXPORT_SYMBOL_GPL(svc_xprt_received); | 438 | EXPORT_SYMBOL_GPL(svc_xprt_received); |
| 432 | 439 | ||
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c index 73e7b954ad2..b25c6463c3e 100644 --- a/net/x25/x25_link.c +++ b/net/x25/x25_link.c | |||
| @@ -394,6 +394,7 @@ void __exit x25_link_free(void) | |||
| 394 | list_for_each_safe(entry, tmp, &x25_neigh_list) { | 394 | list_for_each_safe(entry, tmp, &x25_neigh_list) { |
| 395 | nb = list_entry(entry, struct x25_neigh, node); | 395 | nb = list_entry(entry, struct x25_neigh, node); |
| 396 | __x25_remove_neigh(nb); | 396 | __x25_remove_neigh(nb); |
| 397 | dev_put(nb->dev); | ||
| 397 | } | 398 | } |
| 398 | write_unlock_bh(&x25_neigh_list_lock); | 399 | write_unlock_bh(&x25_neigh_list_lock); |
| 399 | } | 400 | } |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index eb96ce52f17..220ebc05c7a 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
| @@ -1268,7 +1268,7 @@ struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x, | |||
| 1268 | 1268 | ||
| 1269 | return xc; | 1269 | return xc; |
| 1270 | error: | 1270 | error: |
| 1271 | kfree(xc); | 1271 | xfrm_state_put(xc); |
| 1272 | return NULL; | 1272 | return NULL; |
| 1273 | } | 1273 | } |
| 1274 | EXPORT_SYMBOL(xfrm_state_migrate); | 1274 | EXPORT_SYMBOL(xfrm_state_migrate); |
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index cb0c23a6b47..4a663471dad 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c | |||
| @@ -189,6 +189,9 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a, | |||
| 189 | a->channels = GRAB_BITS(buf, 0, 0, 3); | 189 | a->channels = GRAB_BITS(buf, 0, 0, 3); |
| 190 | a->channels++; | 190 | a->channels++; |
| 191 | 191 | ||
| 192 | a->sample_bits = 0; | ||
| 193 | a->max_bitrate = 0; | ||
| 194 | |||
| 192 | a->format = GRAB_BITS(buf, 0, 3, 4); | 195 | a->format = GRAB_BITS(buf, 0, 3, 4); |
| 193 | switch (a->format) { | 196 | switch (a->format) { |
| 194 | case AUDIO_CODING_TYPE_REF_STREAM_HEADER: | 197 | case AUDIO_CODING_TYPE_REF_STREAM_HEADER: |
| @@ -198,7 +201,6 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a, | |||
| 198 | 201 | ||
| 199 | case AUDIO_CODING_TYPE_LPCM: | 202 | case AUDIO_CODING_TYPE_LPCM: |
| 200 | val = GRAB_BITS(buf, 2, 0, 3); | 203 | val = GRAB_BITS(buf, 2, 0, 3); |
| 201 | a->sample_bits = 0; | ||
| 202 | for (i = 0; i < 3; i++) | 204 | for (i = 0; i < 3; i++) |
| 203 | if (val & (1 << i)) | 205 | if (val & (1 << i)) |
| 204 | a->sample_bits |= cea_sample_sizes[i + 1]; | 206 | a->sample_bits |= cea_sample_sizes[i + 1]; |
| @@ -598,24 +600,19 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, | |||
| 598 | { | 600 | { |
| 599 | int i; | 601 | int i; |
| 600 | 602 | ||
| 601 | pcm->rates = 0; | 603 | /* assume basic audio support (the basic audio flag is not in ELD; |
| 602 | pcm->formats = 0; | 604 | * however, all audio capable sinks are required to support basic |
| 603 | pcm->maxbps = 0; | 605 | * audio) */ |
| 604 | pcm->channels_min = -1; | 606 | pcm->rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; |
| 605 | pcm->channels_max = 0; | 607 | pcm->formats = SNDRV_PCM_FMTBIT_S16_LE; |
| 608 | pcm->maxbps = 16; | ||
| 609 | pcm->channels_max = 2; | ||
| 606 | for (i = 0; i < eld->sad_count; i++) { | 610 | for (i = 0; i < eld->sad_count; i++) { |
| 607 | struct cea_sad *a = &eld->sad[i]; | 611 | struct cea_sad *a = &eld->sad[i]; |
| 608 | pcm->rates |= a->rates; | 612 | pcm->rates |= a->rates; |
| 609 | if (a->channels < pcm->channels_min) | ||
| 610 | pcm->channels_min = a->channels; | ||
| 611 | if (a->channels > pcm->channels_max) | 613 | if (a->channels > pcm->channels_max) |
| 612 | pcm->channels_max = a->channels; | 614 | pcm->channels_max = a->channels; |
| 613 | if (a->format == AUDIO_CODING_TYPE_LPCM) { | 615 | if (a->format == AUDIO_CODING_TYPE_LPCM) { |
| 614 | if (a->sample_bits & AC_SUPPCM_BITS_16) { | ||
| 615 | pcm->formats |= SNDRV_PCM_FMTBIT_S16_LE; | ||
| 616 | if (pcm->maxbps < 16) | ||
| 617 | pcm->maxbps = 16; | ||
| 618 | } | ||
| 619 | if (a->sample_bits & AC_SUPPCM_BITS_20) { | 616 | if (a->sample_bits & AC_SUPPCM_BITS_20) { |
| 620 | pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE; | 617 | pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE; |
| 621 | if (pcm->maxbps < 20) | 618 | if (pcm->maxbps < 20) |
| @@ -635,7 +632,6 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, | |||
| 635 | /* restrict the parameters by the values the codec provides */ | 632 | /* restrict the parameters by the values the codec provides */ |
| 636 | pcm->rates &= codec_pars->rates; | 633 | pcm->rates &= codec_pars->rates; |
| 637 | pcm->formats &= codec_pars->formats; | 634 | pcm->formats &= codec_pars->formats; |
| 638 | pcm->channels_min = max(pcm->channels_min, codec_pars->channels_min); | ||
| 639 | pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max); | 635 | pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max); |
| 640 | pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); | 636 | pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); |
| 641 | } | 637 | } |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 21aa9b0e28f..b030c8eba21 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -2296,6 +2296,7 @@ static int azx_dev_free(struct snd_device *device) | |||
| 2296 | */ | 2296 | */ |
| 2297 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { | 2297 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { |
| 2298 | SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB), | 2298 | SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB), |
| 2299 | SND_PCI_QUIRK(0x1025, 0x026f, "Acer Aspire 5538", POS_FIX_LPIB), | ||
| 2299 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), | 2300 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), |
| 2300 | SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), | 2301 | SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), |
| 2301 | SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), | 2302 | SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 846d1ead47f..76bd58a0e2b 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
| @@ -2116,8 +2116,8 @@ static void cxt5066_update_speaker(struct hda_codec *codec) | |||
| 2116 | struct conexant_spec *spec = codec->spec; | 2116 | struct conexant_spec *spec = codec->spec; |
| 2117 | unsigned int pinctl; | 2117 | unsigned int pinctl; |
| 2118 | 2118 | ||
| 2119 | snd_printdd("CXT5066: update speaker, hp_present=%d\n", | 2119 | snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n", |
| 2120 | spec->hp_present); | 2120 | spec->hp_present, spec->cur_eapd); |
| 2121 | 2121 | ||
| 2122 | /* Port A (HP) */ | 2122 | /* Port A (HP) */ |
| 2123 | pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0; | 2123 | pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0; |
| @@ -2125,11 +2125,20 @@ static void cxt5066_update_speaker(struct hda_codec *codec) | |||
| 2125 | pinctl); | 2125 | pinctl); |
| 2126 | 2126 | ||
| 2127 | /* Port D (HP/LO) */ | 2127 | /* Port D (HP/LO) */ |
| 2128 | pinctl = ((spec->hp_present & 2) && spec->cur_eapd) | 2128 | if (spec->dell_automute) { |
| 2129 | ? spec->port_d_mode : 0; | 2129 | /* DELL AIO Port Rule: PortA> PortD> IntSpk */ |
| 2130 | /* Mute if Port A is connected on Thinkpad */ | 2130 | pinctl = (!(spec->hp_present & 1) && spec->cur_eapd) |
| 2131 | if (spec->thinkpad && (spec->hp_present & 1)) | 2131 | ? PIN_OUT : 0; |
| 2132 | pinctl = 0; | 2132 | } else if (spec->thinkpad) { |
| 2133 | if (spec->cur_eapd) | ||
| 2134 | pinctl = spec->port_d_mode; | ||
| 2135 | /* Mute dock line-out if Port A (laptop HP) is present */ | ||
| 2136 | if (spec->hp_present& 1) | ||
| 2137 | pinctl = 0; | ||
| 2138 | } else { | ||
| 2139 | pinctl = ((spec->hp_present & 2) && spec->cur_eapd) | ||
| 2140 | ? spec->port_d_mode : 0; | ||
| 2141 | } | ||
| 2133 | snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 2142 | snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
| 2134 | pinctl); | 2143 | pinctl); |
| 2135 | 2144 | ||
| @@ -2137,14 +2146,6 @@ static void cxt5066_update_speaker(struct hda_codec *codec) | |||
| 2137 | pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; | 2146 | pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; |
| 2138 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 2147 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
| 2139 | pinctl); | 2148 | pinctl); |
| 2140 | |||
| 2141 | if (spec->dell_automute) { | ||
| 2142 | /* DELL AIO Port Rule: PortA > PortD > IntSpk */ | ||
| 2143 | pinctl = (!(spec->hp_present & 1) && spec->cur_eapd) | ||
| 2144 | ? PIN_OUT : 0; | ||
| 2145 | snd_hda_codec_write(codec, 0x1c, 0, | ||
| 2146 | AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); | ||
| 2147 | } | ||
| 2148 | } | 2149 | } |
| 2149 | 2150 | ||
| 2150 | /* turn on/off EAPD (+ mute HP) as a master switch */ | 2151 | /* turn on/off EAPD (+ mute HP) as a master switch */ |
| @@ -3095,8 +3096,7 @@ static const char *cxt5066_models[CXT5066_MODELS] = { | |||
| 3095 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | 3096 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { |
| 3096 | SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), | 3097 | SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), |
| 3097 | SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), | 3098 | SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), |
| 3098 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", | 3099 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), |
| 3099 | CXT5066_DELL_LAPTOP), | ||
| 3100 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), | 3100 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), |
| 3101 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), | 3101 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), |
| 3102 | SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), | 3102 | SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), |
| @@ -3109,6 +3109,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
| 3109 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), | 3109 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), |
| 3110 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), | 3110 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), |
| 3111 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), | 3111 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), |
| 3112 | SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), | ||
| 3112 | SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), | 3113 | SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), |
| 3113 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), | 3114 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), |
| 3114 | SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD), | 3115 | SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD), |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index d3e49aa5b9e..31df7747990 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
| @@ -834,7 +834,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, | |||
| 834 | return -ENODEV; | 834 | return -ENODEV; |
| 835 | } else { | 835 | } else { |
| 836 | /* fallback to the codec default */ | 836 | /* fallback to the codec default */ |
| 837 | hinfo->channels_min = codec_pars->channels_min; | ||
| 838 | hinfo->channels_max = codec_pars->channels_max; | 837 | hinfo->channels_max = codec_pars->channels_max; |
| 839 | hinfo->rates = codec_pars->rates; | 838 | hinfo->rates = codec_pars->rates; |
| 840 | hinfo->formats = codec_pars->formats; | 839 | hinfo->formats = codec_pars->formats; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8fddc9d0872..427da45d790 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -4595,6 +4595,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { | |||
| 4595 | SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), | 4595 | SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), |
| 4596 | SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), | 4596 | SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), |
| 4597 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), | 4597 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), |
| 4598 | SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG), | ||
| 4598 | SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), | 4599 | SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), |
| 4599 | SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), | 4600 | SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), |
| 4600 | SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), | 4601 | SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), |
| @@ -10829,7 +10830,8 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) | |||
| 10829 | { | 10830 | { |
| 10830 | struct alc_spec *spec = codec->spec; | 10831 | struct alc_spec *spec = codec->spec; |
| 10831 | struct auto_pin_cfg *cfg = &spec->autocfg; | 10832 | struct auto_pin_cfg *cfg = &spec->autocfg; |
| 10832 | int i, err; | 10833 | int i, err, type; |
| 10834 | int type_idx = 0; | ||
| 10833 | hda_nid_t nid; | 10835 | hda_nid_t nid; |
| 10834 | 10836 | ||
| 10835 | for (i = 0; i < cfg->num_inputs; i++) { | 10837 | for (i = 0; i < cfg->num_inputs; i++) { |
| @@ -10838,9 +10840,15 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) | |||
| 10838 | nid = cfg->inputs[i].pin; | 10840 | nid = cfg->inputs[i].pin; |
| 10839 | if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { | 10841 | if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { |
| 10840 | char label[32]; | 10842 | char label[32]; |
| 10843 | type = cfg->inputs[i].type; | ||
| 10844 | if (i > 0 && type == cfg->inputs[i - 1].type) | ||
| 10845 | type_idx++; | ||
| 10846 | else | ||
| 10847 | type_idx = 0; | ||
| 10841 | snprintf(label, sizeof(label), "%s Boost", | 10848 | snprintf(label, sizeof(label), "%s Boost", |
| 10842 | hda_get_autocfg_input_label(codec, cfg, i)); | 10849 | hda_get_autocfg_input_label(codec, cfg, i)); |
| 10843 | err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0, | 10850 | err = add_control(spec, ALC_CTL_WIDGET_VOL, label, |
| 10851 | type_idx, | ||
| 10844 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | 10852 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); |
| 10845 | if (err < 0) | 10853 | if (err < 0) |
| 10846 | return err; | 10854 | return err; |
| @@ -14799,6 +14807,8 @@ static int alc269_resume(struct hda_codec *codec) | |||
| 14799 | enum { | 14807 | enum { |
| 14800 | ALC269_FIXUP_SONY_VAIO, | 14808 | ALC269_FIXUP_SONY_VAIO, |
| 14801 | ALC269_FIXUP_DELL_M101Z, | 14809 | ALC269_FIXUP_DELL_M101Z, |
| 14810 | ALC269_FIXUP_LENOVO_EDGE14, | ||
| 14811 | ALC269_FIXUP_ASUS_G73JW, | ||
| 14802 | }; | 14812 | }; |
| 14803 | 14813 | ||
| 14804 | static const struct alc_fixup alc269_fixups[] = { | 14814 | static const struct alc_fixup alc269_fixups[] = { |
| @@ -14816,11 +14826,22 @@ static const struct alc_fixup alc269_fixups[] = { | |||
| 14816 | {} | 14826 | {} |
| 14817 | } | 14827 | } |
| 14818 | }, | 14828 | }, |
| 14829 | [ALC269_FIXUP_LENOVO_EDGE14] = { | ||
| 14830 | .sku = ALC_FIXUP_SKU_IGNORE, | ||
| 14831 | }, | ||
| 14832 | [ALC269_FIXUP_ASUS_G73JW] = { | ||
| 14833 | .pins = (const struct alc_pincfg[]) { | ||
| 14834 | { 0x17, 0x99130111 }, /* subwoofer */ | ||
| 14835 | { } | ||
| 14836 | } | ||
| 14837 | }, | ||
| 14819 | }; | 14838 | }; |
| 14820 | 14839 | ||
| 14821 | static struct snd_pci_quirk alc269_fixup_tbl[] = { | 14840 | static struct snd_pci_quirk alc269_fixup_tbl[] = { |
| 14822 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | 14841 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), |
| 14823 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), | 14842 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), |
| 14843 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_LENOVO_EDGE14), | ||
| 14844 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), | ||
| 14824 | {} | 14845 | {} |
| 14825 | }; | 14846 | }; |
| 14826 | 14847 | ||
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index a2e0ed59b37..8725d4e7543 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c | |||
| @@ -161,7 +161,7 @@ | |||
| 161 | static const u16 wm8580_reg[] = { | 161 | static const u16 wm8580_reg[] = { |
| 162 | 0x0121, 0x017e, 0x007d, 0x0014, /*R3*/ | 162 | 0x0121, 0x017e, 0x007d, 0x0014, /*R3*/ |
| 163 | 0x0121, 0x017e, 0x007d, 0x0194, /*R7*/ | 163 | 0x0121, 0x017e, 0x007d, 0x0194, /*R7*/ |
| 164 | 0x001c, 0x0002, 0x0002, 0x00c2, /*R11*/ | 164 | 0x0010, 0x0002, 0x0002, 0x00c2, /*R11*/ |
| 165 | 0x0182, 0x0082, 0x000a, 0x0024, /*R15*/ | 165 | 0x0182, 0x0082, 0x000a, 0x0024, /*R15*/ |
| 166 | 0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/ | 166 | 0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/ |
| 167 | 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/ | 167 | 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/ |
| @@ -491,16 +491,16 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream, | |||
| 491 | paifa |= 0x8; | 491 | paifa |= 0x8; |
| 492 | break; | 492 | break; |
| 493 | case SNDRV_PCM_FORMAT_S20_3LE: | 493 | case SNDRV_PCM_FORMAT_S20_3LE: |
| 494 | paifa |= 0x10; | 494 | paifa |= 0x0; |
| 495 | paifb |= WM8580_AIF_LENGTH_20; | 495 | paifb |= WM8580_AIF_LENGTH_20; |
| 496 | break; | 496 | break; |
| 497 | case SNDRV_PCM_FORMAT_S24_LE: | 497 | case SNDRV_PCM_FORMAT_S24_LE: |
| 498 | paifa |= 0x10; | 498 | paifa |= 0x0; |
| 499 | paifb |= WM8580_AIF_LENGTH_24; | 499 | paifb |= WM8580_AIF_LENGTH_24; |
| 500 | break; | 500 | break; |
| 501 | case SNDRV_PCM_FORMAT_S32_LE: | 501 | case SNDRV_PCM_FORMAT_S32_LE: |
| 502 | paifa |= 0x10; | 502 | paifa |= 0x0; |
| 503 | paifb |= WM8580_AIF_LENGTH_24; | 503 | paifb |= WM8580_AIF_LENGTH_32; |
| 504 | break; | 504 | break; |
| 505 | default: | 505 | default: |
| 506 | return -EINVAL; | 506 | return -EINVAL; |
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index fca60a0b57b..9001cc48ba1 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
| @@ -818,7 +818,8 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol, | |||
| 818 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 818 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 819 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 819 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
| 820 | 820 | ||
| 821 | return wm8904->deemph; | 821 | ucontrol->value.enumerated.item[0] = wm8904->deemph; |
| 822 | return 0; | ||
| 822 | } | 823 | } |
| 823 | 824 | ||
| 824 | static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, | 825 | static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, |
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index f89ad6c9a80..9cbab8e1de0 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c | |||
| @@ -380,7 +380,8 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol, | |||
| 380 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 380 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 381 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); | 381 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); |
| 382 | 382 | ||
| 383 | return wm8955->deemph; | 383 | ucontrol->value.enumerated.item[0] = wm8955->deemph; |
| 384 | return 0; | ||
| 384 | } | 385 | } |
| 385 | 386 | ||
| 386 | static int wm8955_put_deemph(struct snd_kcontrol *kcontrol, | 387 | static int wm8955_put_deemph(struct snd_kcontrol *kcontrol, |
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 8d5efb333c3..21986c42272 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
| @@ -138,7 +138,8 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol, | |||
| 138 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 138 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 139 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); | 139 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); |
| 140 | 140 | ||
| 141 | return wm8960->deemph; | 141 | ucontrol->value.enumerated.item[0] = wm8960->deemph; |
| 142 | return 0; | ||
| 142 | } | 143 | } |
| 143 | 144 | ||
| 144 | static int wm8960_put_deemph(struct snd_kcontrol *kcontrol, | 145 | static int wm8960_put_deemph(struct snd_kcontrol *kcontrol, |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index e8092745a20..1304ca91a11 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
| @@ -3339,7 +3339,7 @@ static irqreturn_t wm8962_irq(int irq, void *data) | |||
| 3339 | int mask; | 3339 | int mask; |
| 3340 | int active; | 3340 | int active; |
| 3341 | 3341 | ||
| 3342 | mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); | 3342 | mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK); |
| 3343 | 3343 | ||
| 3344 | active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); | 3344 | active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); |
| 3345 | active &= ~mask; | 3345 | active &= ~mask; |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 19ca782ac97..0e24092722c 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
| @@ -293,7 +293,7 @@ SOC_DOUBLE_R("Speaker Switch", | |||
| 293 | SOC_DOUBLE_R("Speaker ZC Switch", | 293 | SOC_DOUBLE_R("Speaker ZC Switch", |
| 294 | WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT, | 294 | WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT, |
| 295 | 7, 1, 0), | 295 | 7, 1, 0), |
| 296 | SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 0, 3, 7, 0, | 296 | SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 3, 0, 7, 0, |
| 297 | spkboost_tlv), | 297 | spkboost_tlv), |
| 298 | SOC_ENUM("Speaker Reference", speaker_ref), | 298 | SOC_ENUM("Speaker Reference", speaker_ref), |
| 299 | SOC_ENUM("Speaker Mode", speaker_mode), | 299 | SOC_ENUM("Speaker Mode", speaker_mode), |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 441285ade02..85b7d548f16 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
| @@ -1619,12 +1619,14 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) | |||
| 1619 | #ifdef CONFIG_SND_SOC_AC97_BUS | 1619 | #ifdef CONFIG_SND_SOC_AC97_BUS |
| 1620 | /* register any AC97 codecs */ | 1620 | /* register any AC97 codecs */ |
| 1621 | for (i = 0; i < card->num_rtd; i++) { | 1621 | for (i = 0; i < card->num_rtd; i++) { |
| 1622 | ret = soc_register_ac97_dai_link(&card->rtd[i]); | 1622 | ret = soc_register_ac97_dai_link(&card->rtd[i]); |
| 1623 | if (ret < 0) { | 1623 | if (ret < 0) { |
| 1624 | printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name); | 1624 | printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name); |
| 1625 | goto probe_dai_err; | 1625 | while (--i >= 0) |
| 1626 | } | 1626 | soc_unregister_ac97_dai_link(&card->rtd[i]); |
| 1627 | goto probe_dai_err; | ||
| 1627 | } | 1628 | } |
| 1629 | } | ||
| 1628 | #endif | 1630 | #endif |
| 1629 | 1631 | ||
| 1630 | card->instantiated = 1; | 1632 | card->instantiated = 1; |
| @@ -3072,7 +3074,9 @@ int snd_soc_register_dais(struct device *dev, | |||
| 3072 | pr_debug("Registered DAI '%s'\n", dai->name); | 3074 | pr_debug("Registered DAI '%s'\n", dai->name); |
| 3073 | } | 3075 | } |
| 3074 | 3076 | ||
| 3077 | mutex_lock(&client_mutex); | ||
| 3075 | snd_soc_instantiate_cards(); | 3078 | snd_soc_instantiate_cards(); |
| 3079 | mutex_unlock(&client_mutex); | ||
| 3076 | return 0; | 3080 | return 0; |
| 3077 | 3081 | ||
| 3078 | err: | 3082 | err: |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 75ed6491222..c721502833b 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
| @@ -944,6 +944,9 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
| 944 | case SND_SOC_DAPM_STREAM_RESUME: | 944 | case SND_SOC_DAPM_STREAM_RESUME: |
| 945 | sys_power = 1; | 945 | sys_power = 1; |
| 946 | break; | 946 | break; |
| 947 | case SND_SOC_DAPM_STREAM_STOP: | ||
| 948 | sys_power = !!codec->active; | ||
| 949 | break; | ||
| 947 | case SND_SOC_DAPM_STREAM_SUSPEND: | 950 | case SND_SOC_DAPM_STREAM_SUSPEND: |
| 948 | sys_power = 0; | 951 | sys_power = 0; |
| 949 | break; | 952 | break; |
